Compare commits
5 Commits
9ef2ebd13a
...
cfbe8f4df0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfbe8f4df0 | ||
|
|
9d521d74a5 | ||
|
|
e365da3531 | ||
|
|
821abb0740 | ||
|
|
38427d204d |
@ -1239,7 +1239,7 @@ export const CopyAnotherDeviceInputSchema = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
description: '复制已存在设备物模型信息'
|
description: '复制已存在设备端物模型信息'
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const CopyAnotherProductInputSchema = {
|
export const CopyAnotherProductInputSchema = {
|
||||||
@ -1263,6 +1263,27 @@ export const CopyAnotherProductInputSchema = {
|
|||||||
description: '复制已存在产品设备物模型信息'
|
description: '复制已存在产品设备物模型信息'
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export const CopyIoTPlatformThingModelToDeviceInputSchema = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
ioTPlatform: {
|
||||||
|
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
|
||||||
|
},
|
||||||
|
ioTPlatformProductId: {
|
||||||
|
type: 'string',
|
||||||
|
description: '物联网平台中对应的产品Id',
|
||||||
|
nullable: true
|
||||||
|
},
|
||||||
|
deviceThingModelId: {
|
||||||
|
type: 'string',
|
||||||
|
description: '当前设备端物模型数据Id',
|
||||||
|
format: 'uuid'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
additionalProperties: false,
|
||||||
|
description: '通过平台端物模型快速创建设备端物模型信息'
|
||||||
|
} as const;
|
||||||
|
|
||||||
export const CopyStandardThingModelInputSchema = {
|
export const CopyStandardThingModelInputSchema = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
@ -2520,20 +2541,21 @@ export const DeviceThingModelCommandInfoUpdateInputSchema = {
|
|||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const DeviceThingModelCreateInputSchema = {
|
export const DeviceThingModelCreateInputSchema = {
|
||||||
|
required: ['deviceModelName', 'ioTPlatform', 'ioTPlatformProductId'],
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
deviceModelName: {
|
deviceModelName: {
|
||||||
|
minLength: 1,
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: '设备端物模型名称',
|
description: '设备端物模型名称'
|
||||||
nullable: true
|
|
||||||
},
|
},
|
||||||
ioTPlatform: {
|
ioTPlatform: {
|
||||||
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
|
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
|
||||||
},
|
},
|
||||||
ioTPlatformProductId: {
|
ioTPlatformProductId: {
|
||||||
|
minLength: 1,
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: '物联网平台中对应的产品Id',
|
description: '物联网平台中对应的产品Id'
|
||||||
nullable: true
|
|
||||||
},
|
},
|
||||||
scriptName: {
|
scriptName: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -2544,9 +2566,6 @@ export const DeviceThingModelCreateInputSchema = {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
description: '脚本函数体',
|
description: '脚本函数体',
|
||||||
nullable: true
|
nullable: true
|
||||||
},
|
|
||||||
parsingSequence: {
|
|
||||||
'$ref': '#/components/schemas/ParsingSequenceTypeEnum'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
@ -2649,9 +2668,6 @@ export const DeviceThingModelManagementDtoSchema = {
|
|||||||
description: '脚本函数体',
|
description: '脚本函数体',
|
||||||
nullable: true
|
nullable: true
|
||||||
},
|
},
|
||||||
parsingSequence: {
|
|
||||||
'$ref': '#/components/schemas/ParsingSequenceTypeEnum'
|
|
||||||
},
|
|
||||||
functionAnalysisFlag: {
|
functionAnalysisFlag: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: '函数解析标记,默认为false, 不能解析'
|
description: '函数解析标记,默认为false, 不能解析'
|
||||||
@ -2749,7 +2765,7 @@ export const DeviceThingModelPageInputSchema = {
|
|||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const DeviceThingModelPropertyCreateInputSchema = {
|
export const DeviceThingModelPropertyCreateInputSchema = {
|
||||||
required: ['deviceThingModelId', 'ioTPlatformRawFieldDataType', 'ioTPlatformRawFieldName', 'standardFieldDisplayName', 'standardFieldName', 'standardFieldValueType'],
|
required: ['deviceThingModelId', 'ioTPlatformRawFieldDataType', 'ioTPlatformRawFieldName', 'nativeSkipNumber', 'nativeTakeNumber', 'parsingSequence', 'standardFieldDisplayName', 'standardFieldName', 'standardFieldValueType'],
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
deviceThingModelId: {
|
deviceThingModelId: {
|
||||||
@ -2791,15 +2807,30 @@ export const DeviceThingModelPropertyCreateInputSchema = {
|
|||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: '是否需要值类型转换'
|
description: '是否需要值类型转换'
|
||||||
},
|
},
|
||||||
skipNumber: {
|
nativeSkipNumber: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
description: '跳过数量',
|
description: '正序跳过数量',
|
||||||
format: 'int32'
|
format: 'int32'
|
||||||
},
|
},
|
||||||
takeNumber: {
|
nativeTakeNumber: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
description: '获取数量',
|
description: '正序获取数量',
|
||||||
format: 'int32'
|
format: 'int32'
|
||||||
|
},
|
||||||
|
parsingSequence: {
|
||||||
|
'$ref': '#/components/schemas/ParsingSequenceTypeEnum'
|
||||||
|
},
|
||||||
|
reversalSkipNumber: {
|
||||||
|
type: 'integer',
|
||||||
|
description: '反转跳过数量',
|
||||||
|
format: 'int32',
|
||||||
|
nullable: true
|
||||||
|
},
|
||||||
|
reversalTakeNumber: {
|
||||||
|
type: 'integer',
|
||||||
|
description: '反转获取数量',
|
||||||
|
format: 'int32',
|
||||||
|
nullable: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
@ -2893,6 +2924,11 @@ export const DeviceThingModelPropertyInfoDtoSchema = {
|
|||||||
description: '物联网平台中对应的产品Id',
|
description: '物联网平台中对应的产品Id',
|
||||||
nullable: true
|
nullable: true
|
||||||
},
|
},
|
||||||
|
ioTPlatformThingModelDataId: {
|
||||||
|
type: 'string',
|
||||||
|
description: '平台端物模型数据Id',
|
||||||
|
format: 'uuid'
|
||||||
|
},
|
||||||
filedType: {
|
filedType: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: '物联网平台中对应产品物模型属性或者事件类型 JiShe.ServicePro.Core.DataDictionaryTypeConst',
|
description: '物联网平台中对应产品物模型属性或者事件类型 JiShe.ServicePro.Core.DataDictionaryTypeConst',
|
||||||
@ -2927,15 +2963,30 @@ export const DeviceThingModelPropertyInfoDtoSchema = {
|
|||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: '是否需要值类型转换'
|
description: '是否需要值类型转换'
|
||||||
},
|
},
|
||||||
skipNumber: {
|
nativeSkipNumber: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
description: '跳过数量',
|
description: '正序跳过数量',
|
||||||
format: 'int32'
|
format: 'int32'
|
||||||
},
|
},
|
||||||
takeNumber: {
|
nativeTakeNumber: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
description: '获取数量',
|
description: '正序获取数量',
|
||||||
format: 'int32'
|
format: 'int32'
|
||||||
|
},
|
||||||
|
parsingSequence: {
|
||||||
|
'$ref': '#/components/schemas/ParsingSequenceTypeEnum'
|
||||||
|
},
|
||||||
|
reversalSkipNumber: {
|
||||||
|
type: 'integer',
|
||||||
|
description: '反转跳过数量',
|
||||||
|
format: 'int32',
|
||||||
|
nullable: true
|
||||||
|
},
|
||||||
|
reversalTakeNumber: {
|
||||||
|
type: 'integer',
|
||||||
|
description: '反转获取数量',
|
||||||
|
format: 'int32',
|
||||||
|
nullable: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
@ -3021,7 +3072,7 @@ export const DeviceThingModelPropertyPageInputSchema = {
|
|||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const DeviceThingModelPropertyUpdateInputSchema = {
|
export const DeviceThingModelPropertyUpdateInputSchema = {
|
||||||
required: ['deviceThingModelId', 'id', 'ioTPlatformRawFieldDataType', 'ioTPlatformRawFieldName', 'standardFieldDisplayName', 'standardFieldName', 'standardFieldValueType'],
|
required: ['deviceThingModelId', 'id', 'ioTPlatformRawFieldDataType', 'ioTPlatformRawFieldName', 'nativeSkipNumber', 'nativeTakeNumber', 'parsingSequence', 'standardFieldDisplayName', 'standardFieldName', 'standardFieldValueType'],
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
deviceThingModelId: {
|
deviceThingModelId: {
|
||||||
@ -3063,16 +3114,31 @@ export const DeviceThingModelPropertyUpdateInputSchema = {
|
|||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: '是否需要值类型转换'
|
description: '是否需要值类型转换'
|
||||||
},
|
},
|
||||||
skipNumber: {
|
nativeSkipNumber: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
description: '跳过数量',
|
description: '正序跳过数量',
|
||||||
format: 'int32'
|
format: 'int32'
|
||||||
},
|
},
|
||||||
takeNumber: {
|
nativeTakeNumber: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
description: '获取数量',
|
description: '正序获取数量',
|
||||||
format: 'int32'
|
format: 'int32'
|
||||||
},
|
},
|
||||||
|
parsingSequence: {
|
||||||
|
'$ref': '#/components/schemas/ParsingSequenceTypeEnum'
|
||||||
|
},
|
||||||
|
reversalSkipNumber: {
|
||||||
|
type: 'integer',
|
||||||
|
description: '反转跳过数量',
|
||||||
|
format: 'int32',
|
||||||
|
nullable: true
|
||||||
|
},
|
||||||
|
reversalTakeNumber: {
|
||||||
|
type: 'integer',
|
||||||
|
description: '反转获取数量',
|
||||||
|
format: 'int32',
|
||||||
|
nullable: true
|
||||||
|
},
|
||||||
id: {
|
id: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'uuid'
|
format: 'uuid'
|
||||||
@ -3083,20 +3149,21 @@ export const DeviceThingModelPropertyUpdateInputSchema = {
|
|||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const DeviceThingModelUpdateInputSchema = {
|
export const DeviceThingModelUpdateInputSchema = {
|
||||||
|
required: ['deviceModelName', 'ioTPlatform', 'ioTPlatformProductId'],
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
deviceModelName: {
|
deviceModelName: {
|
||||||
|
minLength: 1,
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: '设备端物模型名称',
|
description: '设备端物模型名称'
|
||||||
nullable: true
|
|
||||||
},
|
},
|
||||||
ioTPlatform: {
|
ioTPlatform: {
|
||||||
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
|
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
|
||||||
},
|
},
|
||||||
ioTPlatformProductId: {
|
ioTPlatformProductId: {
|
||||||
|
minLength: 1,
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: '物联网平台中对应的产品Id',
|
description: '物联网平台中对应的产品Id'
|
||||||
nullable: true
|
|
||||||
},
|
},
|
||||||
scriptName: {
|
scriptName: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -3108,9 +3175,6 @@ export const DeviceThingModelUpdateInputSchema = {
|
|||||||
description: '脚本函数体',
|
description: '脚本函数体',
|
||||||
nullable: true
|
nullable: true
|
||||||
},
|
},
|
||||||
parsingSequence: {
|
|
||||||
'$ref': '#/components/schemas/ParsingSequenceTypeEnum'
|
|
||||||
},
|
|
||||||
id: {
|
id: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'uuid'
|
format: 'uuid'
|
||||||
@ -8737,11 +8801,11 @@ export const ParameterApiDescriptionModelSchema = {
|
|||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const ParsingSequenceTypeEnumSchema = {
|
export const ParsingSequenceTypeEnumSchema = {
|
||||||
enum: [1, 2],
|
enum: [1, 2, 3],
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
description: '解析顺序枚举',
|
description: '解析顺序枚举',
|
||||||
format: 'int32',
|
format: 'int32',
|
||||||
'说明:': '正序=1,高低位反转=2'
|
'说明:': '正序=1,高低反转=2,BCD码=3'
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const PermissionOutputSchema = {
|
export const PermissionOutputSchema = {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -233,7 +233,7 @@ export type ControllerInterfaceApiDescriptionModel = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 复制已存在设备物模型信息
|
* 复制已存在设备端物模型信息
|
||||||
*/
|
*/
|
||||||
export type CopyAnotherDeviceInput = {
|
export type CopyAnotherDeviceInput = {
|
||||||
ioTPlatform?: IoTPlatformTypeEnum;
|
ioTPlatform?: IoTPlatformTypeEnum;
|
||||||
@ -262,6 +262,21 @@ export type CopyAnotherProductInput = {
|
|||||||
sourceProductId?: (string) | null;
|
sourceProductId?: (string) | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过平台端物模型快速创建设备端物模型信息
|
||||||
|
*/
|
||||||
|
export type CopyIoTPlatformThingModelToDeviceInput = {
|
||||||
|
ioTPlatform?: IoTPlatformTypeEnum;
|
||||||
|
/**
|
||||||
|
* 物联网平台中对应的产品Id
|
||||||
|
*/
|
||||||
|
ioTPlatformProductId?: (string) | null;
|
||||||
|
/**
|
||||||
|
* 当前设备端物模型数据Id
|
||||||
|
*/
|
||||||
|
deviceThingModelId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 复制标准物模型
|
* 复制标准物模型
|
||||||
*/
|
*/
|
||||||
@ -1419,12 +1434,12 @@ export type DeviceThingModelCreateInput = {
|
|||||||
/**
|
/**
|
||||||
* 设备端物模型名称
|
* 设备端物模型名称
|
||||||
*/
|
*/
|
||||||
deviceModelName?: (string) | null;
|
deviceModelName: string;
|
||||||
ioTPlatform?: IoTPlatformTypeEnum;
|
ioTPlatform: IoTPlatformTypeEnum;
|
||||||
/**
|
/**
|
||||||
* 物联网平台中对应的产品Id
|
* 物联网平台中对应的产品Id
|
||||||
*/
|
*/
|
||||||
ioTPlatformProductId?: (string) | null;
|
ioTPlatformProductId: string;
|
||||||
/**
|
/**
|
||||||
* 脚本函数名称
|
* 脚本函数名称
|
||||||
*/
|
*/
|
||||||
@ -1433,7 +1448,6 @@ export type DeviceThingModelCreateInput = {
|
|||||||
* 脚本函数体
|
* 脚本函数体
|
||||||
*/
|
*/
|
||||||
functionScript?: (string) | null;
|
functionScript?: (string) | null;
|
||||||
parsingSequence?: ParsingSequenceTypeEnum;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1491,7 +1505,6 @@ export type DeviceThingModelManagementDto = {
|
|||||||
* 脚本函数体
|
* 脚本函数体
|
||||||
*/
|
*/
|
||||||
functionScript?: (string) | null;
|
functionScript?: (string) | null;
|
||||||
parsingSequence?: ParsingSequenceTypeEnum;
|
|
||||||
/**
|
/**
|
||||||
* 函数解析标记,默认为false, 不能解析
|
* 函数解析标记,默认为false, 不能解析
|
||||||
*/
|
*/
|
||||||
@ -1587,13 +1600,22 @@ export type DeviceThingModelPropertyCreateInput = {
|
|||||||
*/
|
*/
|
||||||
isValueNeedConvert?: boolean;
|
isValueNeedConvert?: boolean;
|
||||||
/**
|
/**
|
||||||
* 跳过数量
|
* 正序跳过数量
|
||||||
*/
|
*/
|
||||||
skipNumber?: number;
|
nativeSkipNumber: number;
|
||||||
/**
|
/**
|
||||||
* 获取数量
|
* 正序获取数量
|
||||||
*/
|
*/
|
||||||
takeNumber?: number;
|
nativeTakeNumber: number;
|
||||||
|
parsingSequence: ParsingSequenceTypeEnum;
|
||||||
|
/**
|
||||||
|
* 反转跳过数量
|
||||||
|
*/
|
||||||
|
reversalSkipNumber?: (number) | null;
|
||||||
|
/**
|
||||||
|
* 反转获取数量
|
||||||
|
*/
|
||||||
|
reversalTakeNumber?: (number) | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1643,6 +1665,10 @@ export type DeviceThingModelPropertyInfoDto = {
|
|||||||
* 物联网平台中对应的产品Id
|
* 物联网平台中对应的产品Id
|
||||||
*/
|
*/
|
||||||
ioTPlatformProductId?: (string) | null;
|
ioTPlatformProductId?: (string) | null;
|
||||||
|
/**
|
||||||
|
* 平台端物模型数据Id
|
||||||
|
*/
|
||||||
|
ioTPlatformThingModelDataId?: string;
|
||||||
/**
|
/**
|
||||||
* 物联网平台中对应产品物模型属性或者事件类型 JiShe.ServicePro.Core.DataDictionaryTypeConst
|
* 物联网平台中对应产品物模型属性或者事件类型 JiShe.ServicePro.Core.DataDictionaryTypeConst
|
||||||
*/
|
*/
|
||||||
@ -1672,13 +1698,22 @@ export type DeviceThingModelPropertyInfoDto = {
|
|||||||
*/
|
*/
|
||||||
isValueNeedConvert?: boolean;
|
isValueNeedConvert?: boolean;
|
||||||
/**
|
/**
|
||||||
* 跳过数量
|
* 正序跳过数量
|
||||||
*/
|
*/
|
||||||
skipNumber?: number;
|
nativeSkipNumber?: number;
|
||||||
/**
|
/**
|
||||||
* 获取数量
|
* 正序获取数量
|
||||||
*/
|
*/
|
||||||
takeNumber?: number;
|
nativeTakeNumber?: number;
|
||||||
|
parsingSequence?: ParsingSequenceTypeEnum;
|
||||||
|
/**
|
||||||
|
* 反转跳过数量
|
||||||
|
*/
|
||||||
|
reversalSkipNumber?: (number) | null;
|
||||||
|
/**
|
||||||
|
* 反转获取数量
|
||||||
|
*/
|
||||||
|
reversalTakeNumber?: (number) | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DeviceThingModelPropertyInfoDtoPagedResultDto = {
|
export type DeviceThingModelPropertyInfoDtoPagedResultDto = {
|
||||||
@ -1769,13 +1804,22 @@ export type DeviceThingModelPropertyUpdateInput = {
|
|||||||
*/
|
*/
|
||||||
isValueNeedConvert?: boolean;
|
isValueNeedConvert?: boolean;
|
||||||
/**
|
/**
|
||||||
* 跳过数量
|
* 正序跳过数量
|
||||||
*/
|
*/
|
||||||
skipNumber?: number;
|
nativeSkipNumber: number;
|
||||||
/**
|
/**
|
||||||
* 获取数量
|
* 正序获取数量
|
||||||
*/
|
*/
|
||||||
takeNumber?: number;
|
nativeTakeNumber: number;
|
||||||
|
parsingSequence: ParsingSequenceTypeEnum;
|
||||||
|
/**
|
||||||
|
* 反转跳过数量
|
||||||
|
*/
|
||||||
|
reversalSkipNumber?: (number) | null;
|
||||||
|
/**
|
||||||
|
* 反转获取数量
|
||||||
|
*/
|
||||||
|
reversalTakeNumber?: (number) | null;
|
||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1783,12 +1827,12 @@ export type DeviceThingModelUpdateInput = {
|
|||||||
/**
|
/**
|
||||||
* 设备端物模型名称
|
* 设备端物模型名称
|
||||||
*/
|
*/
|
||||||
deviceModelName?: (string) | null;
|
deviceModelName: string;
|
||||||
ioTPlatform?: IoTPlatformTypeEnum;
|
ioTPlatform: IoTPlatformTypeEnum;
|
||||||
/**
|
/**
|
||||||
* 物联网平台中对应的产品Id
|
* 物联网平台中对应的产品Id
|
||||||
*/
|
*/
|
||||||
ioTPlatformProductId?: (string) | null;
|
ioTPlatformProductId: string;
|
||||||
/**
|
/**
|
||||||
* 脚本函数名称
|
* 脚本函数名称
|
||||||
*/
|
*/
|
||||||
@ -1797,7 +1841,6 @@ export type DeviceThingModelUpdateInput = {
|
|||||||
* 脚本函数体
|
* 脚本函数体
|
||||||
*/
|
*/
|
||||||
functionScript?: (string) | null;
|
functionScript?: (string) | null;
|
||||||
parsingSequence?: ParsingSequenceTypeEnum;
|
|
||||||
id?: string;
|
id?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4656,7 +4699,7 @@ export type ParameterApiDescriptionModel = {
|
|||||||
/**
|
/**
|
||||||
* 解析顺序枚举
|
* 解析顺序枚举
|
||||||
*/
|
*/
|
||||||
export type ParsingSequenceTypeEnum = 1 | 2;
|
export type ParsingSequenceTypeEnum = 1 | 2 | 3;
|
||||||
|
|
||||||
export type PermissionOutput = {
|
export type PermissionOutput = {
|
||||||
grants?: Array<(string)> | null;
|
grants?: Array<(string)> | null;
|
||||||
@ -5999,15 +6042,25 @@ export type PostDeviceThingModelManagementFindByPlatformProductIdAsyncResponse =
|
|||||||
|
|
||||||
export type PostDeviceThingModelManagementFindByPlatformProductIdAsyncError = unknown;
|
export type PostDeviceThingModelManagementFindByPlatformProductIdAsyncError = unknown;
|
||||||
|
|
||||||
export type PostDeviceThingModelManagementCopyAnotherThingModelAsyncData = {
|
export type PostDeviceThingModelManagementCopyAnotherDeviceThingModelAsyncData = {
|
||||||
query?: {
|
query?: {
|
||||||
input?: CopyAnotherDeviceInput;
|
input?: CopyAnotherDeviceInput;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PostDeviceThingModelManagementCopyAnotherThingModelAsyncResponse = (boolean);
|
export type PostDeviceThingModelManagementCopyAnotherDeviceThingModelAsyncResponse = (boolean);
|
||||||
|
|
||||||
export type PostDeviceThingModelManagementCopyAnotherThingModelAsyncError = unknown;
|
export type PostDeviceThingModelManagementCopyAnotherDeviceThingModelAsyncError = unknown;
|
||||||
|
|
||||||
|
export type PostDeviceThingModelManagementCopyIoTplatformThingModelToDeviceAsyncData = {
|
||||||
|
query?: {
|
||||||
|
input?: CopyIoTPlatformThingModelToDeviceInput;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PostDeviceThingModelManagementCopyIoTplatformThingModelToDeviceAsyncResponse = (boolean);
|
||||||
|
|
||||||
|
export type PostDeviceThingModelManagementCopyIoTplatformThingModelToDeviceAsyncError = unknown;
|
||||||
|
|
||||||
export type PostDeviceThingModelManagementPageAsyncData = {
|
export type PostDeviceThingModelManagementPageAsyncData = {
|
||||||
query?: {
|
query?: {
|
||||||
|
|||||||
@ -171,11 +171,13 @@ const handleMenuClick = (e: any) => {
|
|||||||
<Icon :icon="action.popConfirm.icon" />
|
<Icon :icon="action.popConfirm.icon" />
|
||||||
</template>
|
</template>
|
||||||
<div
|
<div
|
||||||
:class="
|
:class="[
|
||||||
action.disabled === true
|
action.disabled === true
|
||||||
? 'cursor-not-allowed text-gray-300'
|
? 'cursor-not-allowed text-gray-300'
|
||||||
: ''
|
: '',
|
||||||
"
|
action.class,
|
||||||
|
]"
|
||||||
|
:style="action.style"
|
||||||
>
|
>
|
||||||
<Icon v-if="action.icon" :icon="action.icon" />
|
<Icon v-if="action.icon" :icon="action.icon" />
|
||||||
<span class="ml-1">{{ action.text }}</span>
|
<span class="ml-1">{{ action.text }}</span>
|
||||||
@ -184,11 +186,13 @@ const handleMenuClick = (e: any) => {
|
|||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div
|
<div
|
||||||
:class="
|
:class="[
|
||||||
action.disabled === true
|
action.disabled === true
|
||||||
? 'cursor-not-allowed text-gray-300'
|
? 'cursor-not-allowed text-gray-300'
|
||||||
: ''
|
: '',
|
||||||
"
|
action.class,
|
||||||
|
]"
|
||||||
|
:style="action.style"
|
||||||
>
|
>
|
||||||
<Icon v-if="action.icon" :icon="action.icon" />
|
<Icon v-if="action.icon" :icon="action.icon" />
|
||||||
{{ action.label }}
|
{{ action.label }}
|
||||||
|
|||||||
@ -1,10 +1,21 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { nextTick, ref } from 'vue';
|
||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal, z } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import { message as Message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { postDeviceThingModelManagementCommandPageAsync } from '#/api-client';
|
import {
|
||||||
|
postDeviceThingModelManagementCommandCreateAsync,
|
||||||
|
postDeviceThingModelManagementCommandDeleteAsync,
|
||||||
|
postDeviceThingModelManagementCommandFindByIdAsync,
|
||||||
|
postDeviceThingModelManagementCommandPageAsync,
|
||||||
|
postDeviceThingModelManagementCommandUpdateAsync,
|
||||||
|
postDeviceThingModelManagementPropertyPageAsync,
|
||||||
|
} from '#/api-client';
|
||||||
|
import { TableAction } from '#/components/table-action';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -14,6 +25,10 @@ defineOptions({
|
|||||||
const deviceThingModelId = ref<string>('');
|
const deviceThingModelId = ref<string>('');
|
||||||
const deviceModelName = ref<string>('');
|
const deviceModelName = ref<string>('');
|
||||||
|
|
||||||
|
const editRow: Record<string, any> = ref({});
|
||||||
|
const propertyOptions = ref<Array<{ label: string; value: string }>>([]);
|
||||||
|
|
||||||
|
// 指令列表
|
||||||
const [Grid, gridApi] = useVbenVxeGrid({
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
formOptions: {
|
formOptions: {
|
||||||
schema: [],
|
schema: [],
|
||||||
@ -28,11 +43,33 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
showOverflow: 'tooltip',
|
showOverflow: 'tooltip',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'identifier',
|
field: 'issueCommand',
|
||||||
title: '标识符',
|
title: '下发指令',
|
||||||
minWidth: 140,
|
minWidth: 200,
|
||||||
showOverflow: 'tooltip',
|
showOverflow: 'tooltip',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'propertyArray',
|
||||||
|
title: '属性标识符集合',
|
||||||
|
minWidth: 200,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
formatter: ({ cellValue }: { cellValue: any }) => {
|
||||||
|
if (Array.isArray(cellValue)) {
|
||||||
|
return cellValue.join(', ');
|
||||||
|
}
|
||||||
|
if (typeof cellValue === 'string') {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(cellValue);
|
||||||
|
if (Array.isArray(parsed)) {
|
||||||
|
return parsed.join(', ');
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return cellValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cellValue || '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'action',
|
field: 'action',
|
||||||
title: $t('common.action'),
|
title: $t('common.action'),
|
||||||
@ -43,6 +80,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
],
|
],
|
||||||
height: 400,
|
height: 400,
|
||||||
pagerConfig: {},
|
pagerConfig: {},
|
||||||
|
toolbarConfig: {
|
||||||
|
custom: true,
|
||||||
|
},
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
query: async ({ page }) => {
|
query: async ({ page }) => {
|
||||||
@ -63,15 +103,234 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 指令新增/编辑弹窗
|
||||||
|
const [CommandFormModal, commandFormModalApi] = useVbenModal({
|
||||||
|
draggable: true,
|
||||||
|
footer: true,
|
||||||
|
showCancelButton: true,
|
||||||
|
showConfirmButton: true,
|
||||||
|
onConfirm: submitCommand,
|
||||||
|
onBeforeClose: () => {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
onOpenChange: async (isOpen: boolean) => {
|
||||||
|
if (isOpen) {
|
||||||
|
// 加载当前设备端物模型的属性列表,用于选择属性标识符
|
||||||
|
await loadPropertyOptions();
|
||||||
|
if (editRow.value.id) {
|
||||||
|
// 编辑模式下,加载指令详情
|
||||||
|
nextTick(async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await postDeviceThingModelManagementCommandFindByIdAsync({
|
||||||
|
body: { id: editRow.value.id },
|
||||||
|
});
|
||||||
|
if (data) {
|
||||||
|
const values: any = { ...data };
|
||||||
|
// 处理 propertyArray 字段
|
||||||
|
if (values.propertyArray) {
|
||||||
|
if (typeof values.propertyArray === 'string') {
|
||||||
|
try {
|
||||||
|
values.propertyArray = JSON.parse(values.propertyArray);
|
||||||
|
} catch {
|
||||||
|
values.propertyArray = [values.propertyArray];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!Array.isArray(values.propertyArray)) {
|
||||||
|
values.propertyArray = [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
values.propertyArray = [];
|
||||||
|
}
|
||||||
|
commandFormApi.setValues(values);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载指令详情失败:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 新增模式下,清空表单
|
||||||
|
commandFormApi.resetForm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onCancel: () => {
|
||||||
|
commandFormModalApi.close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 加载属性选项(用于指令的属性标识符选择)
|
||||||
|
async function loadPropertyOptions() {
|
||||||
|
if (!deviceThingModelId.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const { data } = await postDeviceThingModelManagementPropertyPageAsync({
|
||||||
|
body: {
|
||||||
|
pageIndex: 1,
|
||||||
|
pageSize: 1000,
|
||||||
|
deviceThingModelId: deviceThingModelId.value,
|
||||||
|
isPage:false
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const items = data?.items || [];
|
||||||
|
propertyOptions.value = items.map((item: any) => ({
|
||||||
|
label: `${item.standardFieldDisplayName || item.standardFieldName} (${item.standardFieldName})`,
|
||||||
|
value: item.standardFieldName || '',
|
||||||
|
}));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载属性列表失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 指令表单
|
||||||
|
const [CommandForm, commandFormApi] = useVbenForm({
|
||||||
|
collapsed: false,
|
||||||
|
commonConfig: {
|
||||||
|
labelWidth: 140,
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-4/5',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
layout: 'horizontal',
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'commandName',
|
||||||
|
label: '指令名称',
|
||||||
|
rules: z
|
||||||
|
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: $t('common.pleaseInput') + '指令名称',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Textarea',
|
||||||
|
fieldName: 'issueCommand',
|
||||||
|
label: '下发指令',
|
||||||
|
rules: z
|
||||||
|
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
||||||
|
componentProps: {
|
||||||
|
rows: 4,
|
||||||
|
placeholder: $t('common.pleaseInput') + '下发指令(完整的单个下发指令)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
fieldName: 'propertyArray',
|
||||||
|
label: '属性标识符集合',
|
||||||
|
rules: z
|
||||||
|
.preprocess((v) => (v == null ? [] : v), z.array(z.string()).min(1, '请至少选择一个属性标识符')),
|
||||||
|
// 使用函数形式,保证 options 能随着 propertyOptions 的变化而更新
|
||||||
|
componentProps: () => ({
|
||||||
|
mode: 'multiple',
|
||||||
|
placeholder: '请选择属性标识符',
|
||||||
|
options: propertyOptions.value,
|
||||||
|
showSearch: true,
|
||||||
|
filterOption: (input: string, option: any) => {
|
||||||
|
return String(option.label)
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(input.toLowerCase());
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
showCollapseButton: false,
|
||||||
|
showDefaultActions: false,
|
||||||
|
wrapperClass: 'grid-cols-1',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 打开新增指令弹窗
|
||||||
|
function openAddCommandModal() {
|
||||||
|
editRow.value = {};
|
||||||
|
commandFormModalApi.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开编辑指令弹窗
|
||||||
|
function openEditCommandModal(record: any) {
|
||||||
|
editRow.value = record;
|
||||||
|
commandFormModalApi.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交指令(新增/编辑)
|
||||||
|
async function submitCommand() {
|
||||||
|
const isEdit = !!editRow.value.id;
|
||||||
|
const { valid } = await commandFormApi.validate();
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
const formValues = await commandFormApi.getValues();
|
||||||
|
const fetchParams: any = {
|
||||||
|
...formValues,
|
||||||
|
deviceThingModelId: deviceThingModelId.value,
|
||||||
|
// 确保 propertyArray 是数组格式
|
||||||
|
propertyArray: Array.isArray(formValues.propertyArray)
|
||||||
|
? formValues.propertyArray
|
||||||
|
: formValues.propertyArray
|
||||||
|
? [formValues.propertyArray]
|
||||||
|
: [],
|
||||||
|
...(isEdit && { id: editRow.value.id }),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const api = isEdit
|
||||||
|
? postDeviceThingModelManagementCommandUpdateAsync
|
||||||
|
: postDeviceThingModelManagementCommandCreateAsync;
|
||||||
|
const resp = await api({ body: fetchParams });
|
||||||
|
if (resp.data) {
|
||||||
|
Message.success(
|
||||||
|
isEdit ? $t('common.editSuccess') : $t('common.addSuccess'),
|
||||||
|
);
|
||||||
|
commandFormModalApi.close();
|
||||||
|
editRow.value = {};
|
||||||
|
await nextTick();
|
||||||
|
if (gridApi && gridApi.reload) {
|
||||||
|
await gridApi.reload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Message.error(
|
||||||
|
isEdit ? $t('common.editFail') : $t('common.addFail'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('提交指令失败:', error);
|
||||||
|
Message.error(
|
||||||
|
isEdit ? $t('common.editFail') : $t('common.addFail'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除指令
|
||||||
|
async function onDeleteCommand(record: any) {
|
||||||
|
try {
|
||||||
|
const resp = await postDeviceThingModelManagementCommandDeleteAsync({
|
||||||
|
body: { id: record.id },
|
||||||
|
});
|
||||||
|
if (resp.data) {
|
||||||
|
Message.success($t('common.deleteSuccess'));
|
||||||
|
await nextTick();
|
||||||
|
if (gridApi && gridApi.reload) {
|
||||||
|
await gridApi.reload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Message.error($t('common.deleteFail'));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除指令失败:', error);
|
||||||
|
Message.error($t('common.deleteFail'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
onOpenChange(isOpen: boolean) {
|
onOpenChange(isOpen: boolean) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
const data = modalApi.getData<Record<string, any>>();
|
const data = modalApi.getData<Record<string, any>>();
|
||||||
deviceThingModelId.value = data?.deviceThingModelId || '';
|
deviceThingModelId.value = data?.deviceThingModelId || '';
|
||||||
deviceModelName.value = data?.deviceModelName || '';
|
deviceModelName.value = data?.deviceModelName || '';
|
||||||
if (gridApi && gridApi.reload) {
|
// 使用 nextTick 确保 Grid 组件已完全初始化
|
||||||
gridApi.reload();
|
nextTick(() => {
|
||||||
}
|
if (gridApi && gridApi.reload) {
|
||||||
|
gridApi.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -80,9 +339,52 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
<template>
|
<template>
|
||||||
<Modal :title="`指令管理 - ${deviceModelName || ''}`" class="w-[900px]">
|
<Modal :title="`指令管理 - ${deviceModelName || ''}`" class="w-[900px]">
|
||||||
<Grid>
|
<Grid>
|
||||||
<!-- 这里后续可以加 toolbar-actions:新增指令、编辑、删除等 -->
|
<template #toolbar-actions>
|
||||||
|
<TableAction
|
||||||
|
:actions="[
|
||||||
|
{
|
||||||
|
label: $t('common.add'),
|
||||||
|
type: 'primary',
|
||||||
|
icon: 'ant-design:plus-outlined',
|
||||||
|
onClick: openAddCommandModal,
|
||||||
|
auth: ['AbpIdentity.Users.Create'],
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #action="{ row }">
|
||||||
|
<TableAction
|
||||||
|
:actions="[
|
||||||
|
{
|
||||||
|
label: $t('common.edit'),
|
||||||
|
type: 'link',
|
||||||
|
size: 'small',
|
||||||
|
auth: ['AbpIdentity.Users.Update'],
|
||||||
|
onClick: openEditCommandModal.bind(null, row),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: $t('common.delete'),
|
||||||
|
icon: 'ant-design:delete-outlined',
|
||||||
|
type: 'link',
|
||||||
|
size: 'small',
|
||||||
|
auth: ['AbpIdentity.Users.Delete'],
|
||||||
|
popConfirm: {
|
||||||
|
title: $t('common.askConfirmDelete'),
|
||||||
|
confirm: onDeleteCommand.bind(null, row),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<!-- 指令新增/编辑弹窗 -->
|
||||||
|
<CommandFormModal
|
||||||
|
:title="editRow.id ? $t('common.edit') : $t('common.add')"
|
||||||
|
class="w-[800px]"
|
||||||
|
>
|
||||||
|
<CommandForm />
|
||||||
|
</CommandFormModal>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,25 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { computed, nextTick, ref, watch } from 'vue';
|
||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal, z } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import { message as Message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { postDeviceThingModelManagementPropertyPageAsync } from '#/api-client';
|
import {
|
||||||
|
getCommonGetSelectList,
|
||||||
|
postAggregationIoTplatformGetIoTplatformProductInfoAsync,
|
||||||
|
postDeviceThingModelManagementCopyAnotherDeviceThingModelAsync,
|
||||||
|
postDeviceThingModelManagementCopyIoTplatformThingModelToDeviceAsync,
|
||||||
|
postDeviceThingModelManagementPageAsync,
|
||||||
|
postDeviceThingModelManagementPropertyCreateAsync,
|
||||||
|
postDeviceThingModelManagementPropertyDeleteAsync,
|
||||||
|
postDeviceThingModelManagementPropertyFindByIdAsync,
|
||||||
|
postDeviceThingModelManagementPropertyPageAsync,
|
||||||
|
postDeviceThingModelManagementPropertyUpdateAsync,
|
||||||
|
} from '#/api-client';
|
||||||
|
import { TableAction } from '#/components/table-action';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -13,7 +28,12 @@ defineOptions({
|
|||||||
|
|
||||||
const deviceThingModelId = ref<string>('');
|
const deviceThingModelId = ref<string>('');
|
||||||
const deviceModelName = ref<string>('');
|
const deviceModelName = ref<string>('');
|
||||||
|
const ioTPlatform = ref<number | string>('');
|
||||||
|
const ioTPlatformProductId = ref<string>('');
|
||||||
|
|
||||||
|
const editRow: Record<string, any> = ref({});
|
||||||
|
|
||||||
|
// 属性列表
|
||||||
const [Grid, gridApi] = useVbenVxeGrid({
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
formOptions: {
|
formOptions: {
|
||||||
schema: [],
|
schema: [],
|
||||||
@ -22,21 +42,83 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
field: 'propertyName',
|
field: 'filedType',
|
||||||
title: '属性名称',
|
title: '物模型类型',
|
||||||
minWidth: 160,
|
minWidth: 160,
|
||||||
showOverflow: 'tooltip',
|
showOverflow: 'tooltip',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'identifier',
|
field: 'standardFieldDisplayName',
|
||||||
title: '标识符',
|
title: '标准属性名称',
|
||||||
|
minWidth: 160,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'standardFieldName',
|
||||||
|
title: '标准属性标识符',
|
||||||
|
minWidth: 160,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'standardFieldValueType',
|
||||||
|
title: '标准属性值类型',
|
||||||
|
minWidth: 160,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'ioTPlatformRawFieldName',
|
||||||
|
title: '平台属性标识符',
|
||||||
|
minWidth: 160,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'ioTPlatformRawFieldDataType',
|
||||||
|
title: '平台属性值类型',
|
||||||
|
minWidth: 160,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'isValueNeedConvert',
|
||||||
|
title: '值类型是否转换',
|
||||||
|
minWidth: 120,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
formatter: ({ cellValue }: { cellValue: any }) => {
|
||||||
|
return cellValue ? '是' : '否';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'parsingSequence',
|
||||||
|
title: '解析方式',
|
||||||
|
minWidth: 140,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
formatter: ({ cellValue }: { cellValue: any }) => {
|
||||||
|
if (cellValue === 1) return '正序';
|
||||||
|
if (cellValue === 2) return '高低位反转';
|
||||||
|
return cellValue ?? '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'nativeSkipNumber',
|
||||||
|
title: '正序跳过数量',
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
showOverflow: 'tooltip',
|
showOverflow: 'tooltip',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'dataType',
|
field: 'nativeTakeNumber',
|
||||||
title: '数据类型',
|
title: '正序获取数量',
|
||||||
minWidth: 120,
|
minWidth: 140,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'reversalSkipNumber',
|
||||||
|
title: '反转跳过数量',
|
||||||
|
minWidth: 140,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'reversalTakeNumber',
|
||||||
|
title: '反转获取数量',
|
||||||
|
minWidth: 140,
|
||||||
showOverflow: 'tooltip',
|
showOverflow: 'tooltip',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -49,19 +131,23 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
],
|
],
|
||||||
height: 400,
|
height: 400,
|
||||||
pagerConfig: {},
|
pagerConfig: {},
|
||||||
|
toolbarConfig: {
|
||||||
|
custom: true,
|
||||||
|
},
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
query: async ({ page }) => {
|
query: async ({ page }) => {
|
||||||
if (!deviceThingModelId.value) {
|
if (!deviceThingModelId.value) {
|
||||||
return { items: [], totalCount: 0 };
|
return { items: [], totalCount: 0 };
|
||||||
}
|
}
|
||||||
const { data } = await postDeviceThingModelManagementPropertyPageAsync({
|
const { data } =
|
||||||
body: {
|
await postDeviceThingModelManagementPropertyPageAsync({
|
||||||
pageIndex: page.currentPage,
|
body: {
|
||||||
pageSize: page.pageSize,
|
pageIndex: page.currentPage,
|
||||||
deviceThingModelId: deviceThingModelId.value,
|
pageSize: page.pageSize,
|
||||||
},
|
deviceThingModelId: deviceThingModelId.value,
|
||||||
});
|
},
|
||||||
|
});
|
||||||
return data || { items: [], totalCount: 0 };
|
return data || { items: [], totalCount: 0 };
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -69,26 +155,691 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 属性新增/编辑弹窗
|
||||||
|
const [PropertyFormModal, propertyFormModalApi] = useVbenModal({
|
||||||
|
draggable: true,
|
||||||
|
footer: true,
|
||||||
|
showCancelButton: true,
|
||||||
|
showConfirmButton: true,
|
||||||
|
onConfirm: submitProperty,
|
||||||
|
onBeforeClose: () => {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
onOpenChange: (isOpen: boolean) => {
|
||||||
|
if (isOpen && editRow.value.id) {
|
||||||
|
// 编辑模式下,加载属性详情
|
||||||
|
nextTick(async () => {
|
||||||
|
try {
|
||||||
|
const { data } =
|
||||||
|
await postDeviceThingModelManagementPropertyFindByIdAsync({
|
||||||
|
body: { id: editRow.value.id },
|
||||||
|
});
|
||||||
|
if (data) {
|
||||||
|
const values: any = { ...data };
|
||||||
|
// 处理解析方式字段(从后端获取的可能是数字,需要转换成字符串)
|
||||||
|
if (
|
||||||
|
values.parsingSequence !== undefined &&
|
||||||
|
values.parsingSequence !== null
|
||||||
|
) {
|
||||||
|
// 如果后端返回的是数字,转换为字符串;如果已经是字符串,保持原样
|
||||||
|
values.parsingSequence = String(values.parsingSequence);
|
||||||
|
}
|
||||||
|
propertyFormApi.setValues(values);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载属性详情失败:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (isOpen) {
|
||||||
|
// 新增模式下,清空表单
|
||||||
|
propertyFormApi.resetForm();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onCancel: () => {
|
||||||
|
propertyFormModalApi.close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 快速复制平台端物模型属性弹窗
|
||||||
|
const [CopyPropertyModal, copyPropertyModalApi] = useVbenModal({
|
||||||
|
draggable: true,
|
||||||
|
footer: true,
|
||||||
|
showCancelButton: true,
|
||||||
|
showConfirmButton: true,
|
||||||
|
onConfirm: submitCopyProperty,
|
||||||
|
onBeforeClose: () => {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
onCancel: () => {
|
||||||
|
copyPropertyModalApi.close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 快速复制设备端物模型弹窗
|
||||||
|
const [CopyDeviceThingModelModal, copyDeviceThingModelModalApi] = useVbenModal({
|
||||||
|
draggable: true,
|
||||||
|
footer: true,
|
||||||
|
showCancelButton: true,
|
||||||
|
showConfirmButton: true,
|
||||||
|
onConfirm: submitCopyDeviceThingModel,
|
||||||
|
onBeforeClose: () => {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
onCancel: () => {
|
||||||
|
copyDeviceThingModelModalApi.close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 属性表单 schema
|
||||||
|
const propertyFormSchema = computed(() => {
|
||||||
|
const isEdit = !!editRow.value.id;
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'standardFieldDisplayName',
|
||||||
|
label: '标准属性名称',
|
||||||
|
rules: z.preprocess(
|
||||||
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: `${$t('common.pleaseInput')}标准属性名称`,
|
||||||
|
disabled: isEdit, // 编辑模式下禁用
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'standardFieldName',
|
||||||
|
label: '标准属性标识符',
|
||||||
|
rules: z.preprocess(
|
||||||
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: `${$t('common.pleaseInput')}标准属性标识符`,
|
||||||
|
disabled: isEdit, // 编辑模式下禁用
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'ApiSelect',
|
||||||
|
fieldName: 'standardFieldValueType',
|
||||||
|
label: '标准属性值类型',
|
||||||
|
rules: z.preprocess(
|
||||||
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
|
componentProps: {
|
||||||
|
api: getCommonGetSelectList,
|
||||||
|
params: {
|
||||||
|
query: {
|
||||||
|
typeName: 'StandardThingModelDataTypeEnum',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
labelField: 'value',
|
||||||
|
valueField: 'secondValue',
|
||||||
|
optionsPropName: 'options',
|
||||||
|
immediate: true,
|
||||||
|
allowClear: true,
|
||||||
|
disabled: isEdit, // 编辑模式下禁用
|
||||||
|
placeholder: `${$t('common.pleaseSelect')}标准属性值类型`,
|
||||||
|
afterFetch: (res: any) => {
|
||||||
|
if (Array.isArray(res)) return res;
|
||||||
|
if (res && Array.isArray(res.items)) return res.items;
|
||||||
|
if (res && Array.isArray(res.data)) return res.data;
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'ioTPlatformRawFieldName',
|
||||||
|
label: '平台属性标识符',
|
||||||
|
rules: z.preprocess(
|
||||||
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: `${$t('common.pleaseInput')}平台属性标识符`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'ApiSelect',
|
||||||
|
fieldName: 'ioTPlatformRawFieldDataType',
|
||||||
|
label: '平台属性值类型',
|
||||||
|
rules: z.preprocess(
|
||||||
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
|
componentProps: {
|
||||||
|
api: getCommonGetSelectList,
|
||||||
|
params: {
|
||||||
|
query: {
|
||||||
|
typeName: 'StandardThingModelDataTypeEnum',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
labelField: 'value',
|
||||||
|
valueField: 'secondValue',
|
||||||
|
optionsPropName: 'options',
|
||||||
|
immediate: true,
|
||||||
|
allowClear: true,
|
||||||
|
placeholder: `${$t('common.pleaseSelect')}平台属性值类型`,
|
||||||
|
afterFetch: (res: any) => {
|
||||||
|
if (Array.isArray(res)) return res;
|
||||||
|
if (res && Array.isArray(res.items)) return res.items;
|
||||||
|
if (res && Array.isArray(res.data)) return res.data;
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Switch',
|
||||||
|
fieldName: 'isValueNeedConvert',
|
||||||
|
label: '值类型是否转换',
|
||||||
|
componentProps: {
|
||||||
|
checkedChildren: '是',
|
||||||
|
unCheckedChildren: '否',
|
||||||
|
style: { width: 'auto' }, // 优化宽度显示
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'ApiSelect',
|
||||||
|
fieldName: 'parsingSequence',
|
||||||
|
label: '解析方式',
|
||||||
|
componentProps: {
|
||||||
|
api: getCommonGetSelectList,
|
||||||
|
params: {
|
||||||
|
query: {
|
||||||
|
typeName: 'ParsingSequenceTypeEnum',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
labelField: 'value',
|
||||||
|
valueField: 'key',
|
||||||
|
optionsPropName: 'options',
|
||||||
|
immediate: true,
|
||||||
|
allowClear: true,
|
||||||
|
placeholder: `${$t('common.pleaseSelect')}解析方式`,
|
||||||
|
afterFetch: (res: any) => {
|
||||||
|
let items = [];
|
||||||
|
if (Array.isArray(res)) {
|
||||||
|
items = res;
|
||||||
|
} else if (res && Array.isArray(res.items)) {
|
||||||
|
items = res.items;
|
||||||
|
} else if (res && Array.isArray(res.data)) {
|
||||||
|
items = res.data;
|
||||||
|
}
|
||||||
|
// 将 key 转换为字符串,因为表单需要字符串类型
|
||||||
|
return items.map((item: any) => ({
|
||||||
|
...item,
|
||||||
|
key: String(item.key || item.value),
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'InputNumber',
|
||||||
|
fieldName: 'nativeSkipNumber',
|
||||||
|
label: '正序跳过数量',
|
||||||
|
componentProps: {
|
||||||
|
min: 0,
|
||||||
|
placeholder: `${$t('common.pleaseInput')}正序跳过数量`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'InputNumber',
|
||||||
|
fieldName: 'nativeTakeNumber',
|
||||||
|
label: '正序获取数量',
|
||||||
|
componentProps: {
|
||||||
|
min: 0,
|
||||||
|
placeholder: `${$t('common.pleaseInput')}正序获取数量`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'InputNumber',
|
||||||
|
fieldName: 'reversalSkipNumber',
|
||||||
|
label: '反转跳过数量',
|
||||||
|
componentProps: {
|
||||||
|
min: 0,
|
||||||
|
placeholder: `${$t('common.pleaseInput')}反转跳过数量`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'InputNumber',
|
||||||
|
fieldName: 'reversalTakeNumber',
|
||||||
|
label: '反转获取数量',
|
||||||
|
componentProps: {
|
||||||
|
min: 0,
|
||||||
|
placeholder: `${$t('common.pleaseInput')}反转获取数量`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
// 属性表单
|
||||||
|
const [PropertyForm, propertyFormApi] = useVbenForm({
|
||||||
|
collapsed: false,
|
||||||
|
commonConfig: {
|
||||||
|
labelWidth: 140,
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-4/5',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
layout: 'horizontal',
|
||||||
|
schema: propertyFormSchema.value,
|
||||||
|
showCollapseButton: false,
|
||||||
|
showDefaultActions: false,
|
||||||
|
wrapperClass: 'grid-cols-2',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听 editRow 变化,动态更新 schema
|
||||||
|
watch(
|
||||||
|
() => editRow.value.id,
|
||||||
|
() => {
|
||||||
|
if (propertyFormApi && propertyFormApi.updateSchema) {
|
||||||
|
propertyFormApi.updateSchema(propertyFormSchema.value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// 快速复制表单(选择平台和产品)
|
||||||
|
const [CopyPropertyForm, copyPropertyFormApi] = useVbenForm({
|
||||||
|
collapsed: false,
|
||||||
|
commonConfig: {
|
||||||
|
labelWidth: 140,
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-4/5',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
layout: 'horizontal',
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'ApiSelect',
|
||||||
|
fieldName: 'ioTPlatform',
|
||||||
|
label: $t('abp.deviceInfos.ioTPlatform'),
|
||||||
|
rules: z.preprocess(
|
||||||
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
|
componentProps: {
|
||||||
|
api: getCommonGetSelectList,
|
||||||
|
params: {
|
||||||
|
query: {
|
||||||
|
typeName: 'IoTPlatformTypeEnum',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
labelField: 'value',
|
||||||
|
valueField: 'key',
|
||||||
|
optionsPropName: 'options',
|
||||||
|
immediate: true,
|
||||||
|
allowClear: true,
|
||||||
|
placeholder:
|
||||||
|
$t('common.pleaseSelect') + $t('abp.deviceInfos.ioTPlatform'),
|
||||||
|
afterFetch: (res: any) => {
|
||||||
|
if (Array.isArray(res)) return res;
|
||||||
|
if (res && Array.isArray(res.items)) return res.items;
|
||||||
|
if (res && Array.isArray(res.data)) return res.data;
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'ApiSelect',
|
||||||
|
fieldName: 'ioTPlatformProductId',
|
||||||
|
label: $t('common.BelongingProductName'),
|
||||||
|
rules: z.preprocess(
|
||||||
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
|
dependencies: {
|
||||||
|
show(values: any) {
|
||||||
|
return !!values.ioTPlatform;
|
||||||
|
},
|
||||||
|
triggerFields: ['ioTPlatform'],
|
||||||
|
},
|
||||||
|
componentProps: (formValues: any) => {
|
||||||
|
const platform = formValues?.ioTPlatform;
|
||||||
|
|
||||||
|
return {
|
||||||
|
api: platform
|
||||||
|
? postAggregationIoTplatformGetIoTplatformProductInfoAsync
|
||||||
|
: null,
|
||||||
|
params: {
|
||||||
|
body: {
|
||||||
|
ioTPlatformType:
|
||||||
|
typeof platform === 'string'
|
||||||
|
? Number.parseInt(platform)
|
||||||
|
: platform,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
labelField: 'productName',
|
||||||
|
valueField: 'ioTPlatformProductId',
|
||||||
|
optionsPropName: 'options',
|
||||||
|
immediate: false,
|
||||||
|
allowClear: true,
|
||||||
|
placeholder:
|
||||||
|
$t('common.pleaseSelect') + $t('common.BelongingProductName'),
|
||||||
|
afterFetch: (res: any) => {
|
||||||
|
if (Array.isArray(res)) return res;
|
||||||
|
if (res && Array.isArray(res.items)) return res.items;
|
||||||
|
if (res && Array.isArray(res.data)) return res.data;
|
||||||
|
if (res && res.data && Array.isArray(res.data.items)) {
|
||||||
|
return res.data.items;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
showCollapseButton: false,
|
||||||
|
showDefaultActions: false,
|
||||||
|
wrapperClass: 'grid-cols-2',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 快速复制设备端物模型表单
|
||||||
|
const [CopyDeviceThingModelForm, copyDeviceThingModelFormApi] = useVbenForm({
|
||||||
|
collapsed: false,
|
||||||
|
commonConfig: {
|
||||||
|
labelWidth: 140,
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-4/5',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
layout: 'horizontal',
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'ApiSelect',
|
||||||
|
fieldName: 'sourceDeviceThingModelId',
|
||||||
|
label: '选择设备端物模型',
|
||||||
|
rules: z.preprocess(
|
||||||
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
|
componentProps: {
|
||||||
|
api: postDeviceThingModelManagementPageAsync,
|
||||||
|
params: {
|
||||||
|
body: {
|
||||||
|
pageIndex: 1,
|
||||||
|
pageSize: 1000,
|
||||||
|
isPage: false, // 不分页,获取全部数据
|
||||||
|
},
|
||||||
|
},
|
||||||
|
labelField: 'deviceModelName',
|
||||||
|
valueField: 'id',
|
||||||
|
optionsPropName: 'options',
|
||||||
|
immediate: true,
|
||||||
|
allowClear: true,
|
||||||
|
placeholder: '请选择要复制的设备端物模型',
|
||||||
|
afterFetch: (res: any) => {
|
||||||
|
if (Array.isArray(res)) return res;
|
||||||
|
if (res && Array.isArray(res.items)) return res.items;
|
||||||
|
if (res && Array.isArray(res.data)) return res.data;
|
||||||
|
if (res && res.data && Array.isArray(res.data.items)) {
|
||||||
|
return res.data.items;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
showCollapseButton: false,
|
||||||
|
showDefaultActions: false,
|
||||||
|
wrapperClass: 'grid-cols-1',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 打开新增属性弹窗
|
||||||
|
function openAddPropertyModal() {
|
||||||
|
editRow.value = {};
|
||||||
|
propertyFormModalApi.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开编辑属性弹窗
|
||||||
|
function openEditPropertyModal(record: any) {
|
||||||
|
editRow.value = record;
|
||||||
|
propertyFormModalApi.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开快速复制平台端物模型弹窗
|
||||||
|
function openCopyPropertyModal() {
|
||||||
|
copyPropertyFormApi.resetForm();
|
||||||
|
copyPropertyModalApi.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开快速复制设备端物模型弹窗
|
||||||
|
function openCopyDeviceThingModelModal() {
|
||||||
|
copyDeviceThingModelFormApi.resetForm();
|
||||||
|
copyDeviceThingModelModalApi.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交属性(新增/编辑)
|
||||||
|
async function submitProperty() {
|
||||||
|
const isEdit = !!editRow.value.id;
|
||||||
|
const { valid } = await propertyFormApi.validate();
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
const formValues = await propertyFormApi.getValues();
|
||||||
|
const fetchParams: any = {
|
||||||
|
...formValues,
|
||||||
|
deviceThingModelId: deviceThingModelId.value,
|
||||||
|
...(formValues.parsingSequence && {
|
||||||
|
// 解析方式从字符串转换为数字
|
||||||
|
parsingSequence: Number.parseInt(String(formValues.parsingSequence)),
|
||||||
|
}),
|
||||||
|
...(isEdit && { id: editRow.value.id }),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const api = isEdit
|
||||||
|
? postDeviceThingModelManagementPropertyUpdateAsync
|
||||||
|
: postDeviceThingModelManagementPropertyCreateAsync;
|
||||||
|
const resp = await api({ body: fetchParams });
|
||||||
|
if (resp.data) {
|
||||||
|
Message.success(
|
||||||
|
isEdit ? $t('common.editSuccess') : $t('common.addSuccess'),
|
||||||
|
);
|
||||||
|
propertyFormModalApi.close();
|
||||||
|
editRow.value = {};
|
||||||
|
await nextTick();
|
||||||
|
if (gridApi && gridApi.reload) {
|
||||||
|
await gridApi.reload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Message.error(isEdit ? $t('common.editFail') : $t('common.addFail'));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('提交属性失败:', error);
|
||||||
|
Message.error(isEdit ? $t('common.editFail') : $t('common.addFail'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交快速复制设备端物模型
|
||||||
|
async function submitCopyDeviceThingModel() {
|
||||||
|
const { valid } = await copyDeviceThingModelFormApi.validate();
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
const formValues = await copyDeviceThingModelFormApi.getValues();
|
||||||
|
|
||||||
|
if (!formValues.sourceDeviceThingModelId) {
|
||||||
|
Message.warning('请选择要复制的设备端物模型');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resp =
|
||||||
|
await postDeviceThingModelManagementCopyAnotherDeviceThingModelAsync({
|
||||||
|
body: {
|
||||||
|
ioTPlatform: Number.parseInt(String(ioTPlatform.value)) as 1 | 2,
|
||||||
|
deviceThingModelId: deviceThingModelId.value,
|
||||||
|
sourceProductId: formValues.sourceDeviceThingModelId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (resp.data) {
|
||||||
|
Message.success('快速复制设备端物模型属性成功');
|
||||||
|
copyDeviceThingModelModalApi.close();
|
||||||
|
await nextTick();
|
||||||
|
if (gridApi && gridApi.reload) {
|
||||||
|
await gridApi.reload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Message.error('快速复制设备端物模型属性失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('快速复制设备端物模型属性失败:', error);
|
||||||
|
Message.error('快速复制设备端物模型属性失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交快速复制平台端物模型
|
||||||
|
async function submitCopyProperty() {
|
||||||
|
const { valid } = await copyPropertyFormApi.validate();
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
const formValues = await copyPropertyFormApi.getValues();
|
||||||
|
|
||||||
|
if (!formValues.ioTPlatform || !formValues.ioTPlatformProductId) {
|
||||||
|
Message.warning('请选择平台和产品');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resp =
|
||||||
|
await postDeviceThingModelManagementCopyIoTplatformThingModelToDeviceAsync(
|
||||||
|
{
|
||||||
|
body: {
|
||||||
|
ioTPlatform: Number.parseInt(String(formValues.ioTPlatform)) as
|
||||||
|
| 1
|
||||||
|
| 2,
|
||||||
|
ioTPlatformProductId: String(formValues.ioTPlatformProductId),
|
||||||
|
deviceThingModelId: deviceThingModelId.value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (resp.data) {
|
||||||
|
Message.success('快速复制平台端物模型属性成功');
|
||||||
|
copyPropertyModalApi.close();
|
||||||
|
await nextTick();
|
||||||
|
if (gridApi && gridApi.reload) {
|
||||||
|
await gridApi.reload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Message.error('快速复制平台端物模型属性失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('快速复制平台端物模型属性失败:', error);
|
||||||
|
Message.error('快速复制平台端物模型属性失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除属性
|
||||||
|
async function onDeleteProperty(record: any) {
|
||||||
|
try {
|
||||||
|
const resp = await postDeviceThingModelManagementPropertyDeleteAsync({
|
||||||
|
body: { id: record.id },
|
||||||
|
});
|
||||||
|
if (resp.data) {
|
||||||
|
Message.success($t('common.deleteSuccess'));
|
||||||
|
await nextTick();
|
||||||
|
if (gridApi && gridApi.reload) {
|
||||||
|
await gridApi.reload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Message.error($t('common.deleteFail'));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除属性失败:', error);
|
||||||
|
Message.error($t('common.deleteFail'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
onOpenChange(isOpen: boolean) {
|
onOpenChange(isOpen: boolean) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
const data = modalApi.getData<Record<string, any>>();
|
const data = modalApi.getData<Record<string, any>>();
|
||||||
deviceThingModelId.value = data?.deviceThingModelId || '';
|
deviceThingModelId.value = data?.deviceThingModelId || '';
|
||||||
deviceModelName.value = data?.deviceModelName || '';
|
deviceModelName.value = data?.deviceModelName || '';
|
||||||
if (gridApi && gridApi.reload) {
|
ioTPlatform.value = data?.ioTPlatform || '';
|
||||||
gridApi.reload();
|
ioTPlatformProductId.value = data?.ioTPlatformProductId || '';
|
||||||
}
|
// 使用 nextTick 确保 Grid 组件已完全初始化
|
||||||
|
nextTick(() => {
|
||||||
|
if (gridApi && gridApi.reload) {
|
||||||
|
gridApi.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal :title="`属性管理 - ${deviceModelName || ''}`" class="w-[900px]">
|
<Modal :title="`属性管理 - ${deviceModelName || ''}`" class="w-[1200px]">
|
||||||
<Grid>
|
<Grid>
|
||||||
<!-- 这里后续可以加 toolbar-actions:新增属性、快速复制平台端物模型 -->
|
<template #toolbar-actions>
|
||||||
|
<TableAction :actions="[
|
||||||
|
{
|
||||||
|
label: $t('common.add'),
|
||||||
|
type: 'primary',
|
||||||
|
icon: 'ant-design:plus-outlined',
|
||||||
|
onClick: openAddPropertyModal,
|
||||||
|
auth: ['AbpIdentity.Users.Create'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '快速复制平台端物模型',
|
||||||
|
type: 'default',
|
||||||
|
icon: 'ant-design:copy-outlined',
|
||||||
|
onClick: openCopyPropertyModal,
|
||||||
|
auth: ['AbpIdentity.Users.Create'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '快速复制设备端物模型',
|
||||||
|
type: 'default',
|
||||||
|
icon: 'ant-design:copy-outlined',
|
||||||
|
onClick: openCopyDeviceThingModelModal,
|
||||||
|
auth: ['AbpIdentity.Users.Create'],
|
||||||
|
},
|
||||||
|
]" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #action="{ row }">
|
||||||
|
<TableAction :actions="[
|
||||||
|
{
|
||||||
|
label: $t('common.edit'),
|
||||||
|
type: 'link',
|
||||||
|
size: 'small',
|
||||||
|
auth: ['AbpIdentity.Users.Update'],
|
||||||
|
onClick: openEditPropertyModal.bind(null, row),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: $t('common.delete'),
|
||||||
|
icon: 'ant-design:delete-outlined',
|
||||||
|
type: 'link',
|
||||||
|
size: 'small',
|
||||||
|
auth: ['AbpIdentity.Users.Delete'],
|
||||||
|
popConfirm: {
|
||||||
|
title: $t('common.askConfirmDelete'),
|
||||||
|
confirm: onDeleteProperty.bind(null, row),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]" />
|
||||||
|
</template>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<!-- 属性新增/编辑弹窗 -->
|
||||||
|
<PropertyFormModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[900px]">
|
||||||
|
<PropertyForm />
|
||||||
|
</PropertyFormModal>
|
||||||
|
|
||||||
|
<!-- 快速复制平台端物模型属性弹窗 -->
|
||||||
|
<CopyPropertyModal title="快速复制平台端物模型属性" class="w-[600px]">
|
||||||
|
<CopyPropertyForm />
|
||||||
|
</CopyPropertyModal>
|
||||||
|
|
||||||
|
<!-- 快速复制设备端物模型属性弹窗 -->
|
||||||
|
<CopyDeviceThingModelModal
|
||||||
|
title="快速复制设备端物模型属性"
|
||||||
|
class="w-[600px]"
|
||||||
|
>
|
||||||
|
<CopyDeviceThingModelForm />
|
||||||
|
</CopyDeviceThingModelModal>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,21 +5,27 @@ import type { VxeGridProps } from '#/adapter/vxe-table';
|
|||||||
import { h, nextTick, onMounted, ref } from 'vue';
|
import { h, nextTick, onMounted, ref } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
import { Page, useVbenModal, z } from '@vben/common-ui';
|
||||||
|
|
||||||
import { message as Message, Tag } from 'ant-design-vue';
|
import { Button, message as Message, Tag } from 'ant-design-vue';
|
||||||
|
|
||||||
import { useVbenForm } from '#/adapter/form';
|
import { useVbenForm } from '#/adapter/form';
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import {
|
import {
|
||||||
|
postDeviceThingModelManagementBuildAnalysisScriptAsync,
|
||||||
|
postDeviceThingModelManagementBuildAnalysisScriptByIdAsync,
|
||||||
postDeviceThingModelManagementCreateAsync,
|
postDeviceThingModelManagementCreateAsync,
|
||||||
postDeviceThingModelManagementDeleteAsync,
|
postDeviceThingModelManagementDeleteAsync,
|
||||||
|
postDeviceThingModelManagementMessageAnalysisTestAsync,
|
||||||
postDeviceThingModelManagementPageAsync,
|
postDeviceThingModelManagementPageAsync,
|
||||||
|
postDeviceThingModelManagementUpdateAnalysisScriptByIdAsync,
|
||||||
postDeviceThingModelManagementUpdateAsync,
|
postDeviceThingModelManagementUpdateAsync,
|
||||||
} from '#/api-client';
|
} from '#/api-client';
|
||||||
import { TableAction } from '#/components/table-action';
|
import { TableAction } from '#/components/table-action';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
|
import DeviceThingModelCommandModal from './DeviceThingModelCommandModal.vue';
|
||||||
|
import DeviceThingModelPropertyModal from './DeviceThingModelPropertyModal.vue';
|
||||||
import {
|
import {
|
||||||
addDeviceThingModelFormSchema,
|
addDeviceThingModelFormSchema,
|
||||||
editDeviceThingModelFormSchema,
|
editDeviceThingModelFormSchema,
|
||||||
@ -27,9 +33,6 @@ import {
|
|||||||
tableSchema,
|
tableSchema,
|
||||||
} from './schema';
|
} from './schema';
|
||||||
|
|
||||||
import DeviceThingModelPropertyModal from './DeviceThingModelPropertyModal.vue';
|
|
||||||
import DeviceThingModelCommandModal from './DeviceThingModelCommandModal.vue';
|
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'DeviceThingModelManagement',
|
name: 'DeviceThingModelManagement',
|
||||||
});
|
});
|
||||||
@ -53,25 +56,21 @@ const formOptions: VbenFormProps = {
|
|||||||
submitOnChange: false,
|
submitOnChange: false,
|
||||||
handleValuesChange: async (values, changedFields) => {
|
handleValuesChange: async (values, changedFields) => {
|
||||||
// 平台变化时,清空产品并更新状态
|
// 平台变化时,清空产品并更新状态
|
||||||
if (changedFields.includes('ioTPlatform')) {
|
if (changedFields.includes('ioTPlatform') && values.ioTPlatform) {
|
||||||
if (values.ioTPlatform) {
|
ioTPlatform.value = String(values.ioTPlatform);
|
||||||
ioTPlatform.value = String(values.ioTPlatform);
|
if (gridApi?.formApi) {
|
||||||
if (gridApi?.formApi) {
|
await gridApi.formApi.setValues({
|
||||||
await gridApi.formApi.setValues({
|
ioTPlatformProductId: undefined,
|
||||||
ioTPlatformProductId: undefined,
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
productId.value = '';
|
|
||||||
}
|
}
|
||||||
|
productId.value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 产品变化时,更新 productId 并刷新列表
|
// 产品变化时,更新 productId 并刷新列表
|
||||||
if (changedFields.includes('ioTPlatformProductId')) {
|
if (changedFields.includes('ioTPlatformProductId')) {
|
||||||
if (values.ioTPlatformProductId) {
|
productId.value = values.ioTPlatformProductId
|
||||||
productId.value = String(values.ioTPlatformProductId);
|
? String(values.ioTPlatformProductId)
|
||||||
} else {
|
: '';
|
||||||
productId.value = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
if (gridApi && gridApi.reload) {
|
if (gridApi && gridApi.reload) {
|
||||||
@ -119,9 +118,7 @@ const gridOptions: VxeGridProps<any> = {
|
|||||||
// 始终以最新的表单值为准,确保搜索关键字等字段不会丢失
|
// 始终以最新的表单值为准,确保搜索关键字等字段不会丢失
|
||||||
const latestFormValues =
|
const latestFormValues =
|
||||||
formValues ||
|
formValues ||
|
||||||
(gridApi && gridApi.formApi
|
(gridApi && gridApi.formApi ? await gridApi.formApi.getValues() : {});
|
||||||
? await gridApi.formApi.getValues()
|
|
||||||
: {});
|
|
||||||
|
|
||||||
// 优先使用表单值,如果没有则使用响应式变量
|
// 优先使用表单值,如果没有则使用响应式变量
|
||||||
const currentPlatform =
|
const currentPlatform =
|
||||||
@ -234,6 +231,80 @@ const [EditForm, editFormApi] = useVbenForm({
|
|||||||
wrapperClass: 'grid-cols-2',
|
wrapperClass: 'grid-cols-2',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 函数脚本测试弹窗
|
||||||
|
const [TestScriptModal, testScriptModalApi] = useVbenModal({
|
||||||
|
draggable: true,
|
||||||
|
footer: true,
|
||||||
|
showCancelButton: true,
|
||||||
|
showConfirmButton: true,
|
||||||
|
onConfirm: submitTestScript,
|
||||||
|
onBeforeClose: () => {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
onCancel: () => {
|
||||||
|
testScriptModalApi.close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 函数脚本测试表单
|
||||||
|
const [TestScriptForm, testScriptFormApi] = useVbenForm({
|
||||||
|
collapsed: false,
|
||||||
|
commonConfig: {
|
||||||
|
labelWidth: 110,
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-4/5',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
layout: 'horizontal',
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'functionName',
|
||||||
|
label: '函数名称',
|
||||||
|
rules: z.preprocess(
|
||||||
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: `${$t('common.pleaseInput')}函数名称`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Textarea',
|
||||||
|
fieldName: 'functionCode',
|
||||||
|
label: '函数代码',
|
||||||
|
rules: z.preprocess(
|
||||||
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
|
componentProps: {
|
||||||
|
rows: 8,
|
||||||
|
placeholder: `${$t('common.pleaseInput')}函数代码`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Textarea',
|
||||||
|
fieldName: 'parameters',
|
||||||
|
label: '函数参数(JSON格式)',
|
||||||
|
componentProps: {
|
||||||
|
rows: 6,
|
||||||
|
placeholder:
|
||||||
|
'请输入函数参数,JSON格式,例如:{"key1": "value1", "key2": "value2"}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
showCollapseButton: false,
|
||||||
|
showDefaultActions: false,
|
||||||
|
wrapperClass: 'grid-cols-1',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 测试结果
|
||||||
|
const testResult = ref<string>('');
|
||||||
|
|
||||||
|
// 当前测试关联的设备端物模型信息(可选)
|
||||||
|
const testDeviceThingModelId = ref<string>('');
|
||||||
|
const testDeviceModelName = ref<string>('');
|
||||||
|
|
||||||
// 新增 / 编辑提交
|
// 新增 / 编辑提交
|
||||||
async function submit() {
|
async function submit() {
|
||||||
const isEdit = !!editRow.value.id;
|
const isEdit = !!editRow.value.id;
|
||||||
@ -267,15 +338,11 @@ async function submit() {
|
|||||||
await gridApi.reload(latestValues);
|
await gridApi.reload(latestValues);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Message.error(
|
Message.error(isEdit ? $t('common.editFail') : $t('common.addFail'));
|
||||||
isEdit ? $t('common.editFail') : $t('common.addFail'),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('提交设备端物模型失败:', error);
|
console.error('提交设备端物模型失败:', error);
|
||||||
Message.error(
|
Message.error(isEdit ? $t('common.editFail') : $t('common.addFail'));
|
||||||
isEdit ? $t('common.editFail') : $t('common.addFail'),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,6 +357,8 @@ async function openPropertyModal(record: any) {
|
|||||||
propertyModalApi.setData({
|
propertyModalApi.setData({
|
||||||
deviceThingModelId: record.id,
|
deviceThingModelId: record.id,
|
||||||
deviceModelName: record.deviceModelName,
|
deviceModelName: record.deviceModelName,
|
||||||
|
ioTPlatform: record.ioTPlatform,
|
||||||
|
ioTPlatformProductId: record.ioTPlatformProductId,
|
||||||
});
|
});
|
||||||
propertyModalApi.open();
|
propertyModalApi.open();
|
||||||
}
|
}
|
||||||
@ -309,6 +378,163 @@ const openAddModal = async () => {
|
|||||||
thingModelModalApi.open();
|
thingModelModalApi.open();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 打开函数脚本测试弹窗
|
||||||
|
function openTestScriptModal(record?: any) {
|
||||||
|
// 工具栏点击:不关心物模型Id/名称
|
||||||
|
if (record && record.id) {
|
||||||
|
testDeviceThingModelId.value = record.id;
|
||||||
|
testDeviceModelName.value = record.deviceModelName || '';
|
||||||
|
} else {
|
||||||
|
testDeviceThingModelId.value = '';
|
||||||
|
testDeviceModelName.value = '';
|
||||||
|
}
|
||||||
|
testScriptFormApi.resetForm();
|
||||||
|
testResult.value = '';
|
||||||
|
testScriptModalApi.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 函数构建并打开测试弹窗
|
||||||
|
async function buildAndOpenTestScript(record: any) {
|
||||||
|
if (!record.id) {
|
||||||
|
Message.warning('设备端物模型ID不存在');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果解析启用为 true,禁止构建函数
|
||||||
|
if (record.functionAnalysisFlag === true) {
|
||||||
|
Message.warning('解析启用状态下不允许构建函数');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resp =
|
||||||
|
await postDeviceThingModelManagementBuildAnalysisScriptByIdAsync({
|
||||||
|
body: { id: record.id },
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('函数构建接口返回:', resp.data);
|
||||||
|
|
||||||
|
// 先通过统一的方法打开弹窗(与工具栏按钮保持一致,并携带物模型信息)
|
||||||
|
openTestScriptModal(record);
|
||||||
|
|
||||||
|
// 等待弹窗和表单渲染完成后再回填数据
|
||||||
|
await nextTick();
|
||||||
|
await testScriptFormApi.setValues({
|
||||||
|
functionName: resp.data?.functionName || '',
|
||||||
|
functionCode: resp.data?.functionCode || '',
|
||||||
|
parameters: '', // 参数需要手动输入
|
||||||
|
});
|
||||||
|
|
||||||
|
Message.success('函数构建成功');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('函数构建失败:', error);
|
||||||
|
Message.error('函数构建失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析启用 / 禁用解析
|
||||||
|
async function enableAnalysisScript(record: any) {
|
||||||
|
if (!record.id) {
|
||||||
|
Message.warning('设备端物模型ID不存在');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const isEnabled = record.functionAnalysisFlag === true;
|
||||||
|
|
||||||
|
const resp =
|
||||||
|
await postDeviceThingModelManagementUpdateAnalysisScriptByIdAsync({
|
||||||
|
query: {
|
||||||
|
id: record.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (resp.data) {
|
||||||
|
Message.success(isEnabled ? '禁用解析成功' : '启用解析成功');
|
||||||
|
// 刷新列表,确保状态立即更新
|
||||||
|
if (gridApi && gridApi.reload) {
|
||||||
|
await gridApi.reload();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Message.error(isEnabled ? '禁用解析失败' : '启用解析失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析启用失败:', error);
|
||||||
|
Message.error('解析状态更新失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交函数脚本测试
|
||||||
|
async function submitTestScript() {
|
||||||
|
const { valid } = await testScriptFormApi.validate();
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
const formValues = await testScriptFormApi.getValues();
|
||||||
|
|
||||||
|
// 解析 parameters JSON 字符串
|
||||||
|
let parameters: any = null;
|
||||||
|
if (formValues.parameters) {
|
||||||
|
try {
|
||||||
|
parameters = JSON.parse(formValues.parameters);
|
||||||
|
} catch {
|
||||||
|
Message.error('函数参数格式错误,请输入有效的JSON格式');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchParams: any = {
|
||||||
|
functionName: formValues.functionName,
|
||||||
|
functionCode: formValues.functionCode,
|
||||||
|
...(parameters && { parameters }),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resp = await postDeviceThingModelManagementMessageAnalysisTestAsync({
|
||||||
|
body: fetchParams,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 将结果格式化为JSON字符串显示
|
||||||
|
testResult.value = JSON.stringify(resp.data || {}, null, 2);
|
||||||
|
Message.success('测试执行成功');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('函数脚本测试失败:', error);
|
||||||
|
testResult.value = `测试失败: ${error instanceof Error ? error.message : String(error)}`;
|
||||||
|
Message.error('函数脚本测试失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新函数脚本到设备端物模型
|
||||||
|
async function updateFunctionScript() {
|
||||||
|
if (!testDeviceThingModelId.value) {
|
||||||
|
Message.warning('当前未关联具体设备端物模型,无法更新函数');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { valid } = await testScriptFormApi.validate();
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
const formValues = await testScriptFormApi.getValues();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resp = await postDeviceThingModelManagementBuildAnalysisScriptAsync({
|
||||||
|
body: {
|
||||||
|
id: testDeviceThingModelId.value,
|
||||||
|
scriptName: formValues.functionName,
|
||||||
|
functionScript: formValues.functionCode,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (resp.data) {
|
||||||
|
Message.success('更新函数成功');
|
||||||
|
} else {
|
||||||
|
Message.error('更新函数失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('更新函数失败:', error);
|
||||||
|
Message.error('更新函数失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
async function onDel(record: any) {
|
async function onDel(record: any) {
|
||||||
try {
|
try {
|
||||||
@ -366,49 +592,49 @@ onMounted(async () => {
|
|||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
<Grid>
|
<Grid>
|
||||||
<template #toolbar-actions>
|
<template #toolbar-actions>
|
||||||
<TableAction
|
<TableAction :actions="[
|
||||||
:actions="[
|
{
|
||||||
{
|
label: $t('common.add'),
|
||||||
label: $t('common.add'),
|
type: 'primary',
|
||||||
type: 'primary',
|
icon: 'ant-design:plus-outlined',
|
||||||
icon: 'ant-design:plus-outlined',
|
onClick: openAddModal.bind(null),
|
||||||
onClick: openAddModal.bind(null),
|
auth: ['AbpIdentity.Users.Create'],
|
||||||
auth: ['AbpIdentity.Users.Create'],
|
},
|
||||||
},
|
{
|
||||||
]"
|
label: '函数脚本测试',
|
||||||
/>
|
type: 'default',
|
||||||
|
icon: 'ant-design:code-outlined',
|
||||||
|
onClick: openTestScriptModal,
|
||||||
|
auth: ['AbpIdentity.Users.Create'],
|
||||||
|
},
|
||||||
|
]" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 解析启用列 -->
|
<!-- 解析启用列 -->
|
||||||
<template #functionAnalysisFlag="{ row }">
|
<template #functionAnalysisFlag="{ row }">
|
||||||
<component
|
<component :is="h(Tag, { color: row.functionAnalysisFlag ? 'green' : 'red' }, () =>
|
||||||
:is="
|
row.functionAnalysisFlag ? '是' : '否',
|
||||||
h(
|
)
|
||||||
Tag,
|
" />
|
||||||
{ color: row.functionAnalysisFlag ? 'green' : 'red' },
|
|
||||||
() => (row.functionAnalysisFlag ? '是' : '否'),
|
|
||||||
)
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #action="{ row }">
|
<template #action="{ row }">
|
||||||
<TableAction
|
<TableAction :actions="[
|
||||||
:actions="[
|
{
|
||||||
{
|
label: $t('common.edit'),
|
||||||
label: $t('common.edit'),
|
type: 'link',
|
||||||
type: 'link',
|
size: 'small',
|
||||||
size: 'small',
|
auth: ['AbpIdentity.Users.Update'],
|
||||||
auth: ['AbpIdentity.Users.Update'],
|
onClick: onEdit.bind(null, row),
|
||||||
onClick: onEdit.bind(null, row),
|
},
|
||||||
},
|
{
|
||||||
{
|
label: '属性管理',
|
||||||
label: '属性管理',
|
type: 'link',
|
||||||
type: 'link',
|
size: 'small',
|
||||||
size: 'small',
|
auth: ['AbpIdentity.Users.Update'],
|
||||||
auth: ['AbpIdentity.Users.Update'],
|
onClick: openPropertyModal.bind(null, row),
|
||||||
onClick: openPropertyModal.bind(null, row),
|
},
|
||||||
},
|
]" :drop-down-actions="[
|
||||||
{
|
{
|
||||||
label: '指令管理',
|
label: '指令管理',
|
||||||
type: 'link',
|
type: 'link',
|
||||||
@ -416,19 +642,44 @@ onMounted(async () => {
|
|||||||
auth: ['AbpIdentity.Users.Update'],
|
auth: ['AbpIdentity.Users.Update'],
|
||||||
onClick: openCommandModal.bind(null, row),
|
onClick: openCommandModal.bind(null, row),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: row.functionAnalysisFlag ? '禁用解析' : '启用解析',
|
||||||
|
type: 'input',
|
||||||
|
size: 'small',
|
||||||
|
auth: ['AbpIdentity.Users.Update'],
|
||||||
|
style: row.functionAnalysisFlag
|
||||||
|
? { color: '#ff4d4f' } // 红色:禁用解析
|
||||||
|
: { color: '#52c41a' }, // 绿色:启用解析
|
||||||
|
popConfirm: {
|
||||||
|
title: row.functionAnalysisFlag
|
||||||
|
? '确定要禁用该设备端物模型的解析吗?'
|
||||||
|
: '确定要启用该设备端物模型的解析吗?',
|
||||||
|
confirm: enableAnalysisScript.bind(null, row),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '函数构建',
|
||||||
|
type: 'link',
|
||||||
|
size: 'small',
|
||||||
|
auth: ['AbpIdentity.Users.Update'],
|
||||||
|
disabled: row.functionAnalysisFlag === true,
|
||||||
|
popConfirm: {
|
||||||
|
title: '确定要为该设备端物模型执行函数构建吗?',
|
||||||
|
confirm: buildAndOpenTestScript.bind(null, row),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: $t('common.delete'),
|
label: $t('common.delete'),
|
||||||
icon: 'ant-design:delete-outlined',
|
|
||||||
type: 'link',
|
type: 'link',
|
||||||
size: 'small',
|
size: 'small',
|
||||||
auth: ['AbpIdentity.Users.Delete'],
|
auth: ['AbpIdentity.Users.Delete'],
|
||||||
|
style: { color: '#ff4d4f' },
|
||||||
popConfirm: {
|
popConfirm: {
|
||||||
title: $t('common.askConfirmDelete'),
|
title: $t('common.askConfirmDelete'),
|
||||||
confirm: onDel.bind(null, row),
|
confirm: onDel.bind(null, row),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]"
|
]" />
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
@ -438,13 +689,23 @@ onMounted(async () => {
|
|||||||
<!-- 指令管理弹窗(独立组件) -->
|
<!-- 指令管理弹窗(独立组件) -->
|
||||||
<CommandModal />
|
<CommandModal />
|
||||||
|
|
||||||
<ThingModelModal
|
<ThingModelModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
|
||||||
:title="editRow.id ? $t('common.edit') : $t('common.add')"
|
|
||||||
class="w-[800px]"
|
|
||||||
>
|
|
||||||
<component :is="editRow.id ? EditForm : AddForm" />
|
<component :is="editRow.id ? EditForm : AddForm" />
|
||||||
</ThingModelModal>
|
</ThingModelModal>
|
||||||
|
|
||||||
|
<!-- 函数脚本测试弹窗 -->
|
||||||
|
<TestScriptModal title="函数脚本测试" class="w-[900px]">
|
||||||
|
<div v-if="testDeviceModelName" class="mb-2 flex items-center justify-between text-base font-semibold">
|
||||||
|
<span>设备端物模型:{{ testDeviceModelName }}</span>
|
||||||
|
<Button v-if="testDeviceThingModelId" type="primary" @click="updateFunctionScript">
|
||||||
|
更新函数
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<TestScriptForm />
|
||||||
|
<div v-if="testResult" class="mt-4">
|
||||||
|
<div class="mb-2 font-semibold">测试结果:</div>
|
||||||
|
<pre class="max-h-96 overflow-auto rounded border bg-gray-50 p-4 text-sm">{{ testResult }}</pre>
|
||||||
|
</div>
|
||||||
|
</TestScriptModal>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -116,7 +116,7 @@ export const tableSchema = computed(() => [
|
|||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
showOverflow: 'tooltip',
|
showOverflow: 'tooltip',
|
||||||
formatter: ({ cellValue }: { cellValue: any }) => {
|
formatter: ({ cellValue }: { cellValue: any }) => {
|
||||||
const map: Record<string | number, string> = {
|
const map: Record<number | string, string> = {
|
||||||
1: 'CTWing',
|
1: 'CTWing',
|
||||||
2: 'OneNET',
|
2: 'OneNET',
|
||||||
};
|
};
|
||||||
@ -135,17 +135,6 @@ export const tableSchema = computed(() => [
|
|||||||
minWidth: 160,
|
minWidth: 160,
|
||||||
showOverflow: 'tooltip',
|
showOverflow: 'tooltip',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
field: 'parsingSequence',
|
|
||||||
title: '解析顺序',
|
|
||||||
minWidth: 120,
|
|
||||||
showOverflow: 'tooltip',
|
|
||||||
formatter: ({ cellValue }: { cellValue: any }) => {
|
|
||||||
if (cellValue === 1) return '正序';
|
|
||||||
if (cellValue === 2) return '高低位反转';
|
|
||||||
return cellValue ?? '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
field: 'functionAnalysisFlag',
|
field: 'functionAnalysisFlag',
|
||||||
title: '解析启用',
|
title: '解析启用',
|
||||||
@ -163,7 +152,7 @@ export const tableSchema = computed(() => [
|
|||||||
{
|
{
|
||||||
field: 'action',
|
field: 'action',
|
||||||
title: $t('common.action'),
|
title: $t('common.action'),
|
||||||
width: 200,
|
width: 160,
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
slots: { default: 'action' },
|
slots: { default: 'action' },
|
||||||
},
|
},
|
||||||
@ -175,18 +164,22 @@ export const addDeviceThingModelFormSchema = computed(() => [
|
|||||||
component: 'Input',
|
component: 'Input',
|
||||||
fieldName: 'deviceModelName',
|
fieldName: 'deviceModelName',
|
||||||
label: '设备端物模型名称',
|
label: '设备端物模型名称',
|
||||||
rules: z
|
rules: z.preprocess(
|
||||||
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
componentProps: {
|
componentProps: {
|
||||||
placeholder: $t('common.pleaseInput') + '设备端物模型名称',
|
placeholder: `${$t('common.pleaseInput')}设备端物模型名称`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: 'ApiSelect',
|
component: 'ApiSelect',
|
||||||
fieldName: 'ioTPlatform',
|
fieldName: 'ioTPlatform',
|
||||||
label: $t('abp.deviceInfos.ioTPlatform'),
|
label: $t('abp.deviceInfos.ioTPlatform'),
|
||||||
rules: z
|
rules: z.preprocess(
|
||||||
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
componentProps: {
|
componentProps: {
|
||||||
api: getCommonGetSelectList,
|
api: getCommonGetSelectList,
|
||||||
params: {
|
params: {
|
||||||
@ -219,8 +212,10 @@ export const addDeviceThingModelFormSchema = computed(() => [
|
|||||||
component: 'ApiSelect',
|
component: 'ApiSelect',
|
||||||
fieldName: 'ioTPlatformProductId',
|
fieldName: 'ioTPlatformProductId',
|
||||||
label: $t('common.BelongingProductName'),
|
label: $t('common.BelongingProductName'),
|
||||||
rules: z
|
rules: z.preprocess(
|
||||||
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
componentProps: (formValues: any) => {
|
componentProps: (formValues: any) => {
|
||||||
const platform = formValues?.ioTPlatform;
|
const platform = formValues?.ioTPlatform;
|
||||||
|
|
||||||
@ -265,10 +260,12 @@ export const addDeviceThingModelFormSchema = computed(() => [
|
|||||||
component: 'Input',
|
component: 'Input',
|
||||||
fieldName: 'scriptName',
|
fieldName: 'scriptName',
|
||||||
label: '脚本函数名称',
|
label: '脚本函数名称',
|
||||||
rules: z
|
rules: z.preprocess(
|
||||||
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
componentProps: {
|
componentProps: {
|
||||||
placeholder: $t('common.pleaseInput') + '脚本函数名称',
|
placeholder: `${$t('common.pleaseInput')}脚本函数名称`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -288,18 +285,22 @@ export const editDeviceThingModelFormSchema = computed(() => [
|
|||||||
component: 'Input',
|
component: 'Input',
|
||||||
fieldName: 'deviceModelName',
|
fieldName: 'deviceModelName',
|
||||||
label: '设备端物模型名称',
|
label: '设备端物模型名称',
|
||||||
rules: z
|
rules: z.preprocess(
|
||||||
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
componentProps: {
|
componentProps: {
|
||||||
placeholder: $t('common.pleaseInput') + '设备端物模型名称',
|
placeholder: `${$t('common.pleaseInput')}设备端物模型名称`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: 'ApiSelect',
|
component: 'ApiSelect',
|
||||||
fieldName: 'ioTPlatform',
|
fieldName: 'ioTPlatform',
|
||||||
label: $t('abp.deviceInfos.ioTPlatform'),
|
label: $t('abp.deviceInfos.ioTPlatform'),
|
||||||
rules: z
|
rules: z.preprocess(
|
||||||
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
componentProps: {
|
componentProps: {
|
||||||
api: getCommonGetSelectList,
|
api: getCommonGetSelectList,
|
||||||
params: {
|
params: {
|
||||||
@ -333,8 +334,10 @@ export const editDeviceThingModelFormSchema = computed(() => [
|
|||||||
component: 'ApiSelect',
|
component: 'ApiSelect',
|
||||||
fieldName: 'ioTPlatformProductId',
|
fieldName: 'ioTPlatformProductId',
|
||||||
label: $t('common.BelongingProductName'),
|
label: $t('common.BelongingProductName'),
|
||||||
rules: z
|
rules: z.preprocess(
|
||||||
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
componentProps: (formValues: any) => {
|
componentProps: (formValues: any) => {
|
||||||
const platform = formValues?.ioTPlatform;
|
const platform = formValues?.ioTPlatform;
|
||||||
|
|
||||||
@ -380,10 +383,12 @@ export const editDeviceThingModelFormSchema = computed(() => [
|
|||||||
component: 'Input',
|
component: 'Input',
|
||||||
fieldName: 'scriptName',
|
fieldName: 'scriptName',
|
||||||
label: '脚本函数名称',
|
label: '脚本函数名称',
|
||||||
rules: z
|
rules: z.preprocess(
|
||||||
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
(v) => (v == null ? '' : v),
|
||||||
|
z.string().min(1, $t('common.required')),
|
||||||
|
),
|
||||||
componentProps: {
|
componentProps: {
|
||||||
placeholder: $t('common.pleaseInput') + '脚本函数名称',
|
placeholder: `${$t('common.pleaseInput')}脚本函数名称`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -396,5 +401,3 @@ export const editDeviceThingModelFormSchema = computed(() => [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user