2025-01-06 11:03:30 +08:00
|
|
|
<template>
|
2025-01-08 11:13:44 +08:00
|
|
|
<div class="container">
|
|
|
|
<Breadcrumb :items="['物联网管理', '设备管理', '设备详情']" />
|
|
|
|
<a-card class="general-card" title=" ">
|
|
|
|
<a-descriptions v-model="renderData" size="large">
|
2025-02-17 22:42:51 +08:00
|
|
|
<template #title
|
|
|
|
><h3 style="margin-top: -15px"
|
|
|
|
><a-button
|
|
|
|
class="nav-btn"
|
|
|
|
type="outline"
|
|
|
|
:shape="'circle'"
|
|
|
|
@click="() => $router.go(-1)"
|
|
|
|
>
|
|
|
|
<icon-undo />
|
|
|
|
</a-button>
|
|
|
|
设备详情</h3
|
|
|
|
>
|
2025-01-29 14:09:31 +08:00
|
|
|
</template>
|
2025-03-05 21:15:40 +08:00
|
|
|
<a-descriptions-item label="设备名称">{{
|
|
|
|
renderData.name
|
|
|
|
}}</a-descriptions-item>
|
|
|
|
<a-descriptions-item label="硬件版本">{{
|
|
|
|
renderData.hardwareVersion
|
|
|
|
}}</a-descriptions-item>
|
|
|
|
<a-descriptions-item label="固件版本">{{
|
|
|
|
renderData.firmwareVersion
|
|
|
|
}}</a-descriptions-item>
|
|
|
|
<a-descriptions-item label="所属产品">{{
|
|
|
|
renderData.productName
|
|
|
|
}}</a-descriptions-item>
|
2025-02-17 22:42:51 +08:00
|
|
|
<!-- <a-descriptions-item label="备注">{{renderData.remark }}</a-descriptions-item>-->
|
2025-03-05 21:15:40 +08:00
|
|
|
<a-descriptions-item label="创建时间">{{
|
|
|
|
dayjs(renderData.createTime).format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
}}</a-descriptions-item>
|
2025-01-08 11:13:44 +08:00
|
|
|
</a-descriptions>
|
|
|
|
</a-card>
|
|
|
|
<a-card class="general-card" style="margin-top: 10px">
|
2025-02-17 22:42:51 +08:00
|
|
|
<a-tabs
|
|
|
|
:active-key="activeKey"
|
|
|
|
@tab-click="handleMenuClick"
|
|
|
|
style="padding-top: 20px"
|
|
|
|
>
|
2025-01-08 11:13:44 +08:00
|
|
|
<a-tab-pane key="1" tab="参数" title="扩展属性">
|
2025-02-25 16:37:41 +08:00
|
|
|
<a-table :columns="columns" :data="renderData.params" />
|
2025-01-08 11:13:44 +08:00
|
|
|
</a-tab-pane>
|
|
|
|
<a-tab-pane key="2" tab="基本信息" title="基本信息">
|
2025-02-25 22:00:47 +08:00
|
|
|
<a-card class="general-card" title=" ">
|
2025-03-05 21:15:40 +08:00
|
|
|
<a-descriptions size="large">
|
2025-02-25 22:00:47 +08:00
|
|
|
<template #title>
|
|
|
|
<h3 style="margin-top: -15px">所属产品详情</h3>
|
|
|
|
</template>
|
|
|
|
<a-descriptions-item label="产品名称">{{
|
2025-03-05 21:15:40 +08:00
|
|
|
renderData.productName
|
|
|
|
}}</a-descriptions-item>
|
2025-02-25 22:00:47 +08:00
|
|
|
<a-descriptions-item label="产品类型">{{
|
2025-03-05 21:15:40 +08:00
|
|
|
renderData.productType
|
|
|
|
}}</a-descriptions-item>
|
2025-02-25 22:00:47 +08:00
|
|
|
<a-descriptions-item label="产品型号">{{
|
2025-03-05 21:15:40 +08:00
|
|
|
renderData.model
|
|
|
|
}}</a-descriptions-item>
|
2025-02-25 22:00:47 +08:00
|
|
|
<a-descriptions-item label="通讯协议">{{
|
2025-03-05 21:15:40 +08:00
|
|
|
renderData.link
|
|
|
|
}}</a-descriptions-item>
|
2025-02-25 22:00:47 +08:00
|
|
|
<a-descriptions-item label="备注">{{
|
2025-03-05 21:15:40 +08:00
|
|
|
renderData.remark
|
|
|
|
}}</a-descriptions-item>
|
2025-02-25 22:00:47 +08:00
|
|
|
<a-descriptions-item label="创建时间">{{
|
2025-03-05 21:15:40 +08:00
|
|
|
dayjs(renderData.createTime).format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
}}</a-descriptions-item>
|
2025-02-25 22:00:47 +08:00
|
|
|
</a-descriptions>
|
|
|
|
</a-card>
|
2025-01-08 11:13:44 +08:00
|
|
|
</a-tab-pane>
|
2025-02-17 22:42:51 +08:00
|
|
|
<a-tab-pane key="3" tab="执行服务" title="执行服务">
|
2025-03-05 21:15:40 +08:00
|
|
|
<a-table :columns="deviceServeColumns" :data="deviceServerData" >
|
|
|
|
<template #operations="{ record }">
|
|
|
|
<a-button
|
|
|
|
type="text"
|
|
|
|
status="success"
|
|
|
|
@click="openServeForm(record)"
|
|
|
|
>
|
2025-03-07 19:16:59 +08:00
|
|
|
<icon-plus />执行
|
2025-03-05 21:15:40 +08:00
|
|
|
</a-button>
|
|
|
|
</template>
|
|
|
|
</a-table>
|
2025-02-17 22:42:51 +08:00
|
|
|
</a-tab-pane>
|
2025-03-02 17:53:03 +08:00
|
|
|
<a-tab-pane key="4" tab="上报记录" title="上报记录">
|
|
|
|
<a-table :columns="deviceReportColumns" :data="deviceReportData" />
|
|
|
|
</a-tab-pane>
|
2025-01-08 11:13:44 +08:00
|
|
|
</a-tabs>
|
|
|
|
</a-card>
|
2025-03-05 21:15:40 +08:00
|
|
|
|
|
|
|
<a-modal
|
2025-03-07 19:16:59 +08:00
|
|
|
width="1100px"
|
2025-03-05 21:15:40 +08:00
|
|
|
height="500px"
|
|
|
|
:visible="visible"
|
|
|
|
@cancel="handleCancel"
|
|
|
|
>
|
|
|
|
<template #title>执行服务</template>
|
|
|
|
<dynamicForm
|
|
|
|
:fields="fields"
|
|
|
|
@update:form-data="handleFormDataUpdate"
|
|
|
|
/>
|
|
|
|
<template #footer>
|
|
|
|
<a-button class="editor-button" @click="handleCancel">取消</a-button>
|
|
|
|
<a-button class="editor-button" type="primary" @click="handleSubmit">确定</a-button>
|
|
|
|
</template>
|
|
|
|
</a-modal>
|
2025-01-08 11:13:44 +08:00
|
|
|
</div>
|
2025-01-06 11:03:30 +08:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
2025-01-08 11:13:44 +08:00
|
|
|
import dayjs from 'dayjs';
|
|
|
|
import { useRoute } from 'vue-router';
|
2025-03-07 19:16:59 +08:00
|
|
|
import { onMounted, reactive, ref } from 'vue';
|
2025-03-05 21:15:40 +08:00
|
|
|
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'
|
2025-01-06 11:03:30 +08:00
|
|
|
|
2025-01-08 11:13:44 +08:00
|
|
|
const route = useRoute();
|
2025-03-05 21:15:40 +08:00
|
|
|
const { visible, setVisible } = useVisible();
|
2025-01-08 11:13:44 +08:00
|
|
|
const id = Number(route.params.id);
|
|
|
|
const columns = [
|
|
|
|
{
|
|
|
|
title: '参数名称',
|
|
|
|
dataIndex: 'name',
|
|
|
|
slotName: 'name',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '参数标识',
|
|
|
|
dataIndex: 'identifier',
|
|
|
|
slotName: 'identifier',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '数据类型',
|
|
|
|
dataIndex: 'dataType',
|
|
|
|
slotName: 'dataType',
|
2025-01-06 11:03:30 +08:00
|
|
|
},
|
2025-01-08 11:13:44 +08:00
|
|
|
{
|
|
|
|
title: '参数类型',
|
|
|
|
dataIndex: 'type',
|
|
|
|
slotName: 'type',
|
|
|
|
},
|
|
|
|
];
|
2025-03-02 17:53:03 +08:00
|
|
|
const deviceReportColumns = [
|
|
|
|
{
|
|
|
|
title: '上报时间',
|
|
|
|
dataIndex: 'recordTime',
|
|
|
|
slotName: 'recordTime',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '内容',
|
|
|
|
dataIndex: 'content',
|
|
|
|
slotName: 'content',
|
|
|
|
},
|
|
|
|
];
|
2025-03-05 21:15:40 +08:00
|
|
|
const deviceServeColumns = [
|
|
|
|
{
|
|
|
|
title: ' 服务名称',
|
|
|
|
dataIndex: 'name',
|
|
|
|
slotName: 'name',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '备注',
|
|
|
|
dataIndex: 'remark',
|
|
|
|
slotName: 'remark',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '操作',
|
|
|
|
dataIndex: 'operations',
|
|
|
|
slotName: 'operations',
|
|
|
|
},
|
|
|
|
];
|
2025-01-08 11:13:44 +08:00
|
|
|
const activeKey = ref('1');
|
2025-03-05 21:15:40 +08:00
|
|
|
const renderData = ref({
|
2025-03-07 19:16:59 +08:00
|
|
|
deviceId: 0,
|
2025-03-05 21:15:40 +08:00
|
|
|
clientId: 1,
|
|
|
|
productId: 1
|
|
|
|
});
|
2025-03-02 17:53:03 +08:00
|
|
|
const deviceReportData = ref([]);
|
2025-03-05 21:15:40 +08:00
|
|
|
const deviceServerData = ref([]);
|
|
|
|
const fields = ref([]);
|
2025-01-08 11:13:44 +08:00
|
|
|
const fetchData = async (Id: number) => {
|
|
|
|
const res = await queryDeviceDetail(Id);
|
|
|
|
renderData.value = res.data;
|
2025-03-02 17:53:03 +08:00
|
|
|
const res1 = await queryDeviceRecord({
|
2025-03-05 21:15:40 +08:00
|
|
|
clientId: renderData.value.clientId,
|
2025-03-02 17:53:03 +08:00
|
|
|
size: 10,
|
2025-03-05 21:15:40 +08:00
|
|
|
current: 1,
|
2025-03-02 17:53:03 +08:00
|
|
|
});
|
2025-03-05 21:15:40 +08:00
|
|
|
deviceReportData.value = res1.data.records;
|
|
|
|
const res2 = await queryServeList({
|
|
|
|
productId: renderData.value.productId,
|
|
|
|
size: 10,
|
|
|
|
current: 1,
|
|
|
|
})
|
|
|
|
deviceServerData.value = res2.data.records;
|
2025-01-08 11:13:44 +08:00
|
|
|
};
|
|
|
|
const handleMenuClick = (e: any) => {
|
|
|
|
activeKey.value = e;
|
|
|
|
};
|
2025-03-05 21:15:40 +08:00
|
|
|
const dynamicFormData = ref();
|
2025-03-07 19:16:59 +08:00
|
|
|
const formRef = ref();
|
2025-03-05 21:15:40 +08:00
|
|
|
// 关闭
|
|
|
|
const handleCancel = async () => {
|
|
|
|
setVisible(false);
|
|
|
|
};
|
|
|
|
|
|
|
|
const openServeForm = async (record: object) => {
|
|
|
|
setVisible(true);
|
|
|
|
const res = await queryServeDetail(record.id);
|
|
|
|
fields.value = res.data.inputs;
|
|
|
|
};
|
|
|
|
|
2025-03-07 19:16:59 +08:00
|
|
|
const handleFormDataUpdate = (newFormData: any) => {
|
2025-03-05 21:15:40 +08:00
|
|
|
dynamicFormData.value = newFormData; // 更新 formData
|
|
|
|
};
|
|
|
|
// 确定
|
|
|
|
const handleSubmit = async () => {
|
2025-03-07 19:16:59 +08:00
|
|
|
try {
|
|
|
|
const { qos, ...rest } = dynamicFormData.value;
|
|
|
|
const params = {
|
|
|
|
deviceId: id,
|
|
|
|
qos,
|
|
|
|
paras: rest,
|
|
|
|
};
|
|
|
|
console.log(params);
|
|
|
|
const res = await sendCommand(params);
|
|
|
|
if (res.status === 200) {
|
|
|
|
Message.success({
|
|
|
|
content: '执行成功',
|
|
|
|
duration: 5 * 1000,
|
|
|
|
});
|
|
|
|
setVisible(false);
|
|
|
|
} else {
|
|
|
|
Message.error({
|
|
|
|
content: '执行失败',
|
|
|
|
duration: 5 * 1000,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} catch (error) {
|
2025-03-05 21:15:40 +08:00
|
|
|
Message.error({
|
2025-03-07 19:16:59 +08:00
|
|
|
content: '表单不能为空',
|
2025-03-05 21:15:40 +08:00
|
|
|
duration: 5 * 1000,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2025-01-08 11:13:44 +08:00
|
|
|
onMounted(() => {
|
|
|
|
fetchData(id);
|
2025-01-06 11:03:30 +08:00
|
|
|
});
|
2025-01-08 11:13:44 +08:00
|
|
|
</script>
|
2025-01-06 11:03:30 +08:00
|
|
|
|
2025-01-08 11:13:44 +08:00
|
|
|
<style scoped>
|
|
|
|
.container {
|
|
|
|
padding: 0 20px 20px 20px;
|
|
|
|
}
|
2025-01-06 11:03:30 +08:00
|
|
|
|
2025-01-08 11:13:44 +08:00
|
|
|
h1 {
|
|
|
|
font-size: 24px;
|
|
|
|
margin-bottom: 10px;
|
|
|
|
}
|
2025-01-06 11:03:30 +08:00
|
|
|
|
2025-01-08 11:13:44 +08:00
|
|
|
.meta span {
|
|
|
|
margin-right: 20px;
|
|
|
|
}
|
2025-01-06 11:03:30 +08:00
|
|
|
|
2025-01-08 11:13:44 +08:00
|
|
|
.attachments li {
|
|
|
|
margin-bottom: 10px;
|
|
|
|
}
|
2025-01-06 11:03:30 +08:00
|
|
|
|
2025-01-08 11:13:44 +08:00
|
|
|
.attachments a {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
font-size: 14px;
|
|
|
|
color: #1890ff;
|
|
|
|
text-decoration: none;
|
|
|
|
}
|
2025-01-06 11:03:30 +08:00
|
|
|
|
2025-01-08 11:13:44 +08:00
|
|
|
.attachments a:hover {
|
|
|
|
text-decoration: underline;
|
2025-01-06 11:03:30 +08:00
|
|
|
}
|
2025-01-29 14:09:31 +08:00
|
|
|
.nav-btn {
|
|
|
|
border-color: rgb(var(--gray-2));
|
|
|
|
color: rgb(var(--gray-8));
|
|
|
|
font-size: 16px;
|
|
|
|
}
|
2025-01-06 11:03:30 +08:00
|
|
|
</style>
|