【代码评审】IoT:物模型的管理
							parent
							
								
									fec0753d9b
								
							
						
					
					
						commit
						9581ecd7c7
					
				|  | @ -659,7 +659,7 @@ const remainingRouter: AppRouteRecordRaw[] = [ | ||||||
|           title: '设备详情', |           title: '设备详情', | ||||||
|           noCache: true, |           noCache: true, | ||||||
|           hidden: true, |           hidden: true, | ||||||
|           activeMenu: '/iot/device' |           activeMenu: '/iot/device/device' | ||||||
|         }, |         }, | ||||||
|         component: () => import('@/views/iot/device/device/detail/index.vue') |         component: () => import('@/views/iot/device/device/detail/index.vue') | ||||||
|       }, |       }, | ||||||
|  |  | ||||||
|  | @ -1,9 +1,11 @@ | ||||||
|  | <!-- 产品的物模型表单(event 项) --> | ||||||
| <template> | <template> | ||||||
|   <el-form-item |   <el-form-item | ||||||
|     :rules="[{ required: true, message: '请选择事件类型', trigger: 'change' }]" |     :rules="[{ required: true, message: '请选择事件类型', trigger: 'change' }]" | ||||||
|     label="事件类型" |     label="事件类型" | ||||||
|     prop="event.type" |     prop="event.type" | ||||||
|   > |   > | ||||||
|  |     <!-- TODO @puhui999:默认选中,INFO 信息 --> | ||||||
|     <el-radio-group v-model="thingModelEvent.type"> |     <el-radio-group v-model="thingModelEvent.type"> | ||||||
|       <el-radio :value="ThingModelEventType.INFO.value"> |       <el-radio :value="ThingModelEventType.INFO.value"> | ||||||
|         {{ ThingModelEventType.INFO.label }} |         {{ ThingModelEventType.INFO.label }} | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | <!-- 产品的物模型表单 --> | ||||||
| <template> | <template> | ||||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle"> |   <Dialog v-model="dialogVisible" :title="dialogTitle"> | ||||||
|     <el-form |     <el-form | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | <!-- 产品的物模型表单(event、service 项里的参数) --> | ||||||
| <template> | <template> | ||||||
|   <div |   <div | ||||||
|     v-for="(item, index) in thingModelParams" |     v-for="(item, index) in thingModelParams" | ||||||
|  | @ -84,6 +85,7 @@ const openParamForm = (val: any) => { | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | 
 | ||||||
| /** 删除 param 项 */ | /** 删除 param 项 */ | ||||||
| const deleteParamItem = (index: number) => { | const deleteParamItem = (index: number) => { | ||||||
|   thingModelParams.value.splice(index, 1) |   thingModelParams.value.splice(index, 1) | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | <!-- 产品的物模型表单(property 项) --> | ||||||
| <template> | <template> | ||||||
|   <el-form-item |   <el-form-item | ||||||
|     :rules="[{ required: true, message: '请选择数据类型', trigger: 'change' }]" |     :rules="[{ required: true, message: '请选择数据类型', trigger: 'change' }]" | ||||||
|  | @ -5,7 +6,7 @@ | ||||||
|     prop="property.dataType" |     prop="property.dataType" | ||||||
|   > |   > | ||||||
|     <el-select v-model="property.dataType" placeholder="请选择数据类型" @change="handleChange"> |     <el-select v-model="property.dataType" placeholder="请选择数据类型" @change="handleChange"> | ||||||
|       <!-- ARRAY 和 STRUCT 类型数据相互嵌套时,最多支持递归嵌套2层(父和子) --> |       <!-- ARRAY 和 STRUCT 类型数据相互嵌套时,最多支持递归嵌套 2 层(父和子) --> | ||||||
|       <el-option |       <el-option | ||||||
|         v-for="option in getDataTypeOptions" |         v-for="option in getDataTypeOptions" | ||||||
|         :key="option.value" |         :key="option.value" | ||||||
|  | @ -63,7 +64,7 @@ | ||||||
|   </el-form-item> |   </el-form-item> | ||||||
|   <!-- 时间型配置 --> |   <!-- 时间型配置 --> | ||||||
|   <el-form-item v-if="property.dataType === DataSpecsDataType.DATE" label="时间格式" prop="date"> |   <el-form-item v-if="property.dataType === DataSpecsDataType.DATE" label="时间格式" prop="date"> | ||||||
|     <el-input class="w-255px!" disabled placeholder="String类型的UTC时间戳(毫秒)" /> |     <el-input class="w-255px!" disabled placeholder="String 类型的 UTC 时间戳(毫秒)" /> | ||||||
|   </el-form-item> |   </el-form-item> | ||||||
|   <!-- 数组型配置--> |   <!-- 数组型配置--> | ||||||
|   <ThingModelArrayDataSpecs |   <ThingModelArrayDataSpecs | ||||||
|  | @ -75,6 +76,7 @@ | ||||||
|     v-if="property.dataType === DataSpecsDataType.STRUCT" |     v-if="property.dataType === DataSpecsDataType.STRUCT" | ||||||
|     v-model="property.dataSpecsList" |     v-model="property.dataSpecsList" | ||||||
|   /> |   /> | ||||||
|  |   <!-- TODO @puhui999:默认选中第一个 --> | ||||||
|   <el-form-item v-if="!isStructDataSpecs && !isParams" label="读写类型" prop="property.accessMode"> |   <el-form-item v-if="!isStructDataSpecs && !isParams" label="读写类型" prop="property.accessMode"> | ||||||
|     <el-radio-group v-model="property.accessMode"> |     <el-radio-group v-model="property.accessMode"> | ||||||
|       <el-radio :label="ThingModelAccessMode.READ_WRITE.value"> |       <el-radio :label="ThingModelAccessMode.READ_WRITE.value"> | ||||||
|  | @ -120,8 +122,8 @@ const getDataTypeOptions = computed(() => { | ||||||
| 
 | 
 | ||||||
| /** 属性值的数据类型切换时初始化相关数据 */ | /** 属性值的数据类型切换时初始化相关数据 */ | ||||||
| const handleChange = (dataType: any) => { | const handleChange = (dataType: any) => { | ||||||
|   property.value.dataSpecsList = [] |  | ||||||
|   property.value.dataSpecs = {} |   property.value.dataSpecs = {} | ||||||
|  |   property.value.dataSpecsList = [] | ||||||
|   // 不是列表型数据才设置 dataSpecs.dataType |   // 不是列表型数据才设置 dataSpecs.dataType | ||||||
|   ![DataSpecsDataType.ENUM, DataSpecsDataType.BOOL, DataSpecsDataType.STRUCT].includes(dataType) && |   ![DataSpecsDataType.ENUM, DataSpecsDataType.BOOL, DataSpecsDataType.STRUCT].includes(dataType) && | ||||||
|     (property.value.dataSpecs.dataType = dataType) |     (property.value.dataSpecs.dataType = dataType) | ||||||
|  |  | ||||||
|  | @ -1,9 +1,11 @@ | ||||||
|  | <!-- 产品的物模型表单(service 项) --> | ||||||
| <template> | <template> | ||||||
|   <el-form-item |   <el-form-item | ||||||
|     :rules="[{ required: true, message: '请选择调用方式', trigger: 'change' }]" |     :rules="[{ required: true, message: '请选择调用方式', trigger: 'change' }]" | ||||||
|     label="调用方式" |     label="调用方式" | ||||||
|     prop="service.callType" |     prop="service.callType" | ||||||
|   > |   > | ||||||
|  |     <!-- TODO @puhui999:默认选中,ASYNC 异步 --> | ||||||
|     <el-radio-group v-model="service.callType"> |     <el-radio-group v-model="service.callType"> | ||||||
|       <el-radio :value="ThingModelServiceCallType.ASYNC.value"> |       <el-radio :value="ThingModelServiceCallType.ASYNC.value"> | ||||||
|         {{ ThingModelServiceCallType.ASYNC.label }} |         {{ ThingModelServiceCallType.ASYNC.label }} | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ export interface DataSpecsEnumOrBoolDataVO { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** 属性值的数据类型 */ | /** 属性值的数据类型 */ | ||||||
|  | // TODO @puhui999:这个枚举类,要不放到 dict 里?
 | ||||||
| export const DataSpecsDataType = { | export const DataSpecsDataType = { | ||||||
|   INT: 'int', |   INT: 'int', | ||||||
|   FLOAT: 'float', |   FLOAT: 'float', | ||||||
|  | @ -34,6 +35,7 @@ export const DataSpecsDataType = { | ||||||
| } as const | } as const | ||||||
| 
 | 
 | ||||||
| /** 物体模型数据类型配置项 */ | /** 物体模型数据类型配置项 */ | ||||||
|  | // TODO @puhui999:搞到字典里;label 只使用()部分,就是整数型、单精度浮点型等,这种哈。这样,拼接 value(label) 就可以渲染出来,通用性更强
 | ||||||
| export const dataTypeOptions = [ | export const dataTypeOptions = [ | ||||||
|   { value: DataSpecsDataType.INT, label: 'int32 (整数型)' }, |   { value: DataSpecsDataType.INT, label: 'int32 (整数型)' }, | ||||||
|   { value: DataSpecsDataType.FLOAT, label: 'float (单精度浮点型)' }, |   { value: DataSpecsDataType.FLOAT, label: 'float (单精度浮点型)' }, | ||||||
|  | @ -185,6 +187,7 @@ export const ThingModelFormRules = { | ||||||
|   ], |   ], | ||||||
|   'property.accessMode': [{ required: true, message: '请选择读写类型', trigger: 'change' }] |   'property.accessMode': [{ required: true, message: '请选择读写类型', trigger: 'change' }] | ||||||
| } | } | ||||||
|  | 
 | ||||||
| /** 校验布尔值名称 */ | /** 校验布尔值名称 */ | ||||||
| export const validateBoolName = (_: any, value: string, callback: any) => { | export const validateBoolName = (_: any, value: string, callback: any) => { | ||||||
|   if (isEmpty(value)) { |   if (isEmpty(value)) { | ||||||
|  | @ -203,7 +206,7 @@ export const validateBoolName = (_: any, value: string, callback: any) => { | ||||||
|   } |   } | ||||||
|   // 检查长度(一个中文算一个字符)
 |   // 检查长度(一个中文算一个字符)
 | ||||||
|   if (value.length > 20) { |   if (value.length > 20) { | ||||||
|     callback(new Error('布尔值名称长度不能超过20个字符')) |     callback(new Error('布尔值名称长度不能超过 20 个字符')) | ||||||
|     return |     return | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | <!-- dataType:array 数组类型 --> | ||||||
| <template> | <template> | ||||||
|   <el-form-item label="元素类型" prop="property.dataSpecs.childDataType"> |   <el-form-item label="元素类型" prop="property.dataSpecs.childDataType"> | ||||||
|     <el-radio-group v-model="dataSpecs.childDataType" @change="handleChange"> |     <el-radio-group v-model="dataSpecs.childDataType" @change="handleChange"> | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | <!-- dataType:enum 数组类型 --> | ||||||
| <template> | <template> | ||||||
|   <el-form-item |   <el-form-item | ||||||
|     :rules="[{ required: true, validator: validateEnumList, trigger: 'change' }]" |     :rules="[{ required: true, validator: validateEnumList, trigger: 'change' }]" | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | <!-- dataType:number 数组类型 --> | ||||||
| <template> | <template> | ||||||
|   <el-form-item label="取值范围"> |   <el-form-item label="取值范围"> | ||||||
|     <div class="flex items-center justify-between"> |     <div class="flex items-center justify-between"> | ||||||
|  | @ -43,7 +44,7 @@ | ||||||
|       :model-value="dataSpecs.unit ? dataSpecs.unitName + '-' + dataSpecs.unit : ''" |       :model-value="dataSpecs.unit ? dataSpecs.unitName + '-' + dataSpecs.unit : ''" | ||||||
|       filterable |       filterable | ||||||
|       placeholder="请选择单位" |       placeholder="请选择单位" | ||||||
|       style="width: 240px" |       class="w-1/1" | ||||||
|       @change="unitChange" |       @change="unitChange" | ||||||
|     > |     > | ||||||
|       <el-option |       <el-option | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | <!-- dataType:struct 数组类型 --> | ||||||
| <template> | <template> | ||||||
|   <!-- struct 数据展示 --> |   <!-- struct 数据展示 --> | ||||||
|   <el-form-item |   <el-form-item | ||||||
|  | @ -89,6 +90,7 @@ const openStructForm = (val: any) => { | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | 
 | ||||||
| /** 删除 struct 项 */ | /** 删除 struct 项 */ | ||||||
| const deleteStructItem = (index: number) => { | const deleteStructItem = (index: number) => { | ||||||
|   dataSpecsList.value.splice(index, 1) |   dataSpecsList.value.splice(index, 1) | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | <!-- 产品的物模型列表 --> | ||||||
| <template> | <template> | ||||||
|   <ContentWrap> |   <ContentWrap> | ||||||
|     <!-- 搜索工作栏 --> |     <!-- 搜索工作栏 --> | ||||||
|  | @ -44,6 +45,8 @@ | ||||||
|       </el-form-item> |       </el-form-item> | ||||||
|     </el-form> |     </el-form> | ||||||
|   </ContentWrap> |   </ContentWrap> | ||||||
|  | 
 | ||||||
|  |   <!-- 列表 --> | ||||||
|   <ContentWrap> |   <ContentWrap> | ||||||
|     <el-tabs> |     <el-tabs> | ||||||
|       <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true"> |       <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true"> | ||||||
|  | @ -73,6 +76,7 @@ | ||||||
|                   ].includes(row.property.dataType) |                   ].includes(row.property.dataType) | ||||||
|                 " |                 " | ||||||
|               > |               > | ||||||
|  |                 <!-- TODO @puhui999:把数据定义,抽成一个方法?这样,其它地方也可以复用哈。 --> | ||||||
|                 取值范围:{{ `${row.property.dataSpecs.min}~${row.property.dataSpecs.max}` }} |                 取值范围:{{ `${row.property.dataSpecs.min}~${row.property.dataSpecs.max}` }} | ||||||
|               </div> |               </div> | ||||||
|               <!-- 非列表型:文本 --> |               <!-- 非列表型:文本 --> | ||||||
|  | @ -193,6 +197,7 @@ const getList = async () => { | ||||||
|     loading.value = false |     loading.value = false | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | 
 | ||||||
| /** 搜索按钮操作 */ | /** 搜索按钮操作 */ | ||||||
| const handleQuery = () => { | const handleQuery = () => { | ||||||
|   queryParams.pageNo = 1 |   queryParams.pageNo = 1 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 YunaiV
						YunaiV