From 3113bac66843dcc9acde8945f2ab370658a3691d Mon Sep 17 00:00:00 2001 From: Kven <2955163637@qq.com> Date: Mon, 10 Mar 2025 20:55:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(iot):=20=E6=96=B0=E5=A2=9E=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E5=9C=B0=E5=9B=BE=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E4=BA=A7=E5=93=81=E7=BC=96=E8=BE=91=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增设备地图组件,用于展示设备在地图上的位置 -优化产品编辑界面,增加预览图和图标上传功能 - 修改 API 调用路径,使用 SSE (Server-Sent Events) 实现实时数据推送 - 更新表格展示,增加设备上报记录的详细信息 --- package.json | 3 + src/api/dashboard.ts | 8 +- src/api/product.ts | 10 ++ src/assets/images/device.png | Bin 0 -> 3524 bytes src/views/dashboard/workplace/index.vue | 65 +++++++--- .../iot/device/components/device-detail.vue | 20 ++- .../iot/device/components/device-map.vue | 117 ++++++++++++++++++ src/views/iot/deviceMap/index.vue | 2 +- .../iot/product/components/product-edit.vue | 67 +++++++++- .../iot/product/components/product-tsl.vue | 34 ++++- 10 files changed, 301 insertions(+), 25 deletions(-) create mode 100644 src/assets/images/device.png create mode 100644 src/views/iot/device/components/device-map.vue diff --git a/package.json b/package.json index bc65987..92a666e 100644 --- a/package.json +++ b/package.json @@ -34,12 +34,15 @@ "@amap/amap-jsapi-loader": "^1.0.1", "@amap/amap-jsapi-types": "^0.0.15", "@arco-design/web-vue": "^2.44.7", + "@commitlint/load": "^19.8.0", "@vueuse/core": "^9.3.0", "@wangeditor/editor-for-vue": "^5.1.12", "arco-design-pro-vue": "^2.7.2", "axios": "^0.24.0", + "cosmiconfig": "^9.0.0", "dayjs": "^1.11.5", "echarts": "^5.4.0", + "event-source-polyfill": "^1.0.31", "exceljs": "^4.4.0", "file-saver": "^2.0.5", "lodash": "^4.17.21", diff --git a/src/api/dashboard.ts b/src/api/dashboard.ts index c26bbf5..523598c 100644 --- a/src/api/dashboard.ts +++ b/src/api/dashboard.ts @@ -3,20 +3,20 @@ import axios from 'axios'; // 获取设备信息 export function getDeviceInfo() { - return axios.get('/api/rest/device/status'); + return axios.get('/api/rest/device/sse/status'); } // 获取消息信息 export function getMessageInfo() { - return axios.get('/api/rest/device/record/status'); + return axios.get('/api/rest/device/sse/record/status'); } // 获取告警信息 export function getAlarmInfo() { - return axios.get('/api/rest/device/data/status'); + return axios.get('/api/rest/device/sse/data/status'); } // 获取产品信息 export function getProductInfo() { - return axios.get('/api/rest/product/status'); + return axios.get('/api/rest/product/sse/status'); } \ No newline at end of file diff --git a/src/api/product.ts b/src/api/product.ts index f527438..ad14eff 100644 --- a/src/api/product.ts +++ b/src/api/product.ts @@ -66,3 +66,13 @@ export function updateProduct(data: ProductUpdateRecord) { export function deleteProduct(id: number) { return axios.delete(`/api/rest/product/${id}`); } + +// 文件上传 +export function addAttachments(data: any) { + return axios.post(`/api/rest/product/upload`, data); +} + +// 文件删除 +export function deleteAttachment(id: number) { + return axios.delete(`/api/rest/product/attachments/${id}`); +} diff --git a/src/assets/images/device.png b/src/assets/images/device.png new file mode 100644 index 0000000000000000000000000000000000000000..fa44fd6a6cf23aedd3cd25260e6fd4e90d6c7da2 GIT binary patch literal 3524 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 literal 0 HcmV?d00001 diff --git a/src/views/dashboard/workplace/index.vue b/src/views/dashboard/workplace/index.vue index 4e45018..b5e1989 100644 --- a/src/views/dashboard/workplace/index.vue +++ b/src/views/dashboard/workplace/index.vue @@ -3,7 +3,7 @@
- +
@@ -21,8 +21,11 @@ diff --git a/src/views/iot/device/components/device-detail.vue b/src/views/iot/device/components/device-detail.vue index 2d99c4b..90309fb 100644 --- a/src/views/iot/device/components/device-detail.vue +++ b/src/views/iot/device/components/device-detail.vue @@ -84,7 +84,22 @@ - + + + + + + + + + + @@ -116,7 +131,8 @@ import { queryDeviceDetail, queryDeviceRecord, sendCommand } from '@/api/device'; import { queryServeDetail, queryServeList } from '@/api/tsl'; import useVisible from '@/hooks/visible'; - import dynamicForm from './dynamic-form.vue' + import dynamicForm from './dynamic-form.vue'; + import DeviceMap from './device-map.vue'; const route = useRoute(); const { visible, setVisible } = useVisible(); diff --git a/src/views/iot/device/components/device-map.vue b/src/views/iot/device/components/device-map.vue new file mode 100644 index 0000000..bfffda8 --- /dev/null +++ b/src/views/iot/device/components/device-map.vue @@ -0,0 +1,117 @@ + + + + + \ No newline at end of file diff --git a/src/views/iot/deviceMap/index.vue b/src/views/iot/deviceMap/index.vue index bbc5fbb..7c0bcd6 100644 --- a/src/views/iot/deviceMap/index.vue +++ b/src/views/iot/deviceMap/index.vue @@ -55,7 +55,7 @@ // 将标记点添加到地图上 map.setCenter(lngLat); - map.setZoom(16); + map.setZoom(20); map.add(marker); // const infoContent = ` diff --git a/src/views/iot/product/components/product-edit.vue b/src/views/iot/product/components/product-edit.vue index c722820..13be49c 100644 --- a/src/views/iot/product/components/product-edit.vue +++ b/src/views/iot/product/components/product-edit.vue @@ -30,7 +30,7 @@ + + + + + + + +
@@ -209,6 +237,7 @@ ProductCreateRecord, queryProductDetail, updateProduct, + addAttachments, deleteAttachment } from '@/api/product'; const props = defineProps({ @@ -298,6 +327,42 @@ formData.value = res.data; paramsData.value = res.data.params; }; + + // 预览图列表 + const fileList = computed(() => { + return formData.value.attachments?.map((item: any) => { + return { + name: item.fileName, + url: item.url, + uid: item.id, + }; + }); + }); + // 自定义预览图上传 + const customRequest = async (option: any) => { + const { fileItem, onSuccess, onError } = option; + const formDataFile = new FormData(); + formDataFile.append('file', fileItem.file); + formDataFile.append('type', '其他'); + const res = await addAttachments(formDataFile); + if (res.status === 200) { + onSuccess(res.data); + formData.value.attachmentIds?.push(res.data.id); + console.log(formData.value); + } else { + onError(res.data); + } + }; + // 删除图片 + const beforeRemove = async (file: any) => { + if (!file.uid) { + const res = await deleteAttachment(file.response.id); + return res.status === 200; + } + const res = await deleteAttachment(file.uid); + return res.status === 200; + }; + // 组件被点击 const handleClick = () => { setVisible(true); diff --git a/src/views/iot/product/components/product-tsl.vue b/src/views/iot/product/components/product-tsl.vue index 7ad602b..a181388 100644 --- a/src/views/iot/product/components/product-tsl.vue +++ b/src/views/iot/product/components/product-tsl.vue @@ -310,7 +310,7 @@ - + + + (() => [ + { + label: '大于', + value: 'GREATER', + }, + { + label: '小于', + value: 'LESS', + }, + { + label: '等于', + value: 'EQUAL', + }, + ]); const eventTypeOptions = computed(() => [ { label: '主动',