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
6d641177
authored
Oct 01, 2024
by
YunaiV
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【代码评审】IoT:产品、设备、物模型的代码
parent
4b2800f7
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
114 additions
and
149 deletions
+114
-149
src/api/iot/device/index.ts
+14
-14
src/api/iot/product/index.ts
+18
-17
src/api/iot/thinkmodelfunction/index.ts
+13
-13
src/views/iot/device/DeviceForm.vue
+3
-4
src/views/iot/device/detail/DeviceDetailsHeader.vue
+1
-0
src/views/iot/device/detail/DeviceDetailsInfo.vue
+29
-42
src/views/iot/device/index.vue
+4
-3
src/views/iot/product/ProductForm.vue
+7
-21
src/views/iot/product/detail/ProductDetailsHeader.vue
+8
-9
src/views/iot/product/detail/ProductDetailsInfo.vue
+3
-3
src/views/iot/product/detail/ProductTopic.vue
+1
-0
src/views/iot/product/detail/ThinkModelFunction.vue
+2
-1
src/views/iot/product/detail/ThinkModelFunctionForm.vue
+4
-3
src/views/iot/product/detail/index.vue
+6
-1
src/views/iot/product/index.vue
+1
-18
No files found.
src/api/iot/device/index.ts
View file @
6d641177
import
request
from
'@/config/axios'
// 设备 VO
//
IoT
设备 VO
export
interface
DeviceVO
{
id
:
number
// 设备 ID,主键,自增
deviceKey
:
string
// 设备唯一标识符
,全局唯一,用于识别设备
deviceName
:
string
// 设备名称
,在产品内唯一,用于标识设备
productId
:
number
// 产品
ID,关联 iot_product 表的 id
productKey
:
string
// 产品
Key,关联 iot_product 表的 product_key
deviceType
:
number
// 设备类型
:0 - 直连设备,1 - 网关子设备,2 - 网关设备
nickname
:
string
// 设备备注名称
,供用户自定义备注
gatewayId
:
number
// 网关设备 ID
,子设备需要关联的网关设备 ID
status
:
number
// 设备状态
:0 - 未激活,1 - 在线,2 - 离线,3 - 已禁用
deviceKey
:
string
// 设备唯一标识符
deviceName
:
string
// 设备名称
productId
:
number
// 产品
编号
productKey
:
string
// 产品
标识
deviceType
:
number
// 设备类型
nickname
:
string
// 设备备注名称
gatewayId
:
number
// 网关设备 ID
status
:
number
// 设备状态
statusLastUpdateTime
:
Date
// 设备状态最后更新时间
lastOnlineTime
:
Date
// 最后上线时间
lastOfflineTime
:
Date
// 最后离线时间
...
...
@@ -22,17 +22,17 @@ export interface DeviceVO {
mqttClientId
:
string
// MQTT 客户端 ID
mqttUsername
:
string
// MQTT 用户名
mqttPassword
:
string
// MQTT 密码
authType
:
string
// 认证类型
(如一机一密、动态注册)
latitude
:
number
// 设备位置的纬度
,范围 -90.000000 ~ 90.000000
longitude
:
number
// 设备位置的经度
,范围 -180.000000 ~ 180.000000
areaId
:
number
// 地区编码
,符合国家地区编码标准,关联地区表
authType
:
string
// 认证类型
latitude
:
number
// 设备位置的纬度
longitude
:
number
// 设备位置的经度
areaId
:
number
// 地区编码
address
:
string
// 设备详细地址
serialNumber
:
string
// 设备序列号
}
export
interface
DeviceUpdateStatusVO
{
id
:
number
// 设备 ID,主键,自增
status
:
number
// 设备状态
:0 - 未激活,1 - 在线,2 - 离线,3 - 已禁用
status
:
number
// 设备状态
}
// 设备 API
...
...
src/api/iot/product/index.ts
View file @
6d641177
import
request
from
'@/config/axios'
//
iot
产品 VO
//
IoT
产品 VO
export
interface
ProductVO
{
id
:
number
// 产品编号
name
:
string
// 产品名称
id
:
number
// 产品ID
productKey
:
string
// 产品标识
protocolId
:
number
// 协议编号
(脚本解析 id)
protocolId
:
number
// 协议编号
categoryId
:
number
// 产品所属品类标识符
description
:
string
// 产品描述
validateType
:
number
// 数据校验级别
, 0: 强校验, 1: 弱校验, 2: 免校验
status
:
number
// 产品状态
, 0: DEVELOPMENT_STATUS, 1: RELEASE_STATUS
deviceType
:
number
// 设备类型
, 0: 直连设备, 1: 网关子设备, 2: 网关设备
netType
:
number
// 联网方式
, 0: Wi-Fi, 1: Cellular, 2: Ethernet, 3: 其他
protocolType
:
number
// 接入网关协议
, 0: modbus, 1: opc-ua, 2: customize, 3: ble, 4: zigbee
dataFormat
:
number
// 数据格式
, 0: 透传模式, 1: Alink JSON
validateType
:
number
// 数据校验级别
status
:
number
// 产品状态
deviceType
:
number
// 设备类型
netType
:
number
// 联网方式
protocolType
:
number
// 接入网关协议
dataFormat
:
number
// 数据格式
deviceCount
:
number
// 设备数量
createTime
:
Date
// 创建时间
}
//
iot
产品 API
//
IoT
产品 API
export
const
ProductApi
=
{
// 查询
iot
产品分页
// 查询产品分页
getProductPage
:
async
(
params
:
any
)
=>
{
return
await
request
.
get
({
url
:
`/iot/product/page`
,
params
})
},
// 查询
iot
产品详情
// 查询产品详情
getProduct
:
async
(
id
:
number
)
=>
{
return
await
request
.
get
({
url
:
`/iot/product/get?id=`
+
id
})
},
// 新增
iot
产品
// 新增产品
createProduct
:
async
(
data
:
ProductVO
)
=>
{
return
await
request
.
post
({
url
:
`/iot/product/create`
,
data
})
},
// 修改
iot
产品
// 修改产品
updateProduct
:
async
(
data
:
ProductVO
)
=>
{
return
await
request
.
put
({
url
:
`/iot/product/update`
,
data
})
},
// 删除
iot
产品
// 删除产品
deleteProduct
:
async
(
id
:
number
)
=>
{
return
await
request
.
delete
({
url
:
`/iot/product/delete?id=`
+
id
})
},
// 导出
iot
产品 Excel
// 导出产品 Excel
exportProduct
:
async
(
params
)
=>
{
return
await
request
.
download
({
url
:
`/iot/product/export-excel`
,
params
})
},
...
...
@@ -54,7 +55,7 @@ export const ProductApi = {
return
await
request
.
put
({
url
:
`/iot/product/update-status?id=`
+
id
+
`&status=`
+
status
})
},
// 查询产品(精简
)
列表
// 查询产品(精简
)
列表
getSimpleProductList
()
{
return
request
.
get
({
url
:
'/iot/product/list-all-simple'
})
}
...
...
src/api/iot/thinkmodelfunction/index.ts
View file @
6d641177
...
...
@@ -6,21 +6,21 @@ export interface ThinkModelFunctionVO {
identifier
:
string
// 功能标识
name
:
string
// 功能名称
description
:
string
// 功能描述
productId
:
number
// 产品
ID(关联 IotProductDO 的 id)
productKey
:
string
// 产品
Key(关联 IotProductDO 的 productKey)
type
:
number
// 功能类型
(1 - 属性,2 - 服务,3 - 事件)
property
:
string
// 属性
(存储 ThingModelProperty 的 JSON 数据)
event
:
string
// 事件
(存储 ThingModelEvent 的 JSON 数据)
service
:
string
// 服务
(存储服务的 JSON 数据)
productId
:
number
// 产品
编号
productKey
:
string
// 产品
标识
type
:
number
// 功能类型
property
:
string
// 属性
event
:
string
// 事件
service
:
string
// 服务
}
// IoT 产品物模型 API
export
const
ThinkModelFunctionApi
=
{
// 查询
IoT
产品物模型分页
// 查询产品物模型分页
getThinkModelFunctionPage
:
async
(
params
:
any
)
=>
{
return
await
request
.
get
({
url
:
`/iot/think-model-function/page`
,
params
})
},
// 获得
IoT
产品物模型
// 获得产品物模型
getThinkModelFunctionListByProductId
:
async
(
params
:
any
)
=>
{
return
await
request
.
get
({
url
:
`/iot/think-model-function/list-by-product-id`
,
...
...
@@ -28,27 +28,27 @@ export const ThinkModelFunctionApi = {
})
},
// 查询
IoT
产品物模型详情
// 查询产品物模型详情
getThinkModelFunction
:
async
(
id
:
number
)
=>
{
return
await
request
.
get
({
url
:
`/iot/think-model-function/get?id=`
+
id
})
},
// 新增
IoT
产品物模型
// 新增产品物模型
createThinkModelFunction
:
async
(
data
:
ThinkModelFunctionVO
)
=>
{
return
await
request
.
post
({
url
:
`/iot/think-model-function/create`
,
data
})
},
// 修改
IoT
产品物模型
// 修改产品物模型
updateThinkModelFunction
:
async
(
data
:
ThinkModelFunctionVO
)
=>
{
return
await
request
.
put
({
url
:
`/iot/think-model-function/update`
,
data
})
},
// 删除
IoT
产品物模型
// 删除产品物模型
deleteThinkModelFunction
:
async
(
id
:
number
)
=>
{
return
await
request
.
delete
({
url
:
`/iot/think-model-function/delete?id=`
+
id
})
},
// 导出
IoT
产品物模型 Excel
// 导出产品物模型 Excel
exportThinkModelFunction
:
async
(
params
)
=>
{
return
await
request
.
download
({
url
:
`/iot/think-model-function/export-excel`
,
params
})
}
...
...
src/views/iot/device/DeviceForm.vue
View file @
6d641177
...
...
@@ -57,8 +57,7 @@ const formData = ref({
id
:
undefined
,
productId
:
undefined
,
deviceName
:
undefined
,
nickname
:
undefined
,
serialNumber
:
undefined
nickname
:
undefined
})
const
formRules
=
reactive
({
productId
:
[{
required
:
true
,
message
:
'产品不能为空'
,
trigger
:
'blur'
}],
...
...
@@ -66,7 +65,7 @@ const formRules = reactive({
{
pattern
:
/^
[
a-zA-Z0-9_.
\-
:@
]{4,32}
$/
,
message
:
'支持英文字母、数字、下划线(_)、中划线(-)、点号(.)、半角冒号(:)和特殊字符@,长度限制为
4~32
个字符'
,
'支持英文字母、数字、下划线(_)、中划线(-)、点号(.)、半角冒号(:)和特殊字符@,长度限制为
4~32
个字符'
,
trigger
:
'blur'
}
],
...
...
@@ -79,7 +78,7 @@ const formRules = reactive({
}
const
length
=
value
.
replace
(
/
[\u
4e00-
\u
9fa5
\u
3040-
\u
30ff
]
/g
,
'aa'
).
length
if
(
length
<
4
||
length
>
64
)
{
callback
(
new
Error
(
'备注名称长度限制为
4~64个字符,中文及日文算2
个字符'
))
callback
(
new
Error
(
'备注名称长度限制为
4~64 个字符,中文及日文算 2
个字符'
))
}
else
if
(
!
/^
[\u
4e00-
\u
9fa5
\u
3040-
\u
30ff_a-zA-Z0-9
]
+$/
.
test
(
value
))
{
callback
(
new
Error
(
'备注名称只能包含中文、英文字母、日文、数字和下划线(_)'
))
}
else
{
...
...
src/views/iot/device/detail/DeviceDetailsHeader.vue
View file @
6d641177
...
...
@@ -59,6 +59,7 @@ const emit = defineEmits(['refresh'])
* @param text 需要复制的文本
*/
const
copyToClipboard
=
(
text
:
string
)
=>
{
// TODO @haohao:可以考虑用 await 异步转同步哈
navigator
.
clipboard
.
writeText
(
text
).
then
(()
=>
{
message
.
success
(
'复制成功'
)
})
...
...
src/views/iot/device/detail/DeviceDetailsInfo.vue
View file @
6d641177
...
...
@@ -3,33 +3,33 @@
<el-collapse
v-model=
"activeNames"
>
<el-descriptions
:column=
"3"
title=
"设备信息"
>
<el-descriptions-item
label=
"产品名称"
>
{{
product
.
name
}}
</el-descriptions-item>
<el-descriptions-item
label=
"ProductKey"
>
{{
product
.
productKey
}}
<el-descriptions-item
label=
"ProductKey"
>
{{
product
.
productKey
}}
<el-button
@
click=
"copyToClipboard(product.productKey)"
>
复制
</el-button>
</el-descriptions-item>
<el-descriptions-item
label=
"设备类型"
>
<dict-tag
:type=
"DICT_TYPE.IOT_PRODUCT_DEVICE_TYPE"
:value=
"product.deviceType"
/>
</el-descriptions-item>
<el-descriptions-item
label=
"DeviceName"
>
{{
device
.
deviceName
}}
<el-descriptions-item
label=
"DeviceName"
>
{{
device
.
deviceName
}}
<el-button
@
click=
"copyToClipboard(device.deviceName)"
>
复制
</el-button>
</el-descriptions-item>
<el-descriptions-item
label=
"备注名称"
>
{{
device
.
nickname
}}
</el-descriptions-item>
<el-descriptions-item
label=
"创建时间"
>
{{
formatDate
(
device
.
createTime
)
}}
</el-descriptions-item>
<el-descriptions-item
label=
"激活时间"
>
{{
formatDate
(
device
.
activeTime
)
}}
</el-descriptions-item>
<el-descriptions-item
label=
"最后上线时间"
>
{{
formatDate
(
device
.
lastOnlineTime
)
}}
</el-descriptions-item>
<el-descriptions-item
label=
"创建时间"
>
{{
formatDate
(
device
.
createTime
)
}}
</el-descriptions-item>
<el-descriptions-item
label=
"激活时间"
>
{{
formatDate
(
device
.
activeTime
)
}}
</el-descriptions-item>
<el-descriptions-item
label=
"最后上线时间"
>
{{
formatDate
(
device
.
lastOnlineTime
)
}}
</el-descriptions-item>
<el-descriptions-item
label=
"当前状态"
>
<dict-tag
:type=
"DICT_TYPE.IOT_DEVICE_STATUS"
:value=
"device.status"
/>
</el-descriptions-item>
<el-descriptions-item
label=
"最后离线时间"
:span=
"3"
>
{{
formatDate
(
device
.
lastOfflineTime
)
}}
</el-descriptions-item>
<el-descriptions-item
label=
"最后离线时间"
:span=
"3"
>
{{
formatDate
(
device
.
lastOfflineTime
)
}}
</el-descriptions-item>
<el-descriptions-item
label=
"MQTT 连接参数"
>
<el-button
type=
"primary"
@
click=
"openMqttParams"
>
查看
</el-button>
</el-descriptions-item>
...
...
@@ -53,7 +53,6 @@
</
template
>
</el-input>
</el-form-item>
<el-form-item
label=
"username"
>
<el-input
v-model=
"mqttParams.mqttUsername"
readonly
>
<
template
#
append
>
...
...
@@ -63,7 +62,6 @@
</
template
>
</el-input>
</el-form-item>
<el-form-item
label=
"passwd"
>
<el-input
v-model=
"mqttParams.mqttPassword"
readonly
type=
"password"
>
<
template
#
append
>
...
...
@@ -87,39 +85,28 @@ import { ProductVO } from '@/api/iot/product'
import
{
formatDate
}
from
'@/utils/formatTime'
import
{
DeviceVO
}
from
'@/api/iot/device'
// 消息提示
const
message
=
useMessage
()
// 路由实例
const
router
=
useRouter
()
const
message
=
useMessage
()
// 消息提示
// 定义 Props
const
{
product
,
device
}
=
defineProps
<
{
product
:
ProductVO
;
device
:
DeviceVO
}
>
()
const
{
product
,
device
}
=
defineProps
<
{
product
:
ProductVO
;
device
:
DeviceVO
}
>
()
// 定义 Props
// 定义 Emits
const
emit
=
defineEmits
([
'refresh'
])
const
emit
=
defineEmits
([
'refresh'
])
// 定义 Emits
// 展示的折叠面板
const
activeNames
=
ref
([
'basicInfo'
])
const
activeNames
=
ref
([
'basicInfo'
])
// 展示的折叠面板
const
mqttDialogVisible
=
ref
(
false
)
// 定义 MQTT 弹框的可见性
const
mqttParams
=
ref
({
mqttClientId
:
''
,
mqttUsername
:
''
,
mqttPassword
:
''
})
// 定义 MQTT 参数对象
/
/ 复制到剪贴板方法
/
** 复制到剪贴板方法 */
const
copyToClipboard
=
(
text
:
string
)
=>
{
navigator
.
clipboard
.
writeText
(
text
).
then
(()
=>
{
message
.
success
(
'复制成功'
)
})
}
// 定义 MQTT 弹框的可见性
const
mqttDialogVisible
=
ref
(
false
)
// 定义 MQTT 参数对象
const
mqttParams
=
ref
({
mqttClientId
:
''
,
mqttUsername
:
''
,
mqttPassword
:
''
})
// 打开 MQTT 参数弹框的方法
/** 打开 MQTT 参数弹框的方法 */
const
openMqttParams
=
()
=>
{
mqttParams
.
value
=
{
mqttClientId
:
device
.
mqttClientId
||
'N/A'
,
...
...
@@ -129,7 +116,7 @@ const openMqttParams = () => {
mqttDialogVisible
.
value
=
true
}
/
/ 关闭 MQTT 弹框的方法
/
** 关闭 MQTT 弹框的方法 */
const
handleCloseMqttDialog
=
()
=>
{
mqttDialogVisible
.
value
=
false
}
...
...
src/views/iot/device/index.vue
View file @
6d641177
...
...
@@ -192,9 +192,8 @@ const queryParams = reactive({
status
:
undefined
})
const
queryFormRef
=
ref
()
// 搜索的表单
const
exportLoading
=
ref
(
false
)
// 导出的加载中
/** 产品
ID到
名称的映射 */
/** 产品
标号和
名称的映射 */
const
productMap
=
reactive
({})
/** 查询列表 */
...
...
@@ -207,6 +206,7 @@ const getList = async () => {
// 获取产品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
...
...
@@ -235,7 +235,7 @@ const openForm = (type: string, id?: number) => {
}
/** 打开详情 */
const
{
currentRoute
,
push
}
=
useRouter
()
const
{
push
}
=
useRouter
()
const
openDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'IoTDeviceDetail'
,
params
:
{
id
}
})
}
...
...
@@ -252,6 +252,7 @@ const handleDelete = async (id: number) => {
await
getList
()
}
catch
{}
}
/** 查询字典下拉列表 */
const
products
=
ref
()
const
getProducts
=
async
()
=>
{
...
...
src/views/iot/product/ProductForm.vue
View file @
6d641177
...
...
@@ -128,15 +128,10 @@ const formData = ref({
})
const
formRules
=
reactive
({
name
:
[{
required
:
true
,
message
:
'产品名称不能为空'
,
trigger
:
'blur'
}],
deviceType
:
[
{
required
:
true
,
message
:
'设备类型不能为空'
,
trigger
:
'change'
}
],
deviceType
:
[{
required
:
true
,
message
:
'设备类型不能为空'
,
trigger
:
'change'
}],
netType
:
[
{
// TODO @haohao:0、1、/2 最好前端也枚举下;另外,这里的 required 可以直接设置为 true。然后表单那些 v-if。只要不存在,它自动就不校验了哈
required
:
formData
.
deviceType
===
0
||
formData
.
deviceType
===
2
,
message
:
'联网方式不能为空'
,
trigger
:
'change'
...
...
@@ -145,23 +140,12 @@ const formRules = reactive({
protocolType
:
[
{
required
:
formData
.
deviceType
===
1
,
message
:
'接入网关协议不能为空'
,
trigger
:
'change'
}
],
dataFormat
:
[
{
required
:
true
,
message
:
'数据格式不能为空'
,
trigger
:
'change'
}
],
validateType
:
[
{
required
:
true
,
message
:
'数据校验级别不能为空'
,
trigger
:
'change'
}
]
dataFormat
:
[{
required
:
true
,
message
:
'数据格式不能为空'
,
trigger
:
'change'
}],
validateType
:
[{
required
:
true
,
message
:
'数据校验级别不能为空'
,
trigger
:
'change'
}]
})
const
formRef
=
ref
()
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
dialogVisible
.
value
=
true
dialogTitle
.
value
=
t
(
'action.'
+
type
)
...
...
@@ -178,6 +162,7 @@ const open = async (type: string, id?: number) => {
}
defineExpose
({
open
,
close
:
()
=>
(
dialogVisible
.
value
=
false
)
})
/** 提交表单 */
const
emit
=
defineEmits
([
'success'
])
const
submitForm
=
async
()
=>
{
await
formRef
.
value
.
validate
()
...
...
@@ -198,6 +183,7 @@ const submitForm = async () => {
}
}
/** 重置表单 */
const
resetForm
=
()
=>
{
formData
.
value
=
{
name
:
undefined
,
...
...
src/views/iot/product/detail/ProductDetailsHeader.vue
View file @
6d641177
...
...
@@ -58,19 +58,24 @@ import ProductForm from '@/views/iot/product/ProductForm.vue'
import
{
ProductApi
,
ProductVO
}
from
'@/api/iot/product'
const
message
=
useMessage
()
const
{
product
}
=
defineProps
<
{
product
:
ProductVO
}
>
()
// 定义 Props
/** 处理复制 */
const
copyToClipboard
=
(
text
:
string
)
=>
{
navigator
.
clipboard
.
writeText
(
text
).
then
(()
=>
{
message
.
success
(
'复制成功'
)
})
}
/
/ 路由跳转到设备管理
const
{
currentRoute
,
push
}
=
useRouter
()
/
** 路由跳转到设备管理 */
const
{
push
}
=
useRouter
()
const
goToManagement
=
(
productId
:
string
)
=>
{
push
({
name
:
'IoTDevice'
,
query
:
{
productId
}
})
}
// 操作修改
/** 操作修改 */
const
emit
=
defineEmits
([
'refresh'
])
// 定义 Emits
const
formRef
=
ref
()
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
formRef
.
value
.
open
(
type
,
id
)
...
...
@@ -95,10 +100,4 @@ const confirmUnpublish = async (id: number) => {
message
.
error
(
'撤销发布失败'
)
}
}
// 定义 Props
const
{
product
}
=
defineProps
<
{
product
:
ProductVO
}
>
()
// 定义 Emits
const
emit
=
defineEmits
([
'refresh'
])
</
script
>
src/views/iot/product/detail/ProductDetailsInfo.vue
View file @
6d641177
...
...
@@ -6,9 +6,9 @@
<el-descriptions-item
label=
"设备类型"
>
<dict-tag
:type=
"DICT_TYPE.IOT_PRODUCT_DEVICE_TYPE"
:value=
"product.deviceType"
/>
</el-descriptions-item>
<el-descriptions-item
label=
"创建时间"
>
{{
formatDate
(
product
.
createTime
)
}}
</el-descriptions-item>
<el-descriptions-item
label=
"创建时间"
>
{{
formatDate
(
product
.
createTime
)
}}
</el-descriptions-item>
<el-descriptions-item
label=
"数据格式"
>
<dict-tag
:type=
"DICT_TYPE.IOT_DATA_FORMAT"
:value=
"product.dataFormat"
/>
</el-descriptions-item>
...
...
src/views/iot/product/detail/ProductTopic.vue
View file @
6d641177
...
...
@@ -44,6 +44,7 @@ const columns2 = reactive([
{
label
:
'描述'
,
field
:
'description'
}
])
// TODO @haohao:这个,有没可能写到一个枚举里,方便后续维护? /Users/yunai/Java/yudao-ui-admin-vue3/src/views/ai/utils/constants.ts
const
data1
=
computed
(()
=>
{
if
(
!
props
.
product
||
!
props
.
product
.
productKey
)
return
[]
return
[
...
...
src/views/iot/product/detail/ThinkModelFunction.vue
View file @
6d641177
...
...
@@ -88,6 +88,7 @@ import ThinkModelFunctionForm from '@/views/iot/product/detail/ThinkModelFunctio
const
props
=
defineProps
<
{
product
:
ProductVO
}
>
()
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
loading
=
ref
(
true
)
// 列表的加载中
...
...
@@ -97,7 +98,7 @@ const queryParams = reactive({
pageNo
:
1
,
pageSize
:
10
,
type
:
undefined
,
productId
:
undefined
productId
:
-
1
})
const
queryFormRef
=
ref
()
// 搜索的表单
...
...
src/views/iot/product/detail/ThinkModelFunctionForm.vue
View file @
6d641177
...
...
@@ -46,7 +46,6 @@
<span
class=
"mx-2"
>
~
</span>
<el-input
v-model=
"formData.property.dataType.specs.max"
placeholder=
"请输入最大值"
/>
</el-form-item>
<el-form-item
label=
"步长"
prop=
"step"
>
<el-input
v-model=
"formData.property.dataType.specs.step"
placeholder=
"请输入步长"
/>
</el-form-item>
...
...
@@ -77,7 +76,6 @@
<
script
setup
lang=
"ts"
>
import
{
ProductVO
}
from
'@/api/iot/product'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
ThinkModelFunctionApi
,
ThinkModelFunctionVO
}
from
'@/api/iot/thinkmodelfunction'
const
props
=
defineProps
<
{
product
:
ProductVO
}
>
()
...
...
@@ -159,6 +157,7 @@ const formRules = reactive({
})
const
formRef
=
ref
()
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
dialogVisible
.
value
=
true
dialogTitle
.
value
=
t
(
'action.'
+
type
)
...
...
@@ -175,6 +174,7 @@ const open = async (type: string, id?: number) => {
}
defineExpose
({
open
,
close
:
()
=>
(
dialogVisible
.
value
=
false
)
})
/** 提交表单 */
const
emit
=
defineEmits
([
'success'
])
const
submitForm
=
async
()
=>
{
await
formRef
.
value
.
validate
()
...
...
@@ -197,6 +197,7 @@ const submitForm = async () => {
}
}
/** 重置表单 */
const
resetForm
=
()
=>
{
formData
.
value
=
{
id
:
undefined
,
...
...
@@ -205,7 +206,7 @@ const resetForm = () => {
identifier
:
undefined
,
name
:
undefined
,
description
:
undefined
,
type
:
'1'
,
type
:
'1'
,
// todo @HAOHAO:看看枚举下
property
:
{
identifier
:
undefined
,
name
:
undefined
,
...
...
src/views/iot/product/detail/index.vue
View file @
6d641177
...
...
@@ -23,9 +23,14 @@ import ProductDetailsHeader from '@/views/iot/product/detail/ProductDetailsHeade
import
ProductDetailsInfo
from
'@/views/iot/product/detail/ProductDetailsInfo.vue'
import
ProductTopic
from
'@/views/iot/product/detail/ProductTopic.vue'
import
ThinkModelFunction
from
'@/views/iot/product/detail/ThinkModelFunction.vue'
import
{
useTagsViewStore
}
from
'@/store/modules/tagsView'
import
{
useRouter
}
from
'vue-router'
defineOptions
({
name
:
'IoTProductDetail'
})
const
{
delView
}
=
useTagsViewStore
()
// 视图操作
const
{
currentRoute
}
=
useRouter
()
const
route
=
useRoute
()
const
message
=
useMessage
()
const
id
=
Number
(
route
.
params
.
id
)
// 编号
...
...
@@ -45,7 +50,7 @@ const getProductData = async (id: number) => {
}
// 查询设备数量
const
getDeviceCount
=
async
(
productId
:
string
)
=>
{
const
getDeviceCount
=
async
(
productId
:
number
)
=>
{
try
{
const
count
=
await
DeviceApi
.
getDeviceCount
(
productId
)
console
.
log
(
'Device count response:'
,
count
)
...
...
src/views/iot/product/index.vue
View file @
6d641177
...
...
@@ -104,7 +104,6 @@
<
script
setup
lang=
"ts"
>
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
download
from
'@/utils/download'
import
{
ProductApi
,
ProductVO
}
from
'@/api/iot/product'
import
ProductForm
from
'./ProductForm.vue'
import
{
DICT_TYPE
}
from
'@/utils/dict'
...
...
@@ -135,7 +134,6 @@ const queryParams = reactive({
dataFormat
:
undefined
})
const
queryFormRef
=
ref
()
// 搜索的表单
const
exportLoading
=
ref
(
false
)
// 导出的加载中
/** 查询列表 */
const
getList
=
async
()
=>
{
...
...
@@ -168,7 +166,7 @@ const openForm = (type: string, id?: number) => {
}
/** 打开详情 */
const
{
currentRoute
,
push
}
=
useRouter
()
const
{
push
}
=
useRouter
()
const
openDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'IoTProductDetail'
,
params
:
{
id
}
})
}
...
...
@@ -186,21 +184,6 @@ const handleDelete = async (id: number) => {
}
catch
{}
}
/** 导出按钮操作 */
const
handleExport
=
async
()
=>
{
try
{
// 导出的二次确认
await
message
.
exportConfirm
()
// 发起导出
exportLoading
.
value
=
true
const
data
=
await
ProductApi
.
exportProduct
(
queryParams
)
download
.
excel
(
data
,
'iot 产品.xls'
)
}
catch
{
}
finally
{
exportLoading
.
value
=
false
}
}
/** 初始化 **/
onMounted
(()
=>
{
getList
()
...
...
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