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
61ebe5b9
authored
Jan 03, 2025
by
alwayssuper
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:DeviceDetailsLog DeviceDetailsSimulator
parent
77e0a763
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
368 additions
and
1 deletions
+368
-1
pnpm-lock.yaml
+0
-0
src/views/iot/device/device/detail/DeviceDetailsLog.vue
+168
-0
src/views/iot/device/device/detail/DeviceDetailsSimulator.vue
+192
-0
src/views/iot/device/device/detail/index.vue
+8
-1
No files found.
pnpm-lock.yaml
View file @
61ebe5b9
This source diff could not be displayed because it is too large. You can
view the blob
instead.
src/views/iot/device/device/detail/DeviceDetailsLog.vue
0 → 100644
View file @
61ebe5b9
<
template
>
<ContentWrap>
<!-- 搜索区域 -->
<el-form
:model=
"queryParams"
inline
>
<el-form-item>
<el-select
v-model=
"queryParams.type"
placeholder=
"所有"
class=
"!w-120px"
>
<el-option
label=
"所有"
value=
""
/>
<el-option
label=
"状态"
value=
"state"
/>
<el-option
label=
"事件"
value=
"event"
/>
<el-option
label=
"属性"
value=
"property"
/>
<el-option
label=
"服务"
value=
"service"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-input
v-model=
"queryParams.keyword"
placeholder=
"日志识符"
class=
"!w-200px"
/>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
@
click=
"handleQuery"
>
<Icon
icon=
"ep:search"
class=
"mr-5px"
/>
搜索
</el-button>
<el-switch
v-model=
"autoRefresh"
class=
"ml-10px"
/>
定时刷新
</el-form-item>
</el-form>
<!-- 日志列表 -->
<el-table
v-loading=
"loading"
:data=
"logList"
:stripe=
"true"
class=
"whitespace-nowrap"
>
<el-table-column
label=
"时间"
align=
"center"
prop=
"time"
width=
"180"
>
<template
#
default=
"scope"
>
{{
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=
"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"
:total=
"total"
:page-sizes=
"[10, 20, 50, 100]"
small
background
layout=
"total, sizes, prev, pager, next, jumper"
@
size-change=
"handleQuery"
@
current-change=
"handleQuery"
/>
</div>
</ContentWrap>
</template>
<
script
setup
lang=
"ts"
>
import
{
DeviceApi
}
from
'@/api/iot/device/device'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
{
formatDate
}
from
'@/utils/formatTime'
const
props
=
defineProps
<
{
deviceId
:
number
}
>
()
// 查询参数
const
queryParams
=
reactive
({
type
:
''
,
keyword
:
''
,
pageNo
:
1
,
pageSize
:
20
})
// 列表数据
const
loading
=
ref
(
false
)
const
total
=
ref
(
0
)
const
logList
=
ref
([])
const
autoRefresh
=
ref
(
false
)
let
timer
:
any
=
null
// 类型映射
const
typeMap
=
{
lifetime
:
'生命周期'
,
state
:
'设备状态'
,
property
:
'属性'
,
event
:
'事件'
,
service
:
'服务'
}
/** 查询日志列表 */
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
}
}
/** 获取日志名称 */
const
getLogName
=
(
log
:
any
)
=>
{
const
{
type
,
identifier
}
=
log
let
name
=
'未知'
if
(
type
===
'property'
)
{
if
(
identifier
===
'set_reply'
)
name
=
'设置回复'
else
if
(
identifier
===
'report'
)
name
=
'上报'
else
if
(
identifier
===
'set'
)
name
=
'设置'
}
else
if
(
type
===
'state'
)
{
name
=
identifier
===
'online'
?
'上线'
:
'下线'
}
else
if
(
type
===
'lifetime'
)
{
name
=
identifier
===
'register'
?
'注册'
:
name
}
return
`
${
name
}
(
${
identifier
}
)`
}
/** 搜索操作 */
const
handleQuery
=
()
=>
{
queryParams
.
pageNo
=
1
getLogList
()
}
/** 监听自动刷新 */
watch
(
autoRefresh
,
(
newValue
)
=>
{
if
(
newValue
)
{
timer
=
setInterval
(()
=>
{
getLogList
()
},
5000
)
}
else
{
clearInterval
(
timer
)
timer
=
null
}
})
/** 监听设备ID变化 */
watch
(()
=>
props
.
deviceId
,
(
newValue
)
=>
{
if
(
newValue
)
{
handleQuery
()
}
})
/** 组件卸载时清除定时器 */
onBeforeUnmount
(()
=>
{
if
(
timer
)
{
clearInterval
(
timer
)
}
})
/** 初始化 */
onMounted
(()
=>
{
if
(
props
.
deviceId
)
{
getLogList
()
}
})
</
script
>
src/views/iot/device/device/detail/DeviceDetailsSimulator.vue
0 → 100644
View file @
61ebe5b9
<
template
>
<ContentWrap>
<el-row
:gutter=
"20"
>
<!-- 左侧指令调试区域 -->
<el-col
:span=
"12"
>
<el-tabs
v-model=
"activeTab"
type=
"border-card"
>
<!-- 上行指令调试 -->
<el-tab-pane
label=
"上行指令调试"
name=
"up"
>
<el-tabs
v-model=
"subTab"
v-if=
"activeTab === 'up'"
>
<!-- 属性上报 -->
<el-tab-pane
label=
"属性上报"
name=
"property"
>
<ContentWrap>
<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=
"identifier"
/>
<el-table-column
label=
"数据类型"
align=
"center"
prop=
"dataType"
/>
<el-table-column
label=
"数据定义"
align=
"center"
prop=
"specs"
:show-overflow-tooltip=
"true"
/>
</el-table>
<div
class=
"mt-10px"
>
<el-button
type=
"primary"
@
click=
"handlePropertyReport"
>
发送
</el-button>
</div>
</ContentWrap>
</el-tab-pane>
<!-- 事件上报 -->
<el-tab-pane
label=
"事件上报"
name=
"event"
>
<ContentWrap>
<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=
"identifier"
/>
<el-table-column
label=
"数据类型"
align=
"center"
prop=
"dataType"
/>
<el-table-column
label=
"数据定义"
align=
"center"
prop=
"specs"
:show-overflow-tooltip=
"true"
/>
</el-table>
<div
class=
"mt-10px"
>
<el-button
type=
"primary"
@
click=
"handleEventReport"
>
发送
</el-button>
</div>
</ContentWrap>
</el-tab-pane>
<!-- 状态变更 -->
<el-tab-pane
label=
"状态变更"
name=
"status"
>
<ContentWrap>
<div
class=
"flex gap-4"
>
<el-button
type=
"primary"
@
click=
"handleDeviceState('online')"
>
设备上线
</el-button>
<el-button
type=
"primary"
@
click=
"handleDeviceState('offline')"
>
设备下线
</el-button>
</div>
</ContentWrap>
</el-tab-pane>
</el-tabs>
</el-tab-pane>
<!-- 下行指令调试 -->
<el-tab-pane
label=
"下行指令调试"
name=
"down"
>
<el-tabs
v-model=
"subTab"
v-if=
"activeTab === 'down'"
>
<!-- 属性调试 -->
<el-tab-pane
label=
"属性调试"
name=
"propertyDebug"
>
<ContentWrap>
<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=
"identifier"
/>
<el-table-column
label=
"数据类型"
align=
"center"
prop=
"dataType"
/>
<el-table-column
label=
"数据定义"
align=
"center"
prop=
"specs"
:show-overflow-tooltip=
"true"
/>
</el-table>
<div
class=
"mt-10px"
>
<el-button
type=
"primary"
@
click=
"handlePropertyGet"
>
获取
</el-button>
</div>
</ContentWrap>
</el-tab-pane>
<!-- 服务调用 -->
<el-tab-pane
label=
"服务调用"
name=
"service"
>
<ContentWrap>
<!-- 服务调用相关内容 -->
</ContentWrap>
</el-tab-pane>
</el-tabs>
</el-tab-pane>
</el-tabs>
</el-col>
<!-- 右侧设备日志区域 -->
<el-col
:span=
"12"
>
<el-tabs
type=
"border-card"
>
<el-tab-pane
label=
"设备日志"
>
<DeviceDetailsLog
:device-id=
"device.id"
/>
</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
</ContentWrap>
</template>
<
script
setup
lang=
"ts"
>
import
{
ProductVO
}
from
'@/api/iot/product/product'
import
{
DeviceApi
,
DeviceVO
}
from
'@/api/iot/device/device'
import
DeviceDetailsLog
from
'./DeviceDetailsLog.vue'
const
message
=
useMessage
()
// 消息弹窗
const
loading
=
ref
(
false
)
const
activeTab
=
ref
(
'up'
)
const
subTab
=
ref
(
'property'
)
const
props
=
defineProps
<
{
product
:
ProductVO
;
device
:
DeviceVO
}
>
()
// 功能列表数据结构定义
interface
TableItem
{
name
:
string
identifier
:
string
dataType
:
string
specs
:
string
value
:
string
|
number
}
// 属性列表数据
const
propertyList
=
ref
<
TableItem
[]
>
([
{
name
:
'电量'
,
identifier
:
'power'
,
dataType
:
'int32'
,
specs
:
''
,
value
:
''
},
{
name
:
'设备型号'
,
identifier
:
'DeviceType'
,
dataType
:
'text'
,
specs
:
'{ "length": "128" }'
,
value
:
''
},
{
name
:
'信号强度'
,
identifier
:
'rssi'
,
dataType
:
'int32'
,
specs
:
'{ "min": "-127", "max": "127" }'
,
value
:
''
},
{
name
:
'门状态'
,
identifier
:
'doorStatus'
,
dataType
:
'enum'
,
specs
:
'{ "0": "关", "1": "开" }'
,
value
:
''
}
])
// 事件列表数据
const
eventList
=
ref
<
TableItem
[]
>
([])
// 处理属性上报
const
handlePropertyReport
=
async
()
=>
{
// TODO: 实现属性上报逻辑
message
.
success
(
'属性上报成功'
)
}
// 处理事件上报
const
handleEventReport
=
async
()
=>
{
// TODO: 实现事件上报逻辑
message
.
success
(
'事件上报成功'
)
}
// 处理设备状态变更
const
handleDeviceState
=
async
(
state
:
'online'
|
'offline'
)
=>
{
// TODO: 实现设备状态变更逻辑
message
.
success
(
`设备
${
state
===
'online'
?
'上线'
:
'下线'
}
成功`
)
}
// 处理属性获取
const
handlePropertyGet
=
async
()
=>
{
// TODO: 实现属性获取逻辑
message
.
success
(
'属性获取成功'
)
}
// 初始化
onMounted
(()
=>
{
// TODO: 获取初始数据
})
</
script
>
src/views/iot/device/device/detail/index.vue
View file @
61ebe5b9
...
...
@@ -16,6 +16,12 @@
</el-tab-pane>
<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"
/>
</el-tab-pane>
<el-tab-pane
label=
"模拟设备"
name=
"simulator"
>
<DeviceDetailsSimulator
v-if=
"activeTab === 'simulator'"
:product=
"product"
:device=
"device"
/>
</el-tab-pane>
</el-tabs>
</el-col>
</
template
>
...
...
@@ -26,7 +32,8 @@ import { DeviceTypeEnum, ProductApi, ProductVO } from '@/api/iot/product/product
import
DeviceDetailsHeader
from
'./DeviceDetailsHeader.vue'
import
DeviceDetailsInfo
from
'./DeviceDetailsInfo.vue'
import
DeviceDetailsModel
from
'./DeviceDetailsModel.vue'
import
DeviceDetailsLog
from
'./DeviceDetailsLog.vue'
import
DeviceDetailsSimulator
from
'./DeviceDetailsSimulator.vue'
defineOptions
({
name
:
'IoTDeviceDetail'
})
const
route
=
useRoute
()
...
...
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