From 69444994ad442ae1cfded77dd44569f58d900e3a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 21 Jun 2026 07:06:20 -0700 Subject: [PATCH] =?UTF-8?q?fix(ts):=20=E6=94=B6=E5=B0=BE=20IOT=20=E7=89=A9?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E7=B1=BB=E5=9E=8B=EF=BC=8Cts:check=20?= =?UTF-8?q?=E6=B8=85=E9=9B=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 去掉 ThingModelProperty/Event/Service 重复空接口,dataSpecs 建为通用联合类型 - dataSpecsList 支持结构体/枚举/布尔项,补齐枚举项 identifier/accessMode - 物模型表单编辑态用类型断言;DataDefinition/ThingModelProperty 对动态 dataSpecs 安全访问 - 场景规则动态字段改用 Object.assign,规避 keyof 写入被推成 never Co-Authored-By: Codex ts:check 26 → 0 --- src/api/iot/thingmodel/index.ts | 77 ++++++++----------- .../configs/CurrentTimeConditionConfig.vue | 2 +- .../form/configs/MainConditionInnerConfig.vue | 2 +- src/views/iot/thingmodel/ThingModelForm.vue | 36 +++++---- .../iot/thingmodel/ThingModelProperty.vue | 10 ++- .../thingmodel/components/DataDefinition.vue | 20 +++-- 6 files changed, 79 insertions(+), 68 deletions(-) diff --git a/src/api/iot/thingmodel/index.ts b/src/api/iot/thingmodel/index.ts index fb9492675..1a14b2d3c 100644 --- a/src/api/iot/thingmodel/index.ts +++ b/src/api/iot/thingmodel/index.ts @@ -18,47 +18,35 @@ export interface ThingModelData { service?: ThingModelService // 服务 } -/** - * ThingModelProperty 类型 - */ -export interface ThingModelProperty { - [key: string]: any -} - -/** - * ThingModelEvent 类型 - */ -export interface ThingModelEvent { - [key: string]: any -} - -/** - * ThingModelService 类型 - */ -export interface ThingModelService { - [key: string]: any -} - /** dataSpecs 数值型数据结构 */ export interface DataSpecsNumberData { - dataType: 'int' | 'float' | 'double' // 数据类型,取值为 INT、FLOAT 或 DOUBLE - max: string // 最大值,必须与 dataType 设置一致,且为 STRING 类型 - min: string // 最小值,必须与 dataType 设置一致,且为 STRING 类型 - step: string // 步长,必须与 dataType 设置一致,且为 STRING 类型 + dataType: string // 数据类型,取值为 INT、FLOAT 或 DOUBLE + max?: string // 最大值,必须与 dataType 设置一致,且为 STRING 类型 + min?: string // 最小值,必须与 dataType 设置一致,且为 STRING 类型 + step?: string // 步长,必须与 dataType 设置一致,且为 STRING 类型 precise?: string // 精度,当 dataType 为 FLOAT 或 DOUBLE 时可选 defaultValue?: string // 默认值,可选 - unit: string // 单位的符号 - unitName: string // 单位的名称 + unit?: string // 单位的符号 + unitName?: string // 单位的名称 } /** dataSpecs 枚举型数据结构 */ export interface DataSpecsEnumOrBoolData { - dataType: 'enum' | 'bool' + dataType: string defaultValue?: string // 默认值,可选 name: string // 枚举项的名称 value: number | undefined // 枚举值 } +/** dataSpecs 通用数据结构 */ +export type ThingModelDataSpecs = + | DataSpecsNumberData + | DataSpecsEnumOrBoolData + | ThingModelDateOrTextDataSpecs + | ThingModelArrayDataSpecs + | ThingModelStructDataSpecs + | Record + /** 物模型TSL响应数据结构 */ export interface IotThingModelTSLResp { productId: number @@ -76,8 +64,9 @@ export interface ThingModelProperty { required?: boolean dataType: string description?: string - dataSpecs?: ThingModelProperty - dataSpecsList?: ThingModelProperty[] + dataSpecs?: ThingModelDataSpecs + dataSpecsList?: ThingModelPropertyDataSpecs[] + value?: number } /** 物模型事件 */ @@ -110,8 +99,8 @@ export interface ThingModelParam { direction: string paraOrder?: number dataType: string - dataSpecs?: ThingModelProperty - dataSpecsList?: ThingModelProperty[] + dataSpecs?: ThingModelDataSpecs + dataSpecsList?: ThingModelPropertyDataSpecs[] } /** 数值型数据规范 */ @@ -142,24 +131,26 @@ export interface ThingModelDateOrTextDataSpecs { /** 数组型数据规范 */ export interface ThingModelArrayDataSpecs { - dataType: 'array' - size: number - childDataType: string - dataSpecsList?: ThingModelProperty[] + dataType: string + size?: number + childDataType?: string + dataSpecsList?: ThingModelPropertyDataSpecs[] } /** 结构体型数据规范 */ export interface ThingModelStructDataSpecs { - dataType: 'struct' - identifier: string - name: string - accessMode: string + dataType: string + identifier?: string + name?: string + accessMode?: string required?: boolean - childDataType: string - dataSpecs?: ThingModelProperty - dataSpecsList?: ThingModelProperty[] + childDataType?: string + dataSpecs?: ThingModelDataSpecs + dataSpecsList?: ThingModelPropertyDataSpecs[] } +export type ThingModelPropertyDataSpecs = ThingModelProperty | DataSpecsEnumOrBoolData + // IoT 产品物模型 API export const ThingModelApi = { // 查询产品物模型分页 diff --git a/src/views/iot/rule/scene/form/configs/CurrentTimeConditionConfig.vue b/src/views/iot/rule/scene/form/configs/CurrentTimeConditionConfig.vue index 720c96f3c..f0565f948 100644 --- a/src/views/iot/rule/scene/form/configs/CurrentTimeConditionConfig.vue +++ b/src/views/iot/rule/scene/form/configs/CurrentTimeConditionConfig.vue @@ -189,7 +189,7 @@ const timeValue2 = computed(() => { * @param value 字段值 */ const updateConditionField = (field: keyof TriggerCondition, value: any) => { - condition.value[field] = value + Object.assign(condition.value, { [field]: value }) emit('field-change', field) } diff --git a/src/views/iot/rule/scene/form/configs/MainConditionInnerConfig.vue b/src/views/iot/rule/scene/form/configs/MainConditionInnerConfig.vue index 85066444e..b8f1402d8 100644 --- a/src/views/iot/rule/scene/form/configs/MainConditionInnerConfig.vue +++ b/src/views/iot/rule/scene/form/configs/MainConditionInnerConfig.vue @@ -313,7 +313,7 @@ const ensureDeviceStatusDefaults = () => { * @param value 字段值 */ const updateConditionField = (field: keyof Trigger, value: any) => { - condition.value[field] = value + Object.assign(condition.value, { [field]: value }) nextTick(() => { innerFormRef.value?.validateField(field as string).catch(() => {}) }) diff --git a/src/views/iot/thingmodel/ThingModelForm.vue b/src/views/iot/thingmodel/ThingModelForm.vue index 399fdfbf1..bd039b5d2 100644 --- a/src/views/iot/thingmodel/ThingModelForm.vue +++ b/src/views/iot/thingmodel/ThingModelForm.vue @@ -63,7 +63,14 @@ import { ProductVO } from '@/api/iot/product/product' import ThingModelProperty from './ThingModelProperty.vue' import ThingModelService from './ThingModelService.vue' import ThingModelEvent from './ThingModelEvent.vue' -import { ThingModelApi, ThingModelData, ThingModelFormRules } from '@/api/iot/thingmodel' +import { + ThingModelApi, + ThingModelData, + ThingModelEvent as IotThingModelEvent, + ThingModelFormRules, + ThingModelProperty as IotThingModelProperty, + ThingModelService as IotThingModelService +} from '@/api/iot/thingmodel' import { IOT_PROVIDE_KEY, IoTDataSpecsDataTypeEnum, @@ -93,9 +100,9 @@ const formData = ref({ dataSpecs: { dataType: IoTDataSpecsDataTypeEnum.INT } - }, - service: {}, - event: {} + } as IotThingModelProperty, + service: {} as IotThingModelService, + event: {} as IotThingModelEvent }) const formRef = ref() // 表单 Ref @@ -118,20 +125,23 @@ const open = async (type: string, id?: number) => { dataSpecs: { dataType: IoTDataSpecsDataTypeEnum.INT } - } + } as IotThingModelProperty } // 情况二:服务初始化 if (isEmpty(formData.value.service)) { - formData.value.service = { inputParams: [], outputParams: [] } + formData.value.service = { + inputParams: [], + outputParams: [] + } as unknown as IotThingModelService } else { - formData.value.service.inputParams ??= [] - formData.value.service.outputParams ??= [] + formData.value.service!.inputParams ??= [] + formData.value.service!.outputParams ??= [] } // 情况三:事件初始化 if (isEmpty(formData.value.event)) { - formData.value.event = { outputParams: [] } + formData.value.event = { outputParams: [] } as unknown as IotThingModelEvent } else { - formData.value.event.outputParams ??= [] + formData.value.event!.outputParams ??= [] } } finally { formLoading.value = false @@ -217,9 +227,9 @@ const resetForm = () => { dataSpecs: { dataType: IoTDataSpecsDataTypeEnum.INT } - }, - service: {}, - event: {} + } as IotThingModelProperty, + service: {} as IotThingModelService, + event: {} as IotThingModelEvent } formRef.value?.resetFields() } diff --git a/src/views/iot/thingmodel/ThingModelProperty.vue b/src/views/iot/thingmodel/ThingModelProperty.vue index 490f364e8..989806628 100644 --- a/src/views/iot/thingmodel/ThingModelProperty.vue +++ b/src/views/iot/thingmodel/ThingModelProperty.vue @@ -22,7 +22,7 @@ IoTDataSpecsDataTypeEnum.INT, IoTDataSpecsDataTypeEnum.DOUBLE, IoTDataSpecsDataTypeEnum.FLOAT - ].includes(property.dataType || '') + ].includes(property.dataType as any) " v-model="property.dataSpecs" /> @@ -60,7 +60,11 @@ label="数据长度" prop="property.dataSpecs.length" > - + @@ -134,7 +138,7 @@ const handleChange = (dataType: any) => { IoTDataSpecsDataTypeEnum.ENUM, IoTDataSpecsDataTypeEnum.BOOL, IoTDataSpecsDataTypeEnum.STRUCT - ].includes(dataType) && (property.value.dataSpecs.dataType = dataType) + ].includes(dataType) && (property.value.dataSpecs!.dataType = dataType) switch (dataType) { case IoTDataSpecsDataTypeEnum.ENUM: property.value.dataSpecsList.push({ diff --git a/src/views/iot/thingmodel/components/DataDefinition.vue b/src/views/iot/thingmodel/components/DataDefinition.vue index 22e6e3dd9..7589c8310 100644 --- a/src/views/iot/thingmodel/components/DataDefinition.vue +++ b/src/views/iot/thingmodel/components/DataDefinition.vue @@ -8,14 +8,16 @@ IoTDataSpecsDataTypeEnum.INT, IoTDataSpecsDataTypeEnum.DOUBLE, IoTDataSpecsDataTypeEnum.FLOAT - ].includes(data.property.dataType) + ].includes(data.property.dataType as any) " > - 取值范围:{{ `${data.property.dataSpecs.min}~${data.property.dataSpecs.max}` }} + 取值范围:{{ + `${getDataSpecsValue(data.property, 'min')}~${getDataSpecsValue(data.property, 'max')}` + }}
- 数据长度:{{ data.property.dataSpecs.length }} + 数据长度:{{ getDataSpecsValue(data.property, 'length') }}
- @@ -32,7 +34,7 @@
{{ IoTDataSpecsDataTypeEnum.BOOL === data.property.dataType ? '布尔值' : '枚举值' }}:
-
+
{{ `${item.name}-${item.value}` }}
@@ -56,7 +58,7 @@