【功能优化】Bpm:设备属性上报

This commit is contained in:
YunaiV 2025-01-28 04:55:48 +08:00
parent 3dc7d20005
commit 3d65f1c599
3 changed files with 61 additions and 57 deletions

View File

@ -63,15 +63,12 @@ export enum DeviceStatusEnum {
DISABLED = 3 // 已禁用 DISABLED = 3 // 已禁用
} }
// IoT 模拟设备数据 // IoT 模拟设备上报数据 Request VO
// TODO @superDeviceSimulatorDataReqVO export interface IotDeviceSimulationReportReqVO {
export interface SimulatorDataVO { id: number // 设备编号
productKey: string type: string // 消息类型
deviceKey: string identifier: string // 标识符
type: string data: object // 请求参数
subType: string
reportTime: number // 时间戳
content: string // 存储 JSON 字符串
} }
// 设备 API // 设备 API
@ -146,11 +143,12 @@ export const DeviceApi = {
return await request.download({ url: `/iot/device/get-import-template` }) return await request.download({ url: `/iot/device/get-import-template` })
}, },
// 模拟设备 // 模拟设备上报
simulatorDevice: async (data: SimulatorDataVO) => { simulationReportDevice: async (data: IotDeviceSimulationReportReqVO) => {
// TODO @super/iot/device/simulator // TODO @super/iot/device/simulator
return await request.post({ url: `/iot/device/data/simulator`, data }) return await request.post({ url: `/iot/device/simulation-report`, data })
}, },
// 查询设备日志分页 // 查询设备日志分页
getDeviceLogPage: async (params: any) => { getDeviceLogPage: async (params: any) => {
// TODO @super/iot/log-page 或者 /iot/log/page // TODO @super/iot/log-page 或者 /iot/log/page

View File

@ -52,7 +52,7 @@ import { DeviceApi } from '@/api/iot/device/device'
import { formatDate } from '@/utils/formatTime' import { formatDate } from '@/utils/formatTime'
const props = defineProps<{ const props = defineProps<{
deviceKey: number deviceKey: string
}>() }>()
//TODO:使 type subType //TODO:使 type subType

View File

@ -1,6 +1,5 @@
<template> <template>
<ContentWrap> <ContentWrap>
<!-- TODO @super建议每个 tab 做成一个小的组件命名为了排版整齐点可以叫 DeviceDetailsSimulatorPropertyUpstreamDeviceDetailsSimulatorEventUpstream -->
<el-row :gutter="20"> <el-row :gutter="20">
<!-- 左侧指令调试区域 --> <!-- 左侧指令调试区域 -->
<el-col :span="12"> <el-col :span="12">
@ -17,6 +16,7 @@
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
:stripe="true" :stripe="true"
> >
<!-- TODO @super每个 colum 搞下宽度避免 table 每一列最后有个 . -->
<el-table-column align="center" label="功能名称" prop="name" /> <el-table-column align="center" label="功能名称" prop="name" />
<el-table-column align="center" label="标识符" prop="identifier" /> <el-table-column align="center" label="标识符" prop="identifier" />
<el-table-column align="center" label="数据类型" prop="identifier"> <el-table-column align="center" label="数据类型" prop="identifier">
@ -38,9 +38,8 @@
].includes(row.property.dataType) ].includes(row.property.dataType)
" "
> >
取值范围{{ 取值范围
`${row.property.dataSpecs.min}~${row.property.dataSpecs.max}` {{ `${row.property.dataSpecs.min}~${row.property.dataSpecs.max}` }}
}}
</div> </div>
<!-- 非列表型文本 --> <!-- 非列表型文本 -->
<div v-if="DataSpecsDataType.TEXT === row.property.dataType"> <div v-if="DataSpecsDataType.TEXT === row.property.dataType">
@ -95,12 +94,19 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="mt-10px"> <div class="mt-10px">
<el-button type="primary" @click="handlePropertyReport">发送</el-button> <el-button
type="primary"
@click="handlePropertyReport"
v-hasPermi="['iot:device:simulation-report']"
>
发送
</el-button>
</div> </div>
</ContentWrap> </ContentWrap>
</el-tab-pane> </el-tab-pane>
<!-- 事件上报 --> <!-- 事件上报 -->
<!-- TODO @super待实现 -->
<el-tab-pane label="事件上报" name="event"> <el-tab-pane label="事件上报" name="event">
<ContentWrap> <ContentWrap>
<!-- <el-table v-loading="loading" :data="eventList" :stripe="true"> <!-- <el-table v-loading="loading" :data="eventList" :stripe="true">
@ -129,12 +135,12 @@
<el-tab-pane label="状态变更" name="status"> <el-tab-pane label="状态变更" name="status">
<ContentWrap> <ContentWrap>
<div class="flex gap-4"> <div class="flex gap-4">
<el-button type="primary" @click="handleDeviceState('online')" <el-button type="primary" @click="handleDeviceState('online')">
>设备上线</el-button 设备上线
> </el-button>
<el-button type="primary" @click="handleDeviceState('offline')" <el-button type="primary" @click="handleDeviceState('offline')">
>设备下线</el-button 设备下线
> </el-button>
</div> </div>
</ContentWrap> </ContentWrap>
</el-tab-pane> </el-tab-pane>
@ -142,6 +148,7 @@
</el-tab-pane> </el-tab-pane>
<!-- 下行指令调试 --> <!-- 下行指令调试 -->
<!-- TODO @super待实现 -->
<el-tab-pane label="下行指令调试" name="down"> <el-tab-pane label="下行指令调试" name="down">
<el-tabs v-model="subTab" v-if="activeTab === 'down'"> <el-tabs v-model="subTab" v-if="activeTab === 'down'">
<!-- 属性调试 --> <!-- 属性调试 -->
@ -170,6 +177,7 @@
</el-tab-pane> </el-tab-pane>
<!-- 服务调用 --> <!-- 服务调用 -->
<!-- TODO @super待实现 -->
<el-tab-pane label="服务调用" name="service"> <el-tab-pane label="服务调用" name="service">
<ContentWrap> <ContentWrap>
<!-- 服务调用相关内容 --> <!-- 服务调用相关内容 -->
@ -184,7 +192,7 @@
<el-col :span="12"> <el-col :span="12">
<el-tabs type="border-card"> <el-tabs type="border-card">
<el-tab-pane label="设备日志"> <el-tab-pane label="设备日志">
<DeviceDetailsLog :deviceKey="device.deviceKey" /> <DeviceDetailsLog :device-key="device.deviceKey" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-col> </el-col>
@ -195,7 +203,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ProductVO } from '@/api/iot/product/product' import { ProductVO } from '@/api/iot/product/product'
import { ThingModelApi, SimulatorData } from '@/api/iot/thingmodel' import { ThingModelApi, SimulatorData } from '@/api/iot/thingmodel'
import { DeviceApi, DeviceVO, SimulatorDataVO } from '@/api/iot/device/device' import { DeviceApi, DeviceVO } from '@/api/iot/device/device'
import DeviceDetailsLog from './DeviceDetailsLog.vue' import DeviceDetailsLog from './DeviceDetailsLog.vue'
import { import {
DataSpecsDataType, DataSpecsDataType,
@ -205,26 +213,33 @@ import {
ThingModelType ThingModelType
} from '@/views/iot/thingmodel/config' } from '@/views/iot/thingmodel/config'
const message = useMessage() // const props = defineProps<{
const loading = ref(false) product: ProductVO
const activeTab = ref('up') device: DeviceVO
const subTab = ref('property') }>()
const message = useMessage() //
const activeTab = ref('up') // TODO @superupstream downstream
const subTab = ref('property') // TODO @superupstreamTab
const loading = ref(false)
const queryParams = reactive({ const queryParams = reactive({
type: undefined, type: undefined, // TODO @supertype tab watch
productId: -1 productId: -1
}) })
const list = ref<SimulatorData[]>([]) // TODO @superthingModelList
// TODO @superdataTypeOptionsLabel getDataTypeOptionsLabel template 使
const dataTypeOptionsLabel = computed(() => (value: string) => getDataTypeOptionsLabel(value)) // const dataTypeOptionsLabel = computed(() => (value: string) => getDataTypeOptionsLabel(value)) //
const props = defineProps<{ product: ProductVO; device: DeviceVO }>()
const list = ref<SimulatorData[]>([]) //
/** 查询列表 */ /** 查询物模型列表 */
// TODO @supergetThingModelList
const getList = async () => { const getList = async () => {
loading.value = true loading.value = true
try { try {
queryParams.productId = props.product?.id || -1 queryParams.productId = props.product?.id || -1
const data = await ThingModelApi.getThingModelList(queryParams) const data = await ThingModelApi.getThingModelList(queryParams)
// simulateValue // simulateValue
// TODO @super simulateValue
list.value = data.map((item) => ({ list.value = data.map((item) => ({
...item, ...item,
simulateValue: '' simulateValue: ''
@ -262,7 +277,8 @@ const getList = async () => {
// })) // }))
// }) // })
// todo: /** 监听标签页变化 */
// todo:
watch( watch(
[activeTab, subTab], [activeTab, subTab],
([newActiveTab, newSubTab]) => { ([newActiveTab, newSubTab]) => {
@ -294,36 +310,26 @@ watch(
{ immediate: true } { immediate: true }
) )
// interface ReportData { /** 处理属性上报 */
// productKey: string
// deviceKey: string
// type: string
// subType: string
// reportTime: string
// content: string // string JSON
// }
// TODO:
const handlePropertyReport = async () => { const handlePropertyReport = async () => {
const contentObj: Record<string, any> = {} // TODO @super:
const data: Record<string, object> = {}
list.value.forEach((item) => { list.value.forEach((item) => {
// simulateValue content // simulateValue content
// TODO @super if (item.simulateValue) js
if (item.simulateValue !== undefined && item.simulateValue !== '') { if (item.simulateValue !== undefined && item.simulateValue !== '') {
contentObj[item.identifier] = item.simulateValue // TODO @super idea
data[item.identifier] = item.simulateValue
} }
}) })
const reportData: SimulatorDataVO = {
productKey: props.product.productKey,
deviceKey: props.device.deviceKey,
type: 'property',
subType: 'report',
reportTime: Date.now(), // reportTime
content: JSON.stringify(contentObj) // JSON
}
try { try {
await DeviceApi.simulatorDevice(reportData) await DeviceApi.simulationReportDevice({
id: props.device.id,
type: 'property',
identifier: 'report',
data: data
})
message.success('属性上报成功') message.success('属性上报成功')
} catch (error) { } catch (error) {
message.error('属性上报失败') message.error('属性上报失败')