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
14fe6c55
authored
Dec 14, 2024
by
YunaiV
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【功能新增】IoT:设备管理界面增加设备分组选择功能
parent
30b19c91
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
69 additions
and
25 deletions
+69
-25
src/api/iot/device/group/index.ts
+6
-0
src/api/iot/device/index.ts
+1
-0
src/views/iot/device/device/DeviceForm.vue
+23
-2
src/views/iot/device/device/index.vue
+38
-23
src/views/iot/device/group/index.vue
+1
-0
No files found.
src/api/iot/device/group/index.ts
View file @
14fe6c55
...
@@ -6,6 +6,7 @@ export interface DeviceGroupVO {
...
@@ -6,6 +6,7 @@ export interface DeviceGroupVO {
name
:
string
// 分组名字
name
:
string
// 分组名字
status
:
number
// 分组状态
status
:
number
// 分组状态
description
:
string
// 分组描述
description
:
string
// 分组描述
deviceCount
?:
number
// 设备数量
}
}
// IoT 设备分组 API
// IoT 设备分组 API
...
@@ -33,5 +34,10 @@ export const DeviceGroupApi = {
...
@@ -33,5 +34,10 @@ export const DeviceGroupApi = {
// 删除IoT 设备分组
// 删除IoT 设备分组
deleteDeviceGroup
:
async
(
id
:
number
)
=>
{
deleteDeviceGroup
:
async
(
id
:
number
)
=>
{
return
await
request
.
delete
({
url
:
`/iot/device-group/delete?id=`
+
id
})
return
await
request
.
delete
({
url
:
`/iot/device-group/delete?id=`
+
id
})
},
// 获取设备分组的精简信息列表
getSimpleDeviceGroupList
:
async
()
=>
{
return
await
request
.
get
({
url
:
`/iot/device-group/simple-list`
})
}
}
}
}
src/api/iot/device/index.ts
View file @
14fe6c55
...
@@ -28,6 +28,7 @@ export interface DeviceVO {
...
@@ -28,6 +28,7 @@ export interface DeviceVO {
areaId
:
number
// 地区编码
areaId
:
number
// 地区编码
address
:
string
// 设备详细地址
address
:
string
// 设备详细地址
serialNumber
:
string
// 设备序列号
serialNumber
:
string
// 设备序列号
groupIds
?:
number
[]
// 添加分组 ID
}
}
export
interface
DeviceUpdateStatusVO
{
export
interface
DeviceUpdateStatusVO
{
...
...
src/views/iot/device/device/DeviceForm.vue
View file @
14fe6c55
...
@@ -62,6 +62,16 @@
...
@@ -62,6 +62,16 @@
<el-form-item
label=
"设备图片"
prop=
"picUrl"
>
<el-form-item
label=
"设备图片"
prop=
"picUrl"
>
<UploadImg
v-model=
"formData.picUrl"
:height=
"'120px'"
:width=
"'120px'"
/>
<UploadImg
v-model=
"formData.picUrl"
:height=
"'120px'"
:width=
"'120px'"
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"设备分组"
prop=
"groupIds"
>
<el-select
v-model=
"formData.groupIds"
placeholder=
"请选择设备分组"
multiple
clearable
>
<el-option
v-for=
"group in deviceGroups"
:key=
"group.id"
:label=
"group.name"
:value=
"group.id"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"设备序列号"
prop=
"serialNumber"
>
<el-form-item
label=
"设备序列号"
prop=
"serialNumber"
>
<el-input
v-model=
"formData.serialNumber"
placeholder=
"请输入设备序列号"
/>
<el-input
v-model=
"formData.serialNumber"
placeholder=
"请输入设备序列号"
/>
</el-form-item>
</el-form-item>
...
@@ -76,6 +86,7 @@
...
@@ -76,6 +86,7 @@
</template>
</template>
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
DeviceApi
,
DeviceVO
}
from
'@/api/iot/device'
import
{
DeviceApi
,
DeviceVO
}
from
'@/api/iot/device'
import
{
DeviceGroupApi
}
from
'@/api/iot/device/group'
import
{
DeviceTypeEnum
,
ProductApi
,
ProductVO
}
from
'@/api/iot/product/product'
import
{
DeviceTypeEnum
,
ProductApi
,
ProductVO
}
from
'@/api/iot/product/product'
import
{
UploadImg
}
from
'@/components/UploadFile'
import
{
UploadImg
}
from
'@/components/UploadFile'
import
{
generateRandomStr
}
from
'@/utils'
import
{
generateRandomStr
}
from
'@/utils'
...
@@ -99,7 +110,8 @@ const formData = ref({
...
@@ -99,7 +110,8 @@ const formData = ref({
picUrl
:
undefined
,
picUrl
:
undefined
,
gatewayId
:
undefined
,
gatewayId
:
undefined
,
deviceType
:
undefined
as
number
|
undefined
,
deviceType
:
undefined
as
number
|
undefined
,
serialNumber
:
undefined
serialNumber
:
undefined
,
groupIds
:
[]
as
number
[]
})
})
const
formRules
=
reactive
({
const
formRules
=
reactive
({
productId
:
[{
required
:
true
,
message
:
'产品不能为空'
,
trigger
:
'blur'
}],
productId
:
[{
required
:
true
,
message
:
'产品不能为空'
,
trigger
:
'blur'
}],
...
@@ -150,6 +162,7 @@ const formRules = reactive({
...
@@ -150,6 +162,7 @@ const formRules = reactive({
const
formRef
=
ref
()
// 表单 Ref
const
formRef
=
ref
()
// 表单 Ref
const
products
=
ref
<
ProductVO
[]
>
([])
// 产品列表
const
products
=
ref
<
ProductVO
[]
>
([])
// 产品列表
const
gatewayDevices
=
ref
<
DeviceVO
[]
>
([])
// 网关设备列表
const
gatewayDevices
=
ref
<
DeviceVO
[]
>
([])
// 网关设备列表
const
deviceGroups
=
ref
<
any
[]
>
([])
/** 打开弹窗 */
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
...
@@ -178,6 +191,13 @@ const open = async (type: string, id?: number) => {
...
@@ -178,6 +191,13 @@ const open = async (type: string, id?: number) => {
}
}
// 加载产品列表
// 加载产品列表
products
.
value
=
await
ProductApi
.
getSimpleProductList
()
products
.
value
=
await
ProductApi
.
getSimpleProductList
()
// 加载设备分组列表
try
{
deviceGroups
.
value
=
await
DeviceGroupApi
.
getSimpleDeviceGroupList
()
}
catch
(
error
)
{
console
.
error
(
'加载设备分组列表失败:'
,
error
)
}
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
...
@@ -216,7 +236,8 @@ const resetForm = () => {
...
@@ -216,7 +236,8 @@ const resetForm = () => {
picUrl
:
undefined
,
picUrl
:
undefined
,
gatewayId
:
undefined
,
gatewayId
:
undefined
,
deviceType
:
undefined
,
deviceType
:
undefined
,
serialNumber
:
undefined
serialNumber
:
undefined
,
groupIds
:
[]
}
}
formRef
.
value
?.
resetFields
()
formRef
.
value
?.
resetFields
()
}
}
...
...
src/views/iot/device/device/index.vue
View file @
14fe6c55
...
@@ -71,6 +71,21 @@
...
@@ -71,6 +71,21 @@
/>
/>
</el-select>
</el-select>
</el-form-item>
</el-form-item>
<el-form-item
label=
"设备分组"
prop=
"groupId"
>
<el-select
v-model=
"queryParams.groupId"
placeholder=
"请选择设备分组"
clearable
class=
"!w-240px"
>
<el-option
v-for=
"group in deviceGroups"
:key=
"group.id"
:label=
"group.name"
:value=
"group.id"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-form-item>
<el-button
@
click=
"handleQuery"
>
<el-button
@
click=
"handleQuery"
>
<Icon
icon=
"ep:search"
class=
"mr-5px"
/>
<Icon
icon=
"ep:search"
class=
"mr-5px"
/>
...
@@ -104,7 +119,7 @@
...
@@ -104,7 +119,7 @@
<el-table-column
label=
"备注名称"
align=
"center"
prop=
"nickname"
/>
<el-table-column
label=
"备注名称"
align=
"center"
prop=
"nickname"
/>
<el-table-column
label=
"设备所属产品"
align=
"center"
prop=
"productId"
>
<el-table-column
label=
"设备所属产品"
align=
"center"
prop=
"productId"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
{{
product
Map
[
scope
.
row
.
productId
]
}}
{{
product
s
.
find
((
p
)
=>
p
.
id
===
scope
.
row
.
productId
)?.
name
||
'-'
}}
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"设备类型"
align=
"center"
prop=
"deviceType"
>
<el-table-column
label=
"设备类型"
align=
"center"
prop=
"deviceType"
>
...
@@ -124,6 +139,15 @@
...
@@ -124,6 +139,15 @@
:formatter=
"dateFormatter"
:formatter=
"dateFormatter"
width=
"180px"
width=
"180px"
/>
/>
<el-table-column
label=
"所属分组"
align=
"center"
prop=
"groupId"
>
<
template
#
default=
"scope"
>
<template
v-if=
"scope.row.groupIds?.length"
>
<el-tag
v-for=
"id in scope.row.groupIds"
:key=
"id"
class=
"ml-5px"
size=
"small"
>
{{
deviceGroups
.
find
((
g
)
=>
g
.
id
===
id
)?.
name
}}
</el-tag>
</
template
>
</template>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"120px"
>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"120px"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
<el-button
<el-button
...
@@ -171,7 +195,8 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
...
@@ -171,7 +195,8 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
{
DeviceApi
,
DeviceVO
}
from
'@/api/iot/device'
import
{
DeviceApi
,
DeviceVO
}
from
'@/api/iot/device'
import
DeviceForm
from
'./DeviceForm.vue'
import
DeviceForm
from
'./DeviceForm.vue'
import
{
ProductApi
}
from
'@/api/iot/product/product'
import
{
ProductApi
,
ProductVO
}
from
'@/api/iot/product/product'
import
{
DeviceGroupApi
,
DeviceGroupVO
}
from
'@/api/iot/device/group'
/** IoT 设备 列表 */
/** IoT 设备 列表 */
defineOptions
({
name
:
'IoTDevice'
})
defineOptions
({
name
:
'IoTDevice'
})
...
@@ -189,12 +214,12 @@ const queryParams = reactive({
...
@@ -189,12 +214,12 @@ const queryParams = reactive({
productId
:
undefined
,
productId
:
undefined
,
deviceType
:
undefined
,
deviceType
:
undefined
,
nickname
:
undefined
,
nickname
:
undefined
,
status
:
undefined
status
:
undefined
,
groupId
:
undefined
})
})
const
queryFormRef
=
ref
()
// 搜索的表单
const
queryFormRef
=
ref
()
// 搜索的表单
const
products
=
ref
<
ProductVO
[]
>
([])
// 产品列表
/** 产品标号和名称的映射 */
const
deviceGroups
=
ref
<
DeviceGroupVO
[]
>
([])
// 设备分组列表
const
productMap
=
reactive
({})
/** 查询列表 */
/** 查询列表 */
const
getList
=
async
()
=>
{
const
getList
=
async
()
=>
{
...
@@ -203,14 +228,6 @@ const getList = async () => {
...
@@ -203,14 +228,6 @@ const getList = async () => {
const
data
=
await
DeviceApi
.
getDevicePage
(
queryParams
)
const
data
=
await
DeviceApi
.
getDevicePage
(
queryParams
)
list
.
value
=
data
.
list
list
.
value
=
data
.
list
total
.
value
=
data
.
total
total
.
value
=
data
.
total
// 获取产品ID列表
const
productIds
=
[...
new
Set
(
data
.
list
.
map
((
device
)
=>
device
.
productId
))]
// 获取产品名称
// TODO @haohao:最好后端拼接哈
const
products
=
await
Promise
.
all
(
productIds
.
map
((
id
)
=>
ProductApi
.
getProduct
(
id
)))
products
.
forEach
((
product
)
=>
{
productMap
[
product
.
id
]
=
product
.
name
})
}
finally
{
}
finally
{
loading
.
value
=
false
loading
.
value
=
false
}
}
...
@@ -245,7 +262,7 @@ const handleDelete = async (id: number) => {
...
@@ -245,7 +262,7 @@ const handleDelete = async (id: number) => {
try
{
try
{
// 删除的二次确认
// 删除的二次确认
await
message
.
delConfirm
()
await
message
.
delConfirm
()
//
发
起删除
// 起删除
await
DeviceApi
.
deleteDevice
(
id
)
await
DeviceApi
.
deleteDevice
(
id
)
message
.
success
(
t
(
'common.delSuccess'
))
message
.
success
(
t
(
'common.delSuccess'
))
// 刷新列表
// 刷新列表
...
@@ -253,15 +270,13 @@ const handleDelete = async (id: number) => {
...
@@ -253,15 +270,13 @@ const handleDelete = async (id: number) => {
}
catch
{}
}
catch
{}
}
}
/** 查询字典下拉列表 */
const
products
=
ref
()
const
getProducts
=
async
()
=>
{
products
.
value
=
await
ProductApi
.
getSimpleProductList
()
}
/** 初始化 **/
/** 初始化 **/
onMounted
(()
=>
{
onMounted
(
async
()
=>
{
getList
()
getList
()
getProducts
()
// 获取产品列表
products
.
value
=
await
ProductApi
.
getSimpleProductList
()
// 获取分组列表
deviceGroups
.
value
=
await
DeviceGroupApi
.
getSimpleDeviceGroupList
()
})
})
</
script
>
</
script
>
src/views/iot/device/group/index.vue
View file @
14fe6c55
...
@@ -61,6 +61,7 @@
...
@@ -61,6 +61,7 @@
:formatter=
"dateFormatter"
:formatter=
"dateFormatter"
width=
"180px"
width=
"180px"
/>
/>
<el-table-column
label=
"设备数量"
align=
"center"
prop=
"deviceCount"
/>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"120px"
>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"120px"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
<el-button
<el-button
...
...
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