Skip to content

Commit eb5d350

Browse files
YunaiVgitee-org
authored andcommitted
!626 【代码完善】IOT: ThingModel StructDataSpecs 组件
Merge pull request !626 from puhui999/feature/iot
2 parents b6d3a85 + 4569491 commit eb5d350

File tree

15 files changed

+423
-246
lines changed

15 files changed

+423
-246
lines changed

src/api/iot/thinkmodel/index.ts renamed to src/api/iot/thingmodel/index.ts

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import request from '@/config/axios'
33
/**
44
* IoT 产品物模型
55
*/
6-
export interface ThinkModelData {
6+
export interface ThingModelData {
77
id?: number // 物模型功能编号
88
identifier?: string // 功能标识
99
name?: string // 功能名称
@@ -12,29 +12,29 @@ export interface ThinkModelData {
1212
productKey?: string // 产品标识
1313
dataType: string // 数据类型,与 dataSpecs 的 dataType 保持一致
1414
type: ProductFunctionTypeEnum // 功能类型
15-
property: ThinkModelProperty // 属性
16-
event?: ThinkModelEvent // 事件
17-
service?: ThinkModelService // 服务
15+
property: ThingModelProperty // 属性
16+
event?: ThingModelEvent // 事件
17+
service?: ThingModelService // 服务
1818
}
1919

2020
/**
21-
* ThinkModelProperty 类型
21+
* ThingModelProperty 类型
2222
*/
23-
export interface ThinkModelProperty {
23+
export interface ThingModelProperty {
2424
[key: string]: any
2525
}
2626

2727
/**
28-
* ThinkModelEvent 类型
28+
* ThingModelEvent 类型
2929
*/
30-
export interface ThinkModelEvent {
30+
export interface ThingModelEvent {
3131
[key: string]: any
3232
}
3333

3434
/**
35-
* ThinkModelService 类型
35+
* ThingModelService 类型
3636
*/
37-
export interface ThinkModelService {
37+
export interface ThingModelService {
3838
[key: string]: any
3939
}
4040

@@ -52,38 +52,37 @@ export enum ProductFunctionAccessModeEnum {
5252
}
5353

5454
// IoT 产品物模型 API
55-
export const ThinkModelApi = {
55+
export const ThingModelApi = {
5656
// 查询产品物模型分页
57-
// TODO @puhui999:product 前缀,是不是去掉哈。
58-
getThinkModelPage: async (params: any) => {
59-
return await request.get({ url: `/iot/product-think-model/page`, params })
57+
getThingModelPage: async (params: any) => {
58+
return await request.get({ url: `/iot/product-thing-model/page`, params })
6059
},
6160

6261
// 获得产品物模型
63-
getThinkModelListByProductId: async (params: any) => {
62+
getThingModelListByProductId: async (params: any) => {
6463
return await request.get({
65-
url: `/iot/product-think-model/list-by-product-id`,
64+
url: `/iot/product-thing-model/list-by-product-id`,
6665
params
6766
})
6867
},
6968

7069
// 查询产品物模型详情
71-
getThinkModel: async (id: number) => {
72-
return await request.get({ url: `/iot/product-think-model/get?id=` + id })
70+
getThingModel: async (id: number) => {
71+
return await request.get({ url: `/iot/product-thing-model/get?id=` + id })
7372
},
7473

7574
// 新增产品物模型
76-
createThinkModel: async (data: ThinkModelData) => {
77-
return await request.post({ url: `/iot/product-think-model/create`, data })
75+
createThingModel: async (data: ThingModelData) => {
76+
return await request.post({ url: `/iot/product-thing-model/create`, data })
7877
},
7978

8079
// 修改产品物模型
81-
updateThinkModel: async (data: ThinkModelData) => {
82-
return await request.put({ url: `/iot/product-think-model/update`, data })
80+
updateThingModel: async (data: ThingModelData) => {
81+
return await request.put({ url: `/iot/product-thing-model/update`, data })
8382
},
8483

8584
// 删除产品物模型
86-
deleteThinkModel: async (id: number) => {
87-
return await request.delete({ url: `/iot/product-think-model/delete?id=` + id })
85+
deleteThingModel: async (id: number) => {
86+
return await request.delete({ url: `/iot/product-thing-model/delete?id=` + id })
8887
}
8988
}

src/utils/dict.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ export enum DICT_TYPE {
236236
IOT_DATA_FORMAT = 'iot_data_format', // IOT 数据格式
237237
IOT_PROTOCOL_TYPE = 'iot_protocol_type', // IOT 接入网关协议
238238
IOT_DEVICE_STATUS = 'iot_device_status', // IOT 设备状态
239-
IOT_PRODUCT_THINK_MODEL_TYPE = 'iot_product_think_model_type', // IOT 产品功能类型
239+
IOT_PRODUCT_THING_MODEL_TYPE = 'iot_product_thing_model_type', // IOT 产品功能类型
240240
IOT_DATA_TYPE = 'iot_data_type', // IOT 数据类型
241241
IOT_UNIT_TYPE = 'iot_unit_type', // IOT 单位类型
242242
IOT_RW_TYPE = 'iot_rw_type', // IOT 读写类型

src/views/iot/product/product/detail/index.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
<el-tab-pane label="Topic 类列表" name="topic">
99
<ProductTopic v-if="activeTab === 'topic'" :product="product" />
1010
</el-tab-pane>
11-
<el-tab-pane label="功能定义" lazy name="thinkModel">
12-
<IoTProductThinkModel ref="thinkModelRef" />
11+
<el-tab-pane label="功能定义" lazy name="thingModel">
12+
<IoTProductThingModel ref="thingModelRef" />
1313
</el-tab-pane>
1414
<el-tab-pane label="消息解析" name="message" />
1515
<el-tab-pane label="服务端订阅" name="subscription" />
@@ -22,7 +22,7 @@ import { DeviceApi } from '@/api/iot/device/device'
2222
import ProductDetailsHeader from './ProductDetailsHeader.vue'
2323
import ProductDetailsInfo from './ProductDetailsInfo.vue'
2424
import ProductTopic from './ProductTopic.vue'
25-
import IoTProductThinkModel from '@/views/iot/thinkmodel/index.vue'
25+
import IoTProductThingModel from '@/views/iot/thingmodel/index.vue'
2626
import { useTagsViewStore } from '@/store/modules/tagsView'
2727
import { useRouter } from 'vue-router'
2828
import { IOT_PROVIDE_KEY } from '@/views/iot/utils/constants'

src/views/iot/product/product/index.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@
9797
</div>
9898
<div class="mb-2.5 last:mb-0">
9999
<span class="text-[#717c8e] mr-2.5">产品标识</span>
100-
<span class="text-[#0b1d30] whitespace-normal break-all">{{ item.productKey }}</span>
100+
<span class="text-[#0b1d30] whitespace-normal break-all">
101+
{{ item.productKey }}
102+
</span>
101103
</div>
102104
</div>
103105
<div class="w-[100px] h-[100px]">
@@ -309,7 +311,7 @@ const openObjectModel = (item: ProductVO) => {
309311
push({
310312
name: 'IoTProductDetail',
311313
params: { id: item.id },
312-
query: { tab: 'thinkModel' }
314+
query: { tab: 'thingModel' }
313315
})
314316
}
315317

src/views/iot/thinkmodel/ThinkModelDataSpecs.vue renamed to src/views/iot/thingmodel/ThingModelDataSpecs.vue

Lines changed: 29 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@
55
prop="property.dataType"
66
>
77
<el-select v-model="property.dataType" placeholder="请选择数据类型" @change="handleChange">
8+
<!-- ARRAY 和 STRUCT 类型数据相互嵌套时,最多支持递归嵌套2层(父和子) -->
89
<el-option
9-
v-for="option in dataTypeOptions"
10+
v-for="option in getDataTypeOptions"
1011
:key="option.value"
1112
:label="option.label"
1213
:value="option.value"
1314
/>
1415
</el-select>
1516
</el-form-item>
1617
<!-- 数值型配置 -->
17-
<ThinkModelNumberTypeDataSpecs
18+
<ThingModelNumberDataSpecs
1819
v-if="
1920
[DataSpecsDataType.INT, DataSpecsDataType.DOUBLE, DataSpecsDataType.FLOAT].includes(
2021
property.dataType || ''
@@ -23,17 +24,12 @@
2324
v-model="property.dataSpecs"
2425
/>
2526
<!-- 枚举型配置 -->
26-
<ThinkModelEnumTypeDataSpecs
27+
<ThingModelEnumDataSpecs
2728
v-if="property.dataType === DataSpecsDataType.ENUM"
2829
v-model="property.dataSpecsList"
2930
/>
3031
<!-- 布尔型配置 -->
31-
<el-form-item
32-
v-if="property.dataType === DataSpecsDataType.BOOL"
33-
:rules="[{ required: true, message: '请输入布尔值名称', trigger: 'blur' }]"
34-
label="布尔值"
35-
prop="property.dataSpecsList"
36-
>
32+
<el-form-item v-if="property.dataType === DataSpecsDataType.BOOL" label="布尔值">
3733
<template v-for="(item, index) in property.dataSpecsList" :key="item.value">
3834
<div class="flex items-center justify-start w-1/1 mb-5px">
3935
<span>{{ item.value }}</span>
@@ -58,10 +54,6 @@
5854
<!-- 文本型配置 -->
5955
<el-form-item
6056
v-if="property.dataType === DataSpecsDataType.TEXT"
61-
:rules="[
62-
{ required: true, message: '请输入文本字节长度', trigger: 'blur' },
63-
{ validator: validateTextLength, trigger: 'blur' }
64-
]"
6557
label="数据长度"
6658
prop="property.dataSpecs.length"
6759
>
@@ -74,16 +66,16 @@
7466
<el-input class="w-255px!" disabled placeholder="String类型的UTC时间戳(毫秒)" />
7567
</el-form-item>
7668
<!-- 数组型配置-->
77-
<ThinkModelArrayTypeDataSpecs
69+
<ThingModelArrayDataSpecs
7870
v-if="property.dataType === DataSpecsDataType.ARRAY"
7971
v-model="property.dataSpecs"
8072
/>
81-
<!-- TODO puhui999: Struct 属性待完善 -->
82-
<el-form-item
83-
:rules="[{ required: true, message: '请选择读写类型', trigger: 'change' }]"
84-
label="读写类型"
85-
prop="property.accessMode"
86-
>
73+
<!-- Struct 型配置-->
74+
<ThingModelStructDataSpecs
75+
v-if="property.dataType === DataSpecsDataType.STRUCT"
76+
v-model="property.dataSpecsList"
77+
/>
78+
<el-form-item v-if="!isStructDataSpecs" label="读写类型" prop="property.accessMode">
8779
<el-radio-group v-model="property.accessMode">
8880
<el-radio label="rw">读写</el-radio>
8981
<el-radio label="r">只读</el-radio>
@@ -102,22 +94,29 @@
10294

10395
<script lang="ts" setup>
10496
import { useVModel } from '@vueuse/core'
105-
import { DataSpecsDataType, dataTypeOptions } from './config'
97+
import { DataSpecsDataType, dataTypeOptions, validateBoolName } from './config'
10698
import {
107-
ThinkModelArrayTypeDataSpecs,
108-
ThinkModelEnumTypeDataSpecs,
109-
ThinkModelNumberTypeDataSpecs
99+
ThingModelArrayDataSpecs,
100+
ThingModelEnumDataSpecs,
101+
ThingModelNumberDataSpecs,
102+
ThingModelStructDataSpecs
110103
} from './dataSpecs'
111-
import { ThinkModelProperty } from '@/api/iot/thinkmodel'
112-
import { isEmpty } from '@/utils/is'
104+
import { ThingModelProperty } from '@/api/iot/thingmodel'
113105
114106
/** IoT 物模型数据 */
115-
defineOptions({ name: 'ThinkModelDataSpecs' })
107+
defineOptions({ name: 'ThingModelDataSpecs' })
116108
117-
const props = defineProps<{ modelValue: any }>()
109+
const props = defineProps<{ modelValue: any; isStructDataSpecs?: boolean }>()
118110
const emits = defineEmits(['update:modelValue'])
119-
const property = useVModel(props, 'modelValue', emits) as Ref<ThinkModelProperty>
120-
111+
const property = useVModel(props, 'modelValue', emits) as Ref<ThingModelProperty>
112+
const getDataTypeOptions = computed(() => {
113+
return !props.isStructDataSpecs
114+
? dataTypeOptions
115+
: dataTypeOptions.filter(
116+
(item) =>
117+
!([DataSpecsDataType.STRUCT, DataSpecsDataType.ARRAY] as any[]).includes(item.value)
118+
)
119+
}) // 获得数据类型列表
121120
/** 属性值的数据类型切换时初始化相关数据 */
122121
const handleChange = (dataType: any) => {
123122
property.value.dataSpecsList = []
@@ -143,45 +142,6 @@ const handleChange = (dataType: any) => {
143142
break
144143
}
145144
}
146-
147-
// TODO @puhui999:一些校验的规则,是不是写到 utils 里。
148-
/** 校验布尔值名称 */
149-
const validateBoolName = (_: any, value: string, callback: any) => {
150-
if (isEmpty(value)) {
151-
callback(new Error('布尔值名称不能为空'))
152-
return
153-
}
154-
// 检查开头字符
155-
if (!/^[\u4e00-\u9fa5a-zA-Z0-9]/.test(value)) {
156-
callback(new Error('布尔值名称必须以中文、英文字母或数字开头'))
157-
return
158-
}
159-
// 检查整体格式
160-
if (!/^[\u4e00-\u9fa5a-zA-Z0-9][a-zA-Z0-9\u4e00-\u9fa5_-]*$/.test(value)) {
161-
callback(new Error('布尔值名称只能包含中文、英文字母、数字、下划线和短划线'))
162-
return
163-
}
164-
// 检查长度(一个中文算一个字符)
165-
if (value.length > 20) {
166-
callback(new Error('布尔值名称长度不能超过20个字符'))
167-
return
168-
}
169-
170-
callback()
171-
}
172-
173-
/** 校验文本长度 */
174-
const validateTextLength = (_: any, value: any, callback: any) => {
175-
if (isEmpty(value)) {
176-
callback(new Error('文本长度不能为空'))
177-
return
178-
}
179-
if (isNaN(Number(value))) {
180-
callback(new Error('文本长度必须是数字'))
181-
return
182-
}
183-
callback()
184-
}
185145
</script>
186146

187147
<style lang="scss" scoped>

0 commit comments

Comments
 (0)