From 39fca49ea6a52909aa19407f87aa5ea8c247920a Mon Sep 17 00:00:00 2001
From: Kven <2955163637@qq.com>
Date: Wed, 5 Mar 2025 21:15:40 +0800
Subject: [PATCH] =?UTF-8?q?feat(iot):=20=E6=96=B0=E5=A2=9E=E8=AE=BE?=
=?UTF-8?q?=E5=A4=87=E6=89=A7=E8=A1=8C=E6=9C=8D=E5=8A=A1=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 添加设备服务列表查询接口和下发命令接口
- 实现设备详情页面的服务执行功能
- 新增动态表单组件用于服务执行时的数据输入
- 优化设备详情页面布局和展示内容
---
src/api/device.ts | 20 +-
src/api/tsl.ts | 5 +
src/components/dynamic-form/index.vue | 636 +-----------------
.../iot/device/components/device-detail.vue | 149 +++-
.../iot/device/components/dynamic-form.vue | 38 ++
src/views/iot/device/index.vue | 9 +-
.../iot/product/components/product-tsl.vue | 6 +-
7 files changed, 216 insertions(+), 647 deletions(-)
create mode 100644 src/views/iot/device/components/dynamic-form.vue
diff --git a/src/api/device.ts b/src/api/device.ts
index 6d3e98d..8eecd47 100644
--- a/src/api/device.ts
+++ b/src/api/device.ts
@@ -5,7 +5,7 @@ export interface DeviceRecord {
size: number;
current: number;
name?: string;
- clientId?: string;
+ clientId?: number;
productId?: number;
status?: string;
isOnline?: boolean;
@@ -83,6 +83,15 @@ export function queryDeviceRecord(data: DeviceRecord) {
});
}
+// 执行服务列表
+export function queryDeviceServeList(data: DeviceRecord) {
+ return axios({
+ url: `/api/rest/device/serve`,
+ method: 'get',
+ params: data,
+ });
+}
+
// 批量创建
export function createDeviceBatch(data: DeviceCreateRecord) {
return axios.post(`/api/rest/device/batch`, data);
@@ -97,4 +106,13 @@ export function triggerEvent(data: DeviceEventRecord) {
});
}
+// 下发命令
+export function sendCommand(data: any) {
+ return axios({
+ url: `/api/rest/device/send`,
+ method: 'post',
+ data,
+ });
+}
+
diff --git a/src/api/tsl.ts b/src/api/tsl.ts
index 892b0f2..8abecc7 100644
--- a/src/api/tsl.ts
+++ b/src/api/tsl.ts
@@ -73,3 +73,8 @@ export function deleteProperty(data: any) {
export function deleteEvent(data: any) {
return axios.delete(`/api/rest/tsl/event/${data}`);
}
+
+// 服务详情
+export function queryServeDetail(id: number) {
+ return axios.get(`/api/rest/tsl/serve/${id}`);
+}
diff --git a/src/components/dynamic-form/index.vue b/src/components/dynamic-form/index.vue
index 0a2c686..1424064 100644
--- a/src/components/dynamic-form/index.vue
+++ b/src/components/dynamic-form/index.vue
@@ -1,630 +1,30 @@
-
-
-
-
-
-
-
-
-
- {{ formData.username }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+/* ... existing code ... */
+
\ No newline at end of file
diff --git a/src/views/iot/device/components/device-detail.vue b/src/views/iot/device/components/device-detail.vue
index 7fe63e5..4583dcb 100644
--- a/src/views/iot/device/components/device-detail.vue
+++ b/src/views/iot/device/components/device-detail.vue
@@ -16,12 +16,22 @@
设备详情
- {{ renderData.name }}
- {{ renderData.hardwareVersion }}
- {{ renderData.firmwareVersion }}
- {{ renderData.productId }}
+ {{
+ renderData.name
+ }}
+ {{
+ renderData.hardwareVersion
+ }}
+ {{
+ renderData.firmwareVersion
+ }}
+ {{
+ renderData.productName
+ }}
- {{dayjs(renderData.createTime).format('YYYY-MM-DD HH:mm:ss') }}
+ {{
+ dayjs(renderData.createTime).format('YYYY-MM-DD HH:mm:ss')
+ }}
@@ -35,39 +45,66 @@
-
+
所属产品详情
{{
- renderData.productName
- }}
+ renderData.productName
+ }}
{{
- renderData.productType
- }}
+ renderData.productType
+ }}
{{
- renderData.model
- }}
+ renderData.model
+ }}
{{
- renderData.link
- }}
+ renderData.link
+ }}
{{
- renderData.remark
- }}
+ renderData.remark
+ }}
{{
- dayjs(renderData.createTime).format('YYYY-MM-DD HH:mm:ss')
- }}
+ dayjs(renderData.createTime).format('YYYY-MM-DD HH:mm:ss')
+ }}
- 执行服务内容
+
+
+
+ 执行
+
+
+
+
+
+ 执行服务
+
+
+ 取消
+ 确定
+
+
@@ -75,9 +112,14 @@
import dayjs from 'dayjs';
import { useRoute } from 'vue-router';
import { onMounted, ref } from 'vue';
- import { queryDeviceDetail, queryDeviceRecord } from '@/api/device';
+ import { Message } from '@arco-design/web-vue';
+ import { queryDeviceDetail, queryDeviceRecord, sendCommand } from '@/api/device';
+ import { queryServeDetail, queryServeList } from '@/api/tsl';
+ import useVisible from '@/hooks/visible';
+ import dynamicForm from './dynamic-form.vue'
const route = useRoute();
+ const { visible, setVisible } = useVisible();
const id = Number(route.params.id);
const columns = [
{
@@ -113,21 +155,82 @@
slotName: 'content',
},
];
+ const deviceServeColumns = [
+ {
+ title: ' 服务名称',
+ dataIndex: 'name',
+ slotName: 'name',
+ },
+ {
+ title: '备注',
+ dataIndex: 'remark',
+ slotName: 'remark',
+ },
+ {
+ title: '操作',
+ dataIndex: 'operations',
+ slotName: 'operations',
+ },
+ ];
const activeKey = ref('1');
- const renderData = ref([]);
+ const renderData = ref({
+ clientId: 1,
+ productId: 1
+ });
const deviceReportData = ref([]);
+ const deviceServerData = ref([]);
+ const fields = ref([]);
const fetchData = async (Id: number) => {
const res = await queryDeviceDetail(Id);
renderData.value = res.data;
const res1 = await queryDeviceRecord({
+ clientId: renderData.value.clientId,
size: 10,
- current: 1
+ current: 1,
});
- deviceReportData.value = res1.data;
+ deviceReportData.value = res1.data.records;
+ const res2 = await queryServeList({
+ productId: renderData.value.productId,
+ size: 10,
+ current: 1,
+ })
+ deviceServerData.value = res2.data.records;
};
const handleMenuClick = (e: any) => {
activeKey.value = e;
};
+ const dynamicFormData = ref();
+ // 关闭
+ const handleCancel = async () => {
+ setVisible(false);
+ };
+
+ const openServeForm = async (record: object) => {
+ setVisible(true);
+ const res = await queryServeDetail(record.id);
+ fields.value = res.data.inputs;
+ };
+
+ const handleFormDataUpdate = (newFormData) => {
+ dynamicFormData.value = newFormData; // 更新 formData
+ };
+ // 确定
+ const handleSubmit = async () => {
+ const res = await sendCommand(dynamicFormData.value);
+ if (res.status === 200) {
+ Message.success({
+ content: '执行成功',
+ duration: 5 * 1000,
+ });
+ setVisible(false);
+ } else {
+ Message.error({
+ content: '执行失败',
+ duration: 5 * 1000,
+ });
+ }
+ };
+
onMounted(() => {
fetchData(id);
});
diff --git a/src/views/iot/device/components/dynamic-form.vue b/src/views/iot/device/components/dynamic-form.vue
new file mode 100644
index 0000000..fda01a6
--- /dev/null
+++ b/src/views/iot/device/components/dynamic-form.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/iot/device/index.vue b/src/views/iot/device/index.vue
index 69dc9ba..5a35e4e 100644
--- a/src/views/iot/device/index.vue
+++ b/src/views/iot/device/index.vue
@@ -226,7 +226,7 @@