|
|
@@ -1,220 +1,289 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { clientGet, clientPost, clientPut, clientDel } from '@/utils/request.ts'
|
|
|
-import { ref } from 'vue'
|
|
|
import type { BaseResponse } from '@/utils/type.ts'
|
|
|
-import { ElMessage, ElDialog, ElInput, ElForm, ElFormItem, ElButton, ElUpload,type UploadFile,type UploadFiles, ElMessageBox } from 'element-plus'
|
|
|
-
|
|
|
-interface ParkStemScreen {
|
|
|
- "id": string,
|
|
|
- "type": string,
|
|
|
- "createTime": string,
|
|
|
- "updateTime": string,
|
|
|
- "filePath": string[],
|
|
|
+import { clientGet, clientPost, clientPut } from '@/utils/request.ts'
|
|
|
+import { onMounted, ref, toRaw } from 'vue'
|
|
|
+import {
|
|
|
+ ElButton,
|
|
|
+ ElDialog,
|
|
|
+ ElForm,
|
|
|
+ ElFormItem,
|
|
|
+ ElInput,
|
|
|
+ ElMessage,
|
|
|
+ ElTable,
|
|
|
+ ElTableColumn,
|
|
|
+ ElUpload
|
|
|
+} from 'element-plus'
|
|
|
+
|
|
|
+// 类型定义
|
|
|
+interface ScreenControlResponse extends BaseResponse {
|
|
|
+ data: ScreenControl[]
|
|
|
+}
|
|
|
+
|
|
|
+interface UploadResponse extends BaseResponse {
|
|
|
+ data: string
|
|
|
}
|
|
|
|
|
|
-interface ParkStemScreenResponse extends BaseResponse {
|
|
|
- data: ParkStemScreen[]
|
|
|
+interface ScreenControl {
|
|
|
+ id: string
|
|
|
+ url: string
|
|
|
+ deviceId: string
|
|
|
+ state: number
|
|
|
+ createTime: string
|
|
|
+ updateTime: string
|
|
|
+ file?: File // 添加文件属性
|
|
|
+ isOpen?: string // 添加 isOpen 属性
|
|
|
}
|
|
|
|
|
|
-const minioUrl = import.meta.env.VITE_MINIO_BASE_URL
|
|
|
+interface IsOpenResponse extends BaseResponse{
|
|
|
+ data:boolean
|
|
|
+}
|
|
|
|
|
|
-const cardList = ref<ParkStemScreen[]>()
|
|
|
+// 响应式数据
|
|
|
+const screenControls = ref<ScreenControl[]>([])
|
|
|
+const dialogVisible = ref(false)
|
|
|
+const BASE_API = import.meta.env.VITE_APP_BASE_API
|
|
|
+const currentItem = ref<ScreenControl>({
|
|
|
+ id: '',
|
|
|
+ url: '',
|
|
|
+ deviceId: '',
|
|
|
+ state: 0,
|
|
|
+ createTime: '',
|
|
|
+ updateTime: ''
|
|
|
+})
|
|
|
+const previewUrl = ref<string>('') // 添加预览URL的响应式数据
|
|
|
|
|
|
+// 获取数据
|
|
|
const getList = async () => {
|
|
|
- const res = await clientGet<null, ParkStemScreenResponse>('/park/parkStemScreen/getListWithImg');
|
|
|
+ const res = await clientGet<null, ScreenControlResponse>('/screen/test/getAllScreenControl')
|
|
|
if (res.code !== 200) {
|
|
|
ElMessage.error(res.msg)
|
|
|
+ return
|
|
|
}
|
|
|
- cardList.value = res.data;
|
|
|
+
|
|
|
+ // 获取每个设备的开启状态并更新数据
|
|
|
+ screenControls.value = await Promise.all(
|
|
|
+ res.data.map(async (item) => {
|
|
|
+ const isOpenRes = await checkIsOpen(item.deviceId)
|
|
|
+ return { ...item, isOpen: isOpenRes }
|
|
|
+ })
|
|
|
+ )
|
|
|
}
|
|
|
|
|
|
-const init = () => {
|
|
|
- getList()
|
|
|
+// 时间格式化方法
|
|
|
+const formatDateTime = (dateTime: string): string => {
|
|
|
+ if (!dateTime) return ''
|
|
|
+ const date = new Date(dateTime)
|
|
|
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}
|
|
|
+ ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
|
|
|
}
|
|
|
-init()
|
|
|
|
|
|
-// 新增功能相关状态和方法
|
|
|
-const addDialogVisible = ref(false)
|
|
|
-const newScreen = ref({
|
|
|
- type: '',
|
|
|
- filePath: [] as string[]
|
|
|
-})
|
|
|
-const addFileList = ref<UploadFile[]>([])
|
|
|
+const pad = (n: number) => n.toString().padStart(2, '0')
|
|
|
|
|
|
-const handleAddFileChange = (file: UploadFile, fileList: UploadFiles) => {
|
|
|
- addFileList.value = fileList
|
|
|
+// 打开修改对话框
|
|
|
+const openEditDialog = (row: ScreenControl) => {
|
|
|
+ currentItem.value = { ...row }
|
|
|
+ previewUrl.value = row.url // 初始化预览URL
|
|
|
+ dialogVisible.value = true
|
|
|
}
|
|
|
|
|
|
-const handleAdd = async () => {
|
|
|
- if (addFileList.value.length === 0) {
|
|
|
- ElMessage.error('请上传文件')
|
|
|
+// 保存修改
|
|
|
+const saveEdit = async () => {
|
|
|
+ const res = await clientPut<ScreenControl, BaseResponse>('/screen/test/updateScreenControl', toRaw(currentItem.value))
|
|
|
+ if (res.code !== 200) {
|
|
|
+ ElMessage.error(res.msg)
|
|
|
return
|
|
|
}
|
|
|
+ ElMessage.success('修改成功')
|
|
|
+ dialogVisible.value = false
|
|
|
+ getList() // 刷新数据
|
|
|
+}
|
|
|
|
|
|
- const formData = new FormData()
|
|
|
- formData.append('type', newScreen.value.type)
|
|
|
- addFileList.value.forEach(file => {
|
|
|
- formData.append('files', file.raw!)
|
|
|
- })
|
|
|
+const beforeUpload = (file: File) => {
|
|
|
+ const isImage = currentItem.value.state === 1
|
|
|
+ const validTypes = isImage
|
|
|
+ ? ['image/jpeg', 'image/png']
|
|
|
+ : ['video/mp4', 'video/avi']
|
|
|
|
|
|
- const res = await clientPost<FormData, BaseResponse>('/park/parkStemScreen/save', formData, {
|
|
|
- headers: {
|
|
|
- 'Content-Type': 'multipart/form-data'
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- if (res.code === 200) {
|
|
|
- ElMessage.success('新增成功')
|
|
|
- getList()
|
|
|
- addDialogVisible.value = false
|
|
|
- addFileList.value = []
|
|
|
- } else {
|
|
|
- ElMessage.error(res.msg)
|
|
|
+ if (!validTypes.includes(file.type)) {
|
|
|
+ ElMessage.error(`请上传${isImage ? '图片' : '视频'}格式文件`)
|
|
|
+ return false
|
|
|
}
|
|
|
+ return true
|
|
|
}
|
|
|
|
|
|
-// 修改功能相关状态和方法
|
|
|
-const editDialogVisible = ref(false)
|
|
|
-const editScreen = ref<ParkStemScreen>({
|
|
|
- id: '',
|
|
|
- type: '',
|
|
|
- createTime: '',
|
|
|
- updateTime: '',
|
|
|
- filePath: [] as string[]
|
|
|
-})
|
|
|
-const editFileList = ref<UploadFile[]>([])
|
|
|
-
|
|
|
-const handleEditFileChange = (file: UploadFile, fileList: UploadFiles) => {
|
|
|
- editFileList.value = fileList
|
|
|
+const handleSuccess = (res: UploadResponse) => {
|
|
|
+ if (res.code !== 200) {
|
|
|
+ ElMessage.error(res.msg)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ currentItem.value.url = res.data
|
|
|
+ previewUrl.value = res.data // 更新预览URL
|
|
|
+ ElMessage.success('上传成功')
|
|
|
}
|
|
|
|
|
|
-const handleEdit = (item: ParkStemScreen) => {
|
|
|
- editScreen.value = { ...item }
|
|
|
- editFileList.value = []
|
|
|
- editDialogVisible.value = true
|
|
|
+const checkIsOpen = async (deviceId:string) => {
|
|
|
+ const res = await clientPost<{deviceId:string},IsOpenResponse>("/screen/test/checkScreenState?deviceCode="+deviceId);
|
|
|
+ if(res.code !== 200){
|
|
|
+ ElMessage.error(deviceId+"开启状态查询失败")
|
|
|
+ return "未知";
|
|
|
+ }else {
|
|
|
+ return res.data?"开启":"关闭"
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-const handleUpdate = async () => {
|
|
|
- const formData = new FormData()
|
|
|
- formData.append('id', editScreen.value.id)
|
|
|
- formData.append('type', editScreen.value.type)
|
|
|
-
|
|
|
- if (editFileList.value.length > 0) {
|
|
|
- editFileList.value.forEach(file => {
|
|
|
- formData.append('files', file.raw!)
|
|
|
- })
|
|
|
+const turnOrOffLight = async (screenControl: ScreenControl, cmd: number) => {
|
|
|
+ try {
|
|
|
+ const params = {
|
|
|
+ deviceCode: screenControl.deviceId,
|
|
|
+ cmd: cmd
|
|
|
+ };
|
|
|
+ const res = await clientPost<null,IsOpenResponse>("/screen/test/turnOffOrLight", null, { params });
|
|
|
+ if (res.code !== 200) {
|
|
|
+ ElMessage.error(`设备 ${screenControl.deviceId} 操作失败: ${res.msg}`);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ ElMessage.success(`设备 ${screenControl.deviceId} 操作成功`);
|
|
|
+ getList();
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error turning on/off light:', error);
|
|
|
+ ElMessage.error('操作失败,请稍后再试');
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- const res = await clientPut<FormData, BaseResponse>('/park/parkStemScreen/updateById', formData, {
|
|
|
- headers: {
|
|
|
- 'Content-Type': 'multipart/form-data'
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- if (res.code === 200) {
|
|
|
- ElMessage.success('修改成功')
|
|
|
- getList()
|
|
|
- editDialogVisible.value = false
|
|
|
- editFileList.value = []
|
|
|
- } else {
|
|
|
+const applyResource = async (item:ScreenControl)=>{
|
|
|
+ const params = {
|
|
|
+ deviceCode: item.deviceId,
|
|
|
+ url: "http://172.16.102.52:83/?deviceId=y4a-b23-00845"
|
|
|
+ }
|
|
|
+ const res = await clientPost<null,BaseResponse>("/screen/test/getTopWebPage",null,{params})
|
|
|
+ if(res.code !== 200){
|
|
|
ElMessage.error(res.msg)
|
|
|
+ }else {
|
|
|
+ ElMessage.success("资源应用成功");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 删除功能相关方法
|
|
|
-const handleDelete = async (id: string) => {
|
|
|
- ElMessageBox.confirm('确定要删除此大屏图片吗?', '提示', {
|
|
|
- confirmButtonText: '确定',
|
|
|
- cancelButtonText: '取消',
|
|
|
- type: 'warning'
|
|
|
- }).then(async () => {
|
|
|
- const res = await clientDel<null,BaseResponse>(`/park/parkStemScreen/deleteById?id=${id}`);
|
|
|
- if (res.code === 200) {
|
|
|
- ElMessage.success('删除成功')
|
|
|
- getList()
|
|
|
- } else {
|
|
|
- ElMessage.error(res.msg)
|
|
|
- }
|
|
|
- }).catch(() => {
|
|
|
- ElMessage.info('已取消删除')
|
|
|
- })
|
|
|
-}
|
|
|
+onMounted(() => {
|
|
|
+ getList()
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
- <div>
|
|
|
- <el-row class="p-20px" :gutter="20">
|
|
|
- <el-col :span="24" class="my-20px">
|
|
|
- <el-button type="primary" @click="addDialogVisible = true">新增大屏图片</el-button>
|
|
|
- </el-col>
|
|
|
- <el-col :lg="6" :sm="12" v-for="(item, index) in cardList" :key="index">
|
|
|
- <el-card style="max-width: 480px">
|
|
|
- <template #header>
|
|
|
- <div class="flex justify-between">
|
|
|
- <div>{{ item.type }}</div>
|
|
|
- <div>
|
|
|
- <el-button type="warning" @click="handleEdit(item)">修改</el-button>
|
|
|
- <el-button type="danger" @click="handleDelete(item.id)" v-if="false">删除</el-button>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <img
|
|
|
- :src="minioUrl + item.filePath[0]"
|
|
|
- style="width: 100%"
|
|
|
- alt="大屏图片"
|
|
|
- />
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
-
|
|
|
- <!-- 新增对话框 -->
|
|
|
- <el-dialog v-model="addDialogVisible" title="新增大屏图片" destroy-on-close>
|
|
|
- <el-form :model="newScreen" label-width="120px">
|
|
|
- <el-form-item label="类型">
|
|
|
- <el-input v-model="newScreen.type" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="文件上传">
|
|
|
- <el-upload
|
|
|
- action=""
|
|
|
- :on-change="handleAddFileChange"
|
|
|
- :auto-upload="false"
|
|
|
- :file-list="addFileList"
|
|
|
- >
|
|
|
- <el-button type="primary">选取文件</el-button>
|
|
|
- </el-upload>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
- <template #footer>
|
|
|
- <span class="dialog-footer">
|
|
|
- <el-button @click="addDialogVisible = false">取消</el-button>
|
|
|
- <el-button type="primary" @click="handleAdd">确定</el-button>
|
|
|
- </span>
|
|
|
+ <el-table :data="screenControls" style="width: 100%">
|
|
|
+ <!-- 原有列 -->
|
|
|
+ <el-table-column prop="id" label="ID" width="180" />
|
|
|
+ <el-table-column prop="deviceId" label="设备ID" width="180" />
|
|
|
+ <el-table-column label="状态" width="180">
|
|
|
+ <template #default="scope">
|
|
|
+ <span v-if="scope.row.state === 1">图片</span>
|
|
|
+ <span v-else-if="scope.row.state === 2">视频</span>
|
|
|
+ <span v-else>{{ scope.row.state }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="状态" width="180">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-tag>
|
|
|
+ {{ scope.row.isOpen || '未知' }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="createTime" label="创建时间" width="180">
|
|
|
+ <template #default="scope">
|
|
|
+ {{ formatDateTime(scope.row.createTime) }}
|
|
|
</template>
|
|
|
- </el-dialog>
|
|
|
-
|
|
|
- <!-- 修改对话框 -->
|
|
|
- <el-dialog v-model="editDialogVisible" title="修改大屏图片" destroy-on-close>
|
|
|
- <el-form :model="editScreen" label-width="120px">
|
|
|
- <el-form-item label="类型">
|
|
|
- <el-input v-model="editScreen.type" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="文件上传">
|
|
|
- <el-upload
|
|
|
- action=""
|
|
|
- :on-change="handleEditFileChange"
|
|
|
- :auto-upload="false"
|
|
|
- :file-list="editFileList"
|
|
|
- >
|
|
|
- <el-button type="primary">选取文件</el-button>
|
|
|
- </el-upload>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
- <template #footer>
|
|
|
- <span class="dialog-footer">
|
|
|
- <el-button @click="editDialogVisible = false">取消</el-button>
|
|
|
- <el-button type="primary" @click="handleUpdate">确定</el-button>
|
|
|
- </span>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="updateTime" label="更新时间" width="180">
|
|
|
+ <template #default="scope">
|
|
|
+ {{ formatDateTime(scope.row.updateTime) }}
|
|
|
</template>
|
|
|
- </el-dialog>
|
|
|
- </div>
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <!-- 操作列 -->
|
|
|
+ <el-table-column label="操作">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-button type="success" size="small" @click="applyResource(scope.row)">
|
|
|
+ 应用
|
|
|
+ </el-button>
|
|
|
+ <el-button type="primary" size="small" @click="openEditDialog(scope.row)">
|
|
|
+ 修改
|
|
|
+ </el-button>
|
|
|
+ <el-button type="warning" size="small" @click="openEditDialog(scope.row)">
|
|
|
+ 预览
|
|
|
+ </el-button>
|
|
|
+ <el-button type="info" size="small" @click="turnOrOffLight(scope.row,1)">
|
|
|
+ 开屏
|
|
|
+ </el-button>
|
|
|
+ <el-button type="danger" size="small" @click="turnOrOffLight(scope.row,0)">
|
|
|
+ 关屏
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <!-- 修改对话框 -->
|
|
|
+ <el-dialog v-model="dialogVisible" title="修改信息" width="30%">
|
|
|
+ <el-form :model="currentItem" label-width="80px">
|
|
|
+ <el-form-item label="ID">
|
|
|
+ <el-input v-model="currentItem.id" disabled />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="设备ID">
|
|
|
+ <el-input v-model="currentItem.deviceId" disabled />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="状态">
|
|
|
+ <el-select v-model="currentItem.state" placeholder="请选择">
|
|
|
+ <el-option
|
|
|
+ label="图片"
|
|
|
+ :value="1"
|
|
|
+ />
|
|
|
+ <el-option
|
|
|
+ label="视频"
|
|
|
+ :value="2"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item>
|
|
|
+ <el-upload
|
|
|
+ class="upload-demo"
|
|
|
+ :action="BASE_API+'/screen/file/upload'"
|
|
|
+ :before-upload="beforeUpload"
|
|
|
+ :accept="currentItem.state === 1 ? 'image/*' : 'video/*'"
|
|
|
+ :show-file-list="false"
|
|
|
+ :on-success="handleSuccess"
|
|
|
+ >
|
|
|
+ <el-button type="primary">点击上传</el-button>
|
|
|
+ <template #tip>
|
|
|
+ <div class="el-upload__tip" v-if="currentItem.state === 1">
|
|
|
+ 只能上传jpg/png等图片文件
|
|
|
+ </div>
|
|
|
+ <div class="el-upload__tip" v-else-if="currentItem.state === 2">
|
|
|
+ 只能上传mp4等视频文件
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-upload>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 资源预览 -->
|
|
|
+ <el-form-item label="预览">
|
|
|
+ <div v-if="previewUrl">
|
|
|
+ <img v-if="currentItem.state === 1" :src="previewUrl" alt="预览图片" style="max-width: 100%; height: auto;" />
|
|
|
+ <video v-else-if="currentItem.state === 2" :src="previewUrl" controls style="max-width: 100%; height: auto;">
|
|
|
+ 您的浏览器不支持 video 标签。
|
|
|
+ </video>
|
|
|
+ </div>
|
|
|
+ <div v-else>
|
|
|
+ 请上传文件以预览
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <span class="dialog-footer">
|
|
|
+ <el-button @click="dialogVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="saveEdit">保存</el-button>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</template>
|