Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
c9e00d97
authored
Jan 06, 2025
by
alwayssuper
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:deviceLog and deviceSimulator
parent
b71fa84a
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
138 additions
and
137 deletions
+138
-137
.vscode/settings.json
+1
-1
src/api/iot/device/device/index.ts
+5
-1
src/api/iot/thingmodel/index.ts
+7
-0
src/views/iot/device/device/detail/DeviceDetailsLog.vue
+36
-39
src/views/iot/device/device/detail/DeviceDetailsSimulator.vue
+88
-95
src/views/iot/device/device/detail/index.vue
+1
-1
No files found.
.vscode/settings.json
View file @
c9e00d97
...
...
@@ -87,7 +87,7 @@
"source.fixAll.stylelint"
:
"explicit"
},
"[vue]"
:
{
"editor.defaultFormatter"
:
"
esbenp.prettier-vscode
"
"editor.defaultFormatter"
:
"
octref.vetur
"
},
"i18n-ally.localesPaths"
:
[
"src/locales"
],
"i18n-ally.keystyle"
:
"nested"
,
...
...
src/api/iot/device/device/index.ts
View file @
c9e00d97
...
...
@@ -69,7 +69,7 @@ export interface SimulatorDataVO {
deviceKey
:
string
type
:
string
subType
:
string
reportTime
:
string
reportTime
:
number
// 时间戳
content
:
string
// 存储 JSON 字符串
}
...
...
@@ -151,5 +151,9 @@ export const DeviceApi = {
// 模拟设备
simulatorDevice
:
async
(
data
:
SimulatorDataVO
)
=>
{
return
await
request
.
post
({
url
:
`/iot/device/data/simulator`
,
data
})
},
//查询设备日志分页
getDeviceLogPage
:
async
(
params
:
any
)
=>
{
return
await
request
.
get
({
url
:
`/iot/device/data/log/page`
,
params
})
}
}
src/api/iot/thingmodel/index.ts
View file @
c9e00d97
...
...
@@ -18,6 +18,13 @@ export interface ThingModelData {
}
/**
* IoT 模拟设备
*/
export
interface
SimulatorData
extends
ThingModelData
{
simulateValue
?:
string
|
number
// 用于存储模拟值
}
/**
* ThingModelProperty 类型
*/
export
interface
ThingModelProperty
{
...
...
src/views/iot/device/device/detail/DeviceDetailsLog.vue
View file @
c9e00d97
...
...
@@ -29,27 +29,18 @@
{{
formatDate
(
scope
.
row
.
time
)
}}
</
template
>
</el-table-column>
<el-table-column
label=
"类型"
align=
"center"
prop=
"type"
width=
"120"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.IOT_MESSAGE_TYPE"
:value=
"scope.row.type"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"名称(标识符)"
align=
"center"
prop=
"name"
/>
<el-table-column
label=
"类型"
align=
"center"
prop=
"type"
width=
"120"
/>
<el-table-column
label=
"名称(标识符)"
align=
"center"
prop=
"subType"
width=
"120"
/>
<el-table-column
label=
"内容"
align=
"center"
prop=
"content"
:show-overflow-tooltip=
"true"
/>
</el-table>
<!-- 分页 -->
<div
class=
"mt-10px flex justify-end"
>
<el-pagination
v-model:current-page=
"queryParams.pageNo"
v-model:page-size=
"queryParams.pageSize"
<Pagination
:total=
"total"
:page-sizes=
"[10, 20, 50, 100]"
small
background
layout=
"total, sizes, prev, pager, next, jumper"
@
size-change=
"handleQuery"
@
current-change=
"handleQuery"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getLogList"
/>
</div>
</ContentWrap>
...
...
@@ -61,15 +52,17 @@ import { DICT_TYPE } from '@/utils/dict'
import
{
formatDate
}
from
'@/utils/formatTime'
const
props
=
defineProps
<
{
device
Id
:
number
device
Key
:
number
}
>
()
//TODO:后续看看使用什么查询条件 目前后端是留了时间范围 type subType
// 查询参数
const
queryParams
=
reactive
({
type
:
''
,
keyword
:
''
,
deviceKey
:
props
.
deviceKey
,
// type: '',
// keyword: '',
pageNo
:
1
,
pageSize
:
2
0
pageSize
:
1
0
})
// 列表数据
...
...
@@ -90,23 +83,24 @@ const typeMap = {
/** 查询日志列表 */
const
getLogList
=
async
()
=>
{
// if (!props.deviceId) return
// loading.value = true
// try {
// const res = await DeviceApi.getDeviceLogs(props.deviceId, queryParams)
// total.value = res.total
// logList.value = res.list.map((item: any) => {
// const log = {
// time: item.time,
// type: typeMap[item.type as keyof typeof typeMap] || item.type,
// name: getLogName(item),
// content: item.content
// }
// return log
// })
// } finally {
// loading.value = false
// }
if
(
!
props
.
deviceKey
)
return
loading
.
value
=
true
try
{
const
res
=
await
DeviceApi
.
getDeviceLogPage
(
queryParams
)
total
.
value
=
res
.
total
logList
.
value
=
res
.
list
.
map
((
item
:
any
)
=>
{
const
log
=
{
time
:
item
.
reportTime
,
type
:
item
.
type
,
subType
:
item
.
subType
,
content
:
item
.
content
}
return
log
})
console
.
log
(
logList
.
value
)
}
finally
{
loading
.
value
=
false
}
}
/** 获取日志名称 */
...
...
@@ -146,11 +140,14 @@ watch(autoRefresh, (newValue) => {
})
/** 监听设备ID变化 */
watch
(()
=>
props
.
deviceId
,
(
newValue
)
=>
{
watch
(
()
=>
props
.
deviceKey
,
(
newValue
)
=>
{
if
(
newValue
)
{
handleQuery
()
}
})
}
)
/** 组件卸载时清除定时器 */
onBeforeUnmount
(()
=>
{
...
...
@@ -161,7 +158,7 @@ onBeforeUnmount(() => {
/** 初始化 */
onMounted
(()
=>
{
if
(
props
.
device
Id
)
{
if
(
props
.
device
Key
)
{
getLogList
()
}
})
...
...
src/views/iot/device/device/detail/DeviceDetailsSimulator.vue
View file @
c9e00d97
...
...
@@ -97,7 +97,7 @@
<!--
事件上报
-->
<
el
-
tab
-
pane
label
=
"事件上报"
name
=
"event"
>
<
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"
prop
=
"name"
/>
<
el
-
table
-
column
label
=
"标识符"
align
=
"center"
prop
=
"identifier"
/>
<
el
-
table
-
column
label
=
"数据类型"
align
=
"center"
prop
=
"dataType"
/>
...
...
@@ -115,7 +115,7 @@
<
/el-table
>
<
div
class
=
"mt-10px"
>
<
el
-
button
type
=
"primary"
@
click
=
"handleEventReport"
>
发送
<
/el-button
>
<
/div
>
<
/div>
--
>
<
/ContentWrap
>
<
/el-tab-pane
>
...
...
@@ -141,7 +141,7 @@
<!--
属性调试
-->
<
el
-
tab
-
pane
label
=
"属性调试"
name
=
"propertyDebug"
>
<
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"
prop
=
"name"
/>
<
el
-
table
-
column
label
=
"标识符"
align
=
"center"
prop
=
"identifier"
/>
<
el
-
table
-
column
label
=
"数据类型"
align
=
"center"
prop
=
"dataType"
/>
...
...
@@ -159,7 +159,7 @@
<
/el-table
>
<
div
class
=
"mt-10px"
>
<
el
-
button
type
=
"primary"
@
click
=
"handlePropertyGet"
>
获取
<
/el-button
>
<
/div
>
<
/div>
--
>
<
/ContentWrap
>
<
/el-tab-pane
>
...
...
@@ -178,7 +178,7 @@
<
el
-
col
:
span
=
"12"
>
<
el
-
tabs
type
=
"border-card"
>
<
el
-
tab
-
pane
label
=
"设备日志"
>
<
DeviceDetailsLog
:
device
-
id
=
"device.id
"
/>
<
DeviceDetailsLog
:
device
Key
=
"device.deviceKey
"
/>
<
/el-tab-pane
>
<
/el-tabs
>
<
/el-col
>
...
...
@@ -188,7 +188,7 @@
<
script
setup
lang
=
"ts"
>
import
{
ProductVO
}
from
'@/api/iot/product/product'
import
{
ThingModelApi
,
ThingModelData
}
from
'@/api/iot/thingmodel'
import
{
ThingModelApi
,
ThingModelData
,
SimulatorData
}
from
'@/api/iot/thingmodel'
import
{
DeviceApi
,
DeviceVO
,
SimulatorDataVO
}
from
'@/api/iot/device/device'
import
DeviceDetailsLog
from
'./DeviceDetailsLog.vue'
import
{
...
...
@@ -212,9 +212,6 @@ const dataTypeOptionsLabel = computed(() => (value: string) => getDataTypeOption
const
props
=
defineProps
<
{
product
:
ProductVO
;
device
:
DeviceVO
}
>
()
const
list
=
ref
<
SimulatorData
[]
>
([])
// 物模型列表的数据
interface
SimulatorData
extends
ThingModelData
{
simulateValue
?:
string
|
number
// 用于存储模拟值
}
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
...
...
@@ -231,33 +228,33 @@ const getList = async () => {
}
}
// 功能列表数据结构定义
interface
TableItem
{
name
:
string
identifier
:
string
value
:
string
|
number
}
//
//
功能列表数据结构定义
//
interface TableItem
{
//
name: string
//
identifier: string
//
value: string | number
//
}
// 添加计算属性来过滤物模型数据
const
propertyList
=
computed
(()
=>
{
return
list
.
value
.
filter
((
item
)
=>
item
.
type
===
'property'
)
.
map
((
item
)
=>
({
name
:
item
.
name
,
identifier
:
item
.
identifier
,
value
:
''
}
))
}
)
//
//
添加计算属性来过滤物模型数据
//
const propertyList = computed(() =>
{
//
return list.value
//
.filter((item) => item.type === 'property')
//
.map((item) => (
{
//
name: item.name,
//
identifier: item.identifier,
//
value: ''
//
}
))
//
}
)
const
eventList
=
computed
(()
=>
{
return
list
.
value
.
filter
((
item
)
=>
item
.
type
===
'event'
)
.
map
((
item
)
=>
({
name
:
item
.
name
,
identifier
:
item
.
identifier
,
value
:
''
}
))
}
)
//
const eventList = computed(() =>
{
//
return list.value
//
.filter((item) => item.type === 'event')
//
.map((item) => (
{
//
name: item.name,
//
identifier: item.identifier,
//
value: ''
//
}
))
//
}
)
// 监听标签页变化 todo:后续改成查询字典
watch
(
...
...
@@ -291,16 +288,16 @@ watch(
{
immediate
:
true
}
)
interface
ReportData
{
productKey
:
string
deviceKey
:
string
type
:
string
subType
:
string
reportTime
:
string
content
:
string
// 改为 string 类型,存储 JSON 字符串
}
//
interface ReportData
{
//
productKey: string
//
deviceKey: string
//
type: string
//
subType: string
//
reportTime: string
//
content: string // 改为 string 类型,存储 JSON 字符串
//
}
// 处理属性上报
// 处理属性上报
TODO:数据类型效验
const
handlePropertyReport
=
async
()
=>
{
const
contentObj
:
Record
<
string
,
any
>
=
{
}
list
.
value
.
forEach
((
item
)
=>
{
...
...
@@ -315,71 +312,67 @@ const handlePropertyReport = async () => {
deviceKey
:
props
.
device
.
deviceKey
,
type
:
'property'
,
subType
:
'report'
,
reportTime
:
new
Date
().
toISOString
(),
reportTime
:
Date
.
now
(),
// 将 reportTime 变为数字类型的时间戳
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'
)
await
DeviceApi
.
simulatorDevice
(
reportData
)
message
.
success
(
'属性上报成功'
)
}
catch
(
error
)
{
message
.
error
(
'属性上报失败'
)
}
}
// 处理事件上报
const
handleEventReport
=
async
()
=>
{
const
contentObj
:
Record
<
string
,
any
>
=
{
}
list
.
value
.
filter
(
item
=>
item
.
type
===
'event'
)
.
forEach
((
item
)
=>
{
if
(
item
.
simulateValue
!==
undefined
&&
item
.
simulateValue
!==
''
)
{
contentObj
[
item
.
identifier
]
=
item
.
simulateValue
}
}
)
//
//
处理事件上报
//
const handleEventReport = async () =>
{
//
const contentObj: Record<string, any> =
{
}
//
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 字符串
}
//
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
(
'事件上报失败'
)
}
}
//
try
{
//
// TODO: 调用API发送数据
//
console.log('上报数据:', reportData)
//
message.success('事件上报成功')
//
}
catch
(
error
)
{
//
message.error('事件上报失败')
//
}
//
}
// 处理设备状态变更
const
handleDeviceState
=
async
(
state
:
'online'
|
'offline'
)
=>
{
const
reportData
:
ReportData
=
{
productKey
:
props
.
product
.
productKey
,
deviceKey
:
props
.
device
.
deviceKey
,
type
:
'status'
,
subType
:
state
,
reportTime
:
new
Date
().
toISOString
(),
content
:
JSON
.
stringify
({
status
:
state
}
)
// 转换为 JSON 字符串
}
//
//
处理设备状态变更
//
const handleDeviceState = async (state: 'online' | 'offline') =>
{
//
const reportData: ReportData =
{
//
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' ? '上线' : '下线'
}
失败`
)
}
}
//
try
{
//
// TODO: 调用API发送数据
//
console.log('状态变更数据:', reportData)
//
console.log('reportData.content111111111', reportData.content)
//
message.success(`设备$
{
state
===
'online'
?
'上线'
:
'下线'
}成功
`)
//
}
catch (error) {
//
message.error(`
设备
$
{
state
===
'online'
?
'上线'
:
'下线'
}失败
`)
//
}
//
}
// 处理属性获取
const handlePropertyGet = async () => {
...
...
src/views/iot/device/device/detail/index.vue
View file @
c9e00d97
...
...
@@ -17,7 +17,7 @@
<el-tab-pane
label=
"子设备管理"
v-if=
"product.deviceType === DeviceTypeEnum.GATEWAY"
/>
<el-tab-pane
label=
"设备影子"
/>
<el-tab-pane
label=
"设备日志"
name=
"log"
>
<DeviceDetailsLog
v-if=
"activeTab === 'log'"
:product=
"product"
:device=
"device
"
/>
<DeviceDetailsLog
v-if=
"activeTab === 'log'"
:deviceKey=
"device.deviceKey
"
/>
</el-tab-pane>
<el-tab-pane
label=
"模拟设备"
name=
"simulator"
>
<DeviceDetailsSimulator
v-if=
"activeTab === 'simulator'"
:product=
"product"
:device=
"device"
/>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment