mirror of
https://gitee.com/myxzgzs/boyue-ui-admin-vue3
synced 2025-08-09 08:52:41 +08:00
feat;simulator
This commit is contained in:
parent
5e8aad7703
commit
b71fa84af3
@ -63,6 +63,16 @@ export enum DeviceStatusEnum {
|
|||||||
DISABLED = 3 // 已禁用
|
DISABLED = 3 // 已禁用
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IoT 模拟设备数据
|
||||||
|
export interface SimulatorDataVO {
|
||||||
|
productKey: string
|
||||||
|
deviceKey: string
|
||||||
|
type: string
|
||||||
|
subType: string
|
||||||
|
reportTime: string
|
||||||
|
content: string // 存储 JSON 字符串
|
||||||
|
}
|
||||||
|
|
||||||
// 设备 API
|
// 设备 API
|
||||||
export const DeviceApi = {
|
export const DeviceApi = {
|
||||||
// 查询设备分页
|
// 查询设备分页
|
||||||
@ -136,5 +146,10 @@ export const DeviceApi = {
|
|||||||
// 获取导入模板
|
// 获取导入模板
|
||||||
importDeviceTemplate: async () => {
|
importDeviceTemplate: async () => {
|
||||||
return await request.download({ url: `/iot/device/get-import-template` })
|
return await request.download({ url: `/iot/device/get-import-template` })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 模拟设备
|
||||||
|
simulatorDevice: async (data: SimulatorDataVO) => {
|
||||||
|
return await request.post({ url: `/iot/device/data/simulator`, data })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,23 +90,23 @@ const typeMap = {
|
|||||||
|
|
||||||
/** 查询日志列表 */
|
/** 查询日志列表 */
|
||||||
const getLogList = async () => {
|
const getLogList = async () => {
|
||||||
if (!props.deviceId) return
|
// if (!props.deviceId) return
|
||||||
loading.value = true
|
// loading.value = true
|
||||||
try {
|
// try {
|
||||||
const res = await DeviceApi.getDeviceLogs(props.deviceId, queryParams)
|
// const res = await DeviceApi.getDeviceLogs(props.deviceId, queryParams)
|
||||||
total.value = res.total
|
// total.value = res.total
|
||||||
logList.value = res.list.map((item: any) => {
|
// logList.value = res.list.map((item: any) => {
|
||||||
const log = {
|
// const log = {
|
||||||
time: item.time,
|
// time: item.time,
|
||||||
type: typeMap[item.type as keyof typeof typeMap] || item.type,
|
// type: typeMap[item.type as keyof typeof typeMap] || item.type,
|
||||||
name: getLogName(item),
|
// name: getLogName(item),
|
||||||
content: item.content
|
// content: item.content
|
||||||
}
|
// }
|
||||||
return log
|
// return log
|
||||||
})
|
// })
|
||||||
} finally {
|
// } finally {
|
||||||
loading.value = false
|
// loading.value = false
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取日志名称 */
|
/** 获取日志名称 */
|
||||||
|
@ -11,11 +11,6 @@
|
|||||||
<el-tab-pane label="属性上报" name="property">
|
<el-tab-pane label="属性上报" name="property">
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
||||||
<el-table-column label="值" align="center" width="80">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input v-model="scope.row.value" class="!w-60px" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<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">
|
||||||
@ -87,6 +82,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="值" align="center" width="80">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input v-model="scope.row.simulateValue" class="!w-60px" />
|
||||||
|
</template>
|
||||||
|
</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">发送</el-button>
|
||||||
@ -98,11 +98,6 @@
|
|||||||
<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">
|
||||||
<el-table-column label="值" align="center" width="80">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input v-model="scope.row.value" class="!w-60px" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="功能名称" align="center" prop="name" />
|
<el-table-column label="功能名称" align="center" prop="name" />
|
||||||
<el-table-column label="标识符" align="center" prop="identifier" />
|
<el-table-column label="标识符" align="center" prop="identifier" />
|
||||||
<el-table-column label="数据类型" align="center" prop="dataType" />
|
<el-table-column label="数据类型" align="center" prop="dataType" />
|
||||||
@ -112,6 +107,11 @@
|
|||||||
prop="specs"
|
prop="specs"
|
||||||
:show-overflow-tooltip="true"
|
:show-overflow-tooltip="true"
|
||||||
/>
|
/>
|
||||||
|
<el-table-column label="值" align="center" width="80">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input v-model="scope.row.simulateValue" class="!w-60px" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<div class="mt-10px">
|
<div class="mt-10px">
|
||||||
<el-button type="primary" @click="handleEventReport">发送</el-button>
|
<el-button type="primary" @click="handleEventReport">发送</el-button>
|
||||||
@ -142,11 +142,6 @@
|
|||||||
<el-tab-pane label="属性调试" name="propertyDebug">
|
<el-tab-pane label="属性调试" name="propertyDebug">
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="propertyList" :stripe="true">
|
<el-table v-loading="loading" :data="propertyList" :stripe="true">
|
||||||
<el-table-column label="值" align="center" width="80">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-input v-model="scope.row.value" class="!w-60px" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="功能名称" align="center" prop="name" />
|
<el-table-column label="功能名称" align="center" prop="name" />
|
||||||
<el-table-column label="标识符" align="center" prop="identifier" />
|
<el-table-column label="标识符" align="center" prop="identifier" />
|
||||||
<el-table-column label="数据类型" align="center" prop="dataType" />
|
<el-table-column label="数据类型" align="center" prop="dataType" />
|
||||||
@ -156,6 +151,11 @@
|
|||||||
prop="specs"
|
prop="specs"
|
||||||
:show-overflow-tooltip="true"
|
:show-overflow-tooltip="true"
|
||||||
/>
|
/>
|
||||||
|
<el-table-column label="值" align="center" width="80">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input v-model="scope.row.simulateValue" class="!w-60px" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<div class="mt-10px">
|
<div class="mt-10px">
|
||||||
<el-button type="primary" @click="handlePropertyGet">获取</el-button>
|
<el-button type="primary" @click="handlePropertyGet">获取</el-button>
|
||||||
@ -189,7 +189,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, ThingModelData } from '@/api/iot/thingmodel'
|
import { ThingModelApi, ThingModelData } from '@/api/iot/thingmodel'
|
||||||
import { DeviceApi, DeviceVO } from '@/api/iot/device/device'
|
import { DeviceApi, DeviceVO,SimulatorDataVO } from '@/api/iot/device/device'
|
||||||
import DeviceDetailsLog from './DeviceDetailsLog.vue'
|
import DeviceDetailsLog from './DeviceDetailsLog.vue'
|
||||||
import {
|
import {
|
||||||
DataSpecsDataType,
|
DataSpecsDataType,
|
||||||
@ -210,18 +210,22 @@ const queryParams = reactive({
|
|||||||
})
|
})
|
||||||
const dataTypeOptionsLabel = computed(() => (value: string) => getDataTypeOptionsLabel(value)) // 解析数据类型
|
const dataTypeOptionsLabel = computed(() => (value: string) => getDataTypeOptionsLabel(value)) // 解析数据类型
|
||||||
const props = defineProps<{ product: ProductVO; device: DeviceVO }>()
|
const props = defineProps<{ product: ProductVO; device: DeviceVO }>()
|
||||||
const list = ref<ThingModelData[]>([]) // 物模型列表的数据
|
const list = ref<SimulatorData[]>([]) // 物模型列表的数据
|
||||||
|
|
||||||
|
interface SimulatorData extends ThingModelData {
|
||||||
|
simulateValue?: string | number // 用于存储模拟值
|
||||||
|
}
|
||||||
/** 查询列表 */
|
/** 查询列表 */
|
||||||
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)
|
||||||
list.value = data
|
// 转换数据,添加 simulateValue 字段
|
||||||
console.log(data)
|
list.value = data.map(item => ({
|
||||||
console.log(list.value)
|
...item,
|
||||||
console.log(queryParams)
|
simulateValue: ''
|
||||||
|
}))
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@ -231,8 +235,6 @@ const getList = async () => {
|
|||||||
interface TableItem {
|
interface TableItem {
|
||||||
name: string
|
name: string
|
||||||
identifier: string
|
identifier: string
|
||||||
dataType: string
|
|
||||||
specs: string
|
|
||||||
value: string | number
|
value: string | number
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,8 +245,6 @@ const propertyList = computed(() => {
|
|||||||
.map((item) => ({
|
.map((item) => ({
|
||||||
name: item.name,
|
name: item.name,
|
||||||
identifier: item.identifier,
|
identifier: item.identifier,
|
||||||
dataType: item.dataType,
|
|
||||||
specs: item.specs,
|
|
||||||
value: ''
|
value: ''
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
@ -255,8 +255,6 @@ const eventList = computed(() => {
|
|||||||
.map((item) => ({
|
.map((item) => ({
|
||||||
name: item.name,
|
name: item.name,
|
||||||
identifier: item.identifier,
|
identifier: item.identifier,
|
||||||
dataType: item.dataType,
|
|
||||||
specs: item.specs,
|
|
||||||
value: ''
|
value: ''
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
@ -293,22 +291,94 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
interface ReportData {
|
||||||
|
productKey: string
|
||||||
|
deviceKey: string
|
||||||
|
type: string
|
||||||
|
subType: string
|
||||||
|
reportTime: string
|
||||||
|
content: string // 改为 string 类型,存储 JSON 字符串
|
||||||
|
}
|
||||||
|
|
||||||
// 处理属性上报
|
// 处理属性上报
|
||||||
const handlePropertyReport = async () => {
|
const handlePropertyReport = async () => {
|
||||||
// TODO: 实现属性上报逻辑
|
const contentObj: Record<string, any> = {}
|
||||||
message.success('属性上报成功')
|
list.value.forEach((item) => {
|
||||||
|
// 只有当 simulateValue 有值时才添加到 content 中
|
||||||
|
if (item.simulateValue !== undefined && item.simulateValue !== '') {
|
||||||
|
contentObj[item.identifier] = item.simulateValue
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const reportData: SimulatorDataVO = {
|
||||||
|
productKey: props.product.productKey,
|
||||||
|
deviceKey: props.device.deviceKey,
|
||||||
|
type: 'property',
|
||||||
|
subType: 'report',
|
||||||
|
reportTime: new Date().toISOString(),
|
||||||
|
content: JSON.stringify(contentObj) // 转换为 JSON 字符串
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// TODO: 调用API发送数据
|
||||||
|
console.log('上报数据:', reportData)
|
||||||
|
console.log('reportData.content', reportData.content)
|
||||||
|
const data = await DeviceApi.simulatorDevice(reportData)
|
||||||
|
console.log(data)
|
||||||
|
message.success('属性上报成功123')
|
||||||
|
} catch (error) {
|
||||||
|
message.error('属性上报失败')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理事件上报
|
// 处理事件上报
|
||||||
const handleEventReport = async () => {
|
const handleEventReport = async () => {
|
||||||
// TODO: 实现事件上报逻辑
|
const contentObj: Record<string, any> = {}
|
||||||
message.success('事件上报成功')
|
list.value
|
||||||
|
.filter(item => item.type === 'event')
|
||||||
|
.forEach((item) => {
|
||||||
|
if (item.simulateValue !== undefined && item.simulateValue !== '') {
|
||||||
|
contentObj[item.identifier] = item.simulateValue
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const reportData: ReportData = {
|
||||||
|
productKey: props.product.productKey,
|
||||||
|
deviceKey: props.device.deviceKey,
|
||||||
|
type: 'event',
|
||||||
|
subType: list.value.find(item => item.type === 'event')?.identifier || '',
|
||||||
|
reportTime: new Date().toISOString(),
|
||||||
|
content: JSON.stringify(contentObj) // 转换为 JSON 字符串
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// TODO: 调用API发送数据
|
||||||
|
console.log('上报数据:', reportData)
|
||||||
|
message.success('事件上报成功')
|
||||||
|
} catch (error) {
|
||||||
|
message.error('事件上报失败')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理设备状态变更
|
// 处理设备状态变更
|
||||||
const handleDeviceState = async (state: 'online' | 'offline') => {
|
const handleDeviceState = async (state: 'online' | 'offline') => {
|
||||||
// TODO: 实现设备状态变更逻辑
|
const reportData: ReportData = {
|
||||||
message.success(`设备${state === 'online' ? '上线' : '下线'}成功`)
|
productKey: props.product.productKey,
|
||||||
|
deviceKey: props.device.deviceKey,
|
||||||
|
type: 'status',
|
||||||
|
subType: state,
|
||||||
|
reportTime: new Date().toISOString(),
|
||||||
|
content: JSON.stringify({ status: state }) // 转换为 JSON 字符串
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// TODO: 调用API发送数据
|
||||||
|
console.log('状态变更数据:', reportData)
|
||||||
|
console.log('reportData.content111111111', reportData.content)
|
||||||
|
message.success(`设备${state === 'online' ? '上线' : '下线'}成功`)
|
||||||
|
} catch (error) {
|
||||||
|
message.error(`设备${state === 'online' ? '上线' : '下线'}失败`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理属性获取
|
// 处理属性获取
|
||||||
|
Loading…
x
Reference in New Issue
Block a user