Compare commits
2 Commits
90a0a05147
...
095b521259
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
095b521259 | ||
|
|
8f4cd47a4f |
@ -1720,6 +1720,30 @@ export const CreateOrganizationUnitInputSchema = {
|
||||
additionalProperties: false
|
||||
} as const;
|
||||
|
||||
export const CreatePlatformThingModelCommandInputSchema = {
|
||||
required: ['issueCommand', 'operateType', 'thingModelDataId'],
|
||||
type: 'object',
|
||||
properties: {
|
||||
thingModelDataId: {
|
||||
type: 'string',
|
||||
description: '平台端物模型数据Id',
|
||||
format: 'uuid'
|
||||
},
|
||||
operateType: {
|
||||
type: 'integer',
|
||||
description: '待下发的操作指令类型,例如阀控操作时,是拉闸还是合闸,根据StandardFieldName进行分组',
|
||||
format: 'int32'
|
||||
},
|
||||
issueCommand: {
|
||||
minLength: 1,
|
||||
type: 'string',
|
||||
description: '完整透明转发指令'
|
||||
}
|
||||
},
|
||||
additionalProperties: false,
|
||||
description: '新增平台端物模型操作指令'
|
||||
} as const;
|
||||
|
||||
export const CreateTextTemplateInputSchema = {
|
||||
required: ['code', 'content', 'cultureName', 'name'],
|
||||
type: 'object',
|
||||
@ -2995,8 +3019,7 @@ export const DeviceThingModelCommandInfoDtoSchema = {
|
||||
operateCommandType: {
|
||||
type: 'integer',
|
||||
description: '待下发的操作指令类型,,例如阀控操作时,是拉闸还是合闸',
|
||||
format: 'int32',
|
||||
nullable: true
|
||||
format: 'int32'
|
||||
}
|
||||
},
|
||||
additionalProperties: false,
|
||||
@ -5329,6 +5352,28 @@ export const GetPermissionInputSchema = {
|
||||
additionalProperties: false
|
||||
} as const;
|
||||
|
||||
export const GetPlatformThingModelServiceInputSchema = {
|
||||
required: ['id'],
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
minLength: 1,
|
||||
type: 'string'
|
||||
},
|
||||
standardFieldName: {
|
||||
type: 'string',
|
||||
description: '管理后台产品标准的物模型属性或者事件名称',
|
||||
nullable: true
|
||||
},
|
||||
isGetOperateService: {
|
||||
type: 'boolean',
|
||||
description: '是否只获取操作服务'
|
||||
}
|
||||
},
|
||||
additionalProperties: false,
|
||||
description: '获取平台物模型服务列表入参'
|
||||
} as const;
|
||||
|
||||
export const GetQRCodeOutputSchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@ -6272,7 +6317,10 @@ export const IoTPlatformThingModelCreateInputSchema = {
|
||||
description: '是否是特殊物模型标识符'
|
||||
},
|
||||
ioTPlatformRawFieldExtension: {
|
||||
'$ref': '#/components/schemas/JToken'
|
||||
type: 'object',
|
||||
additionalProperties: {},
|
||||
description: '物联网平台中对应产品物模型标识符扩展,用于扩展结构体类型',
|
||||
nullable: true
|
||||
},
|
||||
isOperableIdentifier: {
|
||||
type: 'boolean',
|
||||
@ -6287,7 +6335,10 @@ export const IoTPlatformThingModelCreateInputSchema = {
|
||||
'$ref': '#/components/schemas/ThingModelIdentifierTypeEnum'
|
||||
},
|
||||
standardFieldFieldExtension: {
|
||||
'$ref': '#/components/schemas/JToken'
|
||||
type: 'object',
|
||||
additionalProperties: {},
|
||||
description: '标准物模型字段标识符扩展,数组或者结构体时候的参数或者元素名称集合',
|
||||
nullable: true
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
@ -6709,7 +6760,10 @@ export const IoTPlatformThingModelUpdateInputSchema = {
|
||||
description: '是否是特殊物模型标识符'
|
||||
},
|
||||
ioTPlatformRawFieldExtension: {
|
||||
'$ref': '#/components/schemas/JToken'
|
||||
type: 'object',
|
||||
additionalProperties: {},
|
||||
description: '物联网平台中对应产品物模型标识符扩展,用于扩展结构体类型',
|
||||
nullable: true
|
||||
},
|
||||
isOperableIdentifier: {
|
||||
type: 'boolean',
|
||||
@ -6724,7 +6778,10 @@ export const IoTPlatformThingModelUpdateInputSchema = {
|
||||
'$ref': '#/components/schemas/ThingModelIdentifierTypeEnum'
|
||||
},
|
||||
standardFieldFieldExtension: {
|
||||
'$ref': '#/components/schemas/JToken'
|
||||
type: 'object',
|
||||
additionalProperties: {},
|
||||
description: '标准物模型字段标识符扩展,数组或者结构体时候的参数或者元素名称集合',
|
||||
nullable: true
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
@ -6740,13 +6797,6 @@ export const IoTPlatformTypeEnumSchema = {
|
||||
description: '物联网平台类型枚举'
|
||||
} as const;
|
||||
|
||||
export const JTokenSchema = {
|
||||
type: 'array',
|
||||
items: {
|
||||
'$ref': '#/components/schemas/JToken'
|
||||
}
|
||||
} as const;
|
||||
|
||||
export const LanguageInfoSchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@ -9389,6 +9439,14 @@ export const PagingDataDictionaryDetailOutputSchema = {
|
||||
description: '扩展属性',
|
||||
nullable: true
|
||||
},
|
||||
extendedAttributeValue: {
|
||||
type: 'object',
|
||||
additionalProperties: {
|
||||
nullable: true
|
||||
},
|
||||
description: '扩展属性值',
|
||||
nullable: true
|
||||
},
|
||||
isEnabled: {
|
||||
type: 'boolean',
|
||||
description: '启/停用(默认启用)'
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -552,6 +552,24 @@ export type CreateOrganizationUnitInput = {
|
||||
parentId?: (string) | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增平台端物模型操作指令
|
||||
*/
|
||||
export type CreatePlatformThingModelCommandInput = {
|
||||
/**
|
||||
* 平台端物模型数据Id
|
||||
*/
|
||||
thingModelDataId: string;
|
||||
/**
|
||||
* 待下发的操作指令类型,例如阀控操作时,是拉闸还是合闸,根据StandardFieldName进行分组
|
||||
*/
|
||||
operateType: number;
|
||||
/**
|
||||
* 完整透明转发指令
|
||||
*/
|
||||
issueCommand: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* 创建模板
|
||||
*/
|
||||
@ -1731,7 +1749,7 @@ export type DeviceThingModelCommandInfoDto = {
|
||||
/**
|
||||
* 待下发的操作指令类型,,例如阀控操作时,是拉闸还是合闸
|
||||
*/
|
||||
operateCommandType?: (number) | null;
|
||||
operateCommandType?: number;
|
||||
};
|
||||
|
||||
export type DeviceThingModelCommandInfoDtoPagedResultDto = {
|
||||
@ -2875,6 +2893,21 @@ export type GetPermissionInput = {
|
||||
providerKey?: (string) | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取平台物模型服务列表入参
|
||||
*/
|
||||
export type GetPlatformThingModelServiceInput = {
|
||||
id: string;
|
||||
/**
|
||||
* 管理后台产品标准的物模型属性或者事件名称
|
||||
*/
|
||||
standardFieldName?: (string) | null;
|
||||
/**
|
||||
* 是否只获取操作服务
|
||||
*/
|
||||
isGetOperateService?: boolean;
|
||||
};
|
||||
|
||||
export type GetQRCodeOutput = {
|
||||
/**
|
||||
* base64 二维码
|
||||
@ -3286,7 +3319,12 @@ export type IoTPlatformThingModelCreateInput = {
|
||||
* 是否是特殊物模型标识符
|
||||
*/
|
||||
isSpecialIdentifier?: boolean;
|
||||
ioTPlatformRawFieldExtension?: JToken;
|
||||
/**
|
||||
* 物联网平台中对应产品物模型标识符扩展,用于扩展结构体类型
|
||||
*/
|
||||
ioTPlatformRawFieldExtension?: {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
/**
|
||||
* 是否可操作物模型标识符
|
||||
*/
|
||||
@ -3296,7 +3334,12 @@ export type IoTPlatformThingModelCreateInput = {
|
||||
*/
|
||||
accessMode?: (string) | null;
|
||||
identifierType?: ThingModelIdentifierTypeEnum;
|
||||
standardFieldFieldExtension?: JToken;
|
||||
/**
|
||||
* 标准物模型字段标识符扩展,数组或者结构体时候的参数或者元素名称集合
|
||||
*/
|
||||
standardFieldFieldExtension?: {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -3565,7 +3608,12 @@ export type IoTPlatformThingModelUpdateInput = {
|
||||
* 是否是特殊物模型标识符
|
||||
*/
|
||||
isSpecialIdentifier?: boolean;
|
||||
ioTPlatformRawFieldExtension?: JToken;
|
||||
/**
|
||||
* 物联网平台中对应产品物模型标识符扩展,用于扩展结构体类型
|
||||
*/
|
||||
ioTPlatformRawFieldExtension?: {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
/**
|
||||
* 是否可操作物模型标识符
|
||||
*/
|
||||
@ -3575,7 +3623,12 @@ export type IoTPlatformThingModelUpdateInput = {
|
||||
*/
|
||||
accessMode?: (string) | null;
|
||||
identifierType?: ThingModelIdentifierTypeEnum;
|
||||
standardFieldFieldExtension?: JToken;
|
||||
/**
|
||||
* 标准物模型字段标识符扩展,数组或者结构体时候的参数或者元素名称集合
|
||||
*/
|
||||
standardFieldFieldExtension?: {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
id?: string;
|
||||
};
|
||||
|
||||
@ -3599,8 +3652,6 @@ export type IValueValidator = {
|
||||
} | null;
|
||||
};
|
||||
|
||||
export type JToken = Array<JToken>;
|
||||
|
||||
export type LanguageInfo = {
|
||||
cultureName?: (string) | null;
|
||||
uiCultureName?: (string) | null;
|
||||
@ -5219,6 +5270,12 @@ export type PagingDataDictionaryDetailOutput = {
|
||||
* 扩展属性
|
||||
*/
|
||||
extendedAttribute?: (string) | null;
|
||||
/**
|
||||
* 扩展属性值
|
||||
*/
|
||||
extendedAttributeValue?: {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
/**
|
||||
* 启/停用(默认启用)
|
||||
*/
|
||||
@ -7728,7 +7785,7 @@ export type PostIoTplatformThingModelInfoUpdateOperableIdentifierError = unknown
|
||||
|
||||
export type PostIoTplatformThingModelInfoGetIoTplatformThingModelServiceData = {
|
||||
query?: {
|
||||
input?: StringIdInput;
|
||||
input?: GetPlatformThingModelServiceInput;
|
||||
};
|
||||
};
|
||||
|
||||
@ -7736,6 +7793,16 @@ export type PostIoTplatformThingModelInfoGetIoTplatformThingModelServiceResponse
|
||||
|
||||
export type PostIoTplatformThingModelInfoGetIoTplatformThingModelServiceError = unknown;
|
||||
|
||||
export type PostIoTplatformThingModelInfoCreateIoTplatformThingModelCommandData = {
|
||||
query?: {
|
||||
input?: CreatePlatformThingModelCommandInput;
|
||||
};
|
||||
};
|
||||
|
||||
export type PostIoTplatformThingModelInfoCreateIoTplatformThingModelCommandResponse = (IoTPlatformThingModelCommandDto);
|
||||
|
||||
export type PostIoTplatformThingModelInfoCreateIoTplatformThingModelCommandError = unknown;
|
||||
|
||||
export type PostLanguagesAllResponse = (Array<PageLanguageOutput>);
|
||||
|
||||
export type PostLanguagesAllError = (RemoteServiceErrorResponse);
|
||||
|
||||
@ -337,9 +337,9 @@ const commandTableColumns = computed(() => [
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '平台物模型属性标识符',
|
||||
dataIndex: 'ioTPlatformRawFieldName',
|
||||
key: 'ioTPlatformRawFieldName',
|
||||
title: '标准物模型属性标识符',
|
||||
dataIndex: 'standardFieldName',
|
||||
key: 'standardFieldName',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
@ -473,6 +473,7 @@ const bindRows: Array<Record<string, any>> = ref([]);
|
||||
interface ThingModelProperty {
|
||||
id: string; // 物模型属性ID
|
||||
ioTPlatformRawFieldName: string; // 平台原始字段名
|
||||
standardFieldName: string; // 标准物模型字段名(标识符)
|
||||
standardFieldDisplayName: string; // 标准字段显示名
|
||||
commandValue: string; // 指令内容
|
||||
result: string; // 返回结果
|
||||
@ -487,6 +488,10 @@ const thingModelLoading = ref(false);
|
||||
// 筛选关键词
|
||||
const filterKeyword = ref('');
|
||||
|
||||
// 设备操作统一使用标准物模型标识符作为参数键
|
||||
const getPropertyIdentifier = (property: ThingModelProperty) =>
|
||||
(property.standardFieldName || '').trim();
|
||||
|
||||
// 判断是否为数字类型
|
||||
const isNumericType = (dataType: string | undefined): boolean => {
|
||||
if (!dataType) return false;
|
||||
@ -559,7 +564,7 @@ const filteredThingModelProperties = computed(() => {
|
||||
return thingModelProperties.value.filter((prop) => {
|
||||
return (
|
||||
prop.standardFieldDisplayName?.toLowerCase().includes(keyword) ||
|
||||
prop.ioTPlatformRawFieldName?.toLowerCase().includes(keyword)
|
||||
prop.standardFieldName?.toLowerCase().includes(keyword)
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -593,6 +598,7 @@ const fetchThingModelProperties = async (row: Record<string, any>) => {
|
||||
thingModelProperties.value = items.map((item: any) => ({
|
||||
id: item.id || '',
|
||||
ioTPlatformRawFieldName: item.ioTPlatformRawFieldName || '',
|
||||
standardFieldName: item.standardFieldName || '',
|
||||
standardFieldDisplayName: item.standardFieldDisplayName || '',
|
||||
commandValue: '',
|
||||
result: '',
|
||||
@ -626,7 +632,7 @@ const submitBatchCommand = async () => {
|
||||
const selectedProperties = thingModelProperties.value.filter(
|
||||
(prop) =>
|
||||
prop.selected &&
|
||||
prop.ioTPlatformRawFieldName &&
|
||||
getPropertyIdentifier(prop) &&
|
||||
(prop.accessMode === 'rw' || prop.accessMode === 'w') && // 允许读写模式和只写模式
|
||||
prop.commandValue &&
|
||||
prop.commandValue.trim() !== '',
|
||||
@ -647,7 +653,10 @@ const submitBatchCommand = async () => {
|
||||
prop.commandValue.trim(),
|
||||
prop.ioTPlatformRawFieldDataType,
|
||||
);
|
||||
commandContent[prop.ioTPlatformRawFieldName] = convertedValue;
|
||||
const identifier = getPropertyIdentifier(prop);
|
||||
if (identifier) {
|
||||
commandContent[identifier] = convertedValue;
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
@ -807,7 +816,10 @@ function isOperateBreakerServiceItem(item: {
|
||||
/** 拉合闸类型参数:与物模型 InputData 标识符 / 展示名对应 */
|
||||
function isBreakerOperateTypeField(f: ServiceParamField): boolean {
|
||||
const n = f.name.trim().toLowerCase();
|
||||
if (f.label.includes('拉合闸类型')) {
|
||||
if (f.label.includes('拉合闸类型') || f.label.includes('操作类型')) {
|
||||
return true;
|
||||
}
|
||||
if (n === 'operatetype' || n === 'operate_type') {
|
||||
return true;
|
||||
}
|
||||
if (n === 'operatecommandtype') {
|
||||
@ -849,11 +861,6 @@ const valveCommandTypeOptions = ref<Array<{ label: string; value: string }>>(
|
||||
);
|
||||
const valveCommandTypeLoading = ref(false);
|
||||
|
||||
const breakerOperateTypeOptions = ref<Array<{ label: string; value: string }>>(
|
||||
[],
|
||||
);
|
||||
const breakerOperateTypeLoading = ref(false);
|
||||
|
||||
function normalizeServiceThirdValue(raw: unknown): ServiceParamField[] {
|
||||
if (raw === null || raw === undefined || raw === '') {
|
||||
return [];
|
||||
@ -984,6 +991,10 @@ const serviceCallSelectOptions = computed(() =>
|
||||
})),
|
||||
);
|
||||
|
||||
const breakerOperateTypeOptions = computed(() =>
|
||||
extractBreakerOperateTypeOptionsFromSecondValue(currentServiceItem.value),
|
||||
);
|
||||
|
||||
function shouldUseValveCommandTypeSelectForField(f: ServiceParamField): boolean {
|
||||
if (!isValveControlServiceItem(currentServiceItem.value)) {
|
||||
return false;
|
||||
@ -1000,6 +1011,96 @@ function shouldUseBreakerOperateTypeSelectForField(
|
||||
return isBreakerOperateTypeField(f);
|
||||
}
|
||||
|
||||
function parseJsonMaybe(raw: unknown): unknown {
|
||||
if (typeof raw !== 'string') {
|
||||
return raw;
|
||||
}
|
||||
const s = raw.trim();
|
||||
if (!s) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return JSON.parse(s) as unknown;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function toSecondValueSelectOptions(
|
||||
list: unknown[],
|
||||
): Array<{ label: string; value: string }> {
|
||||
return list
|
||||
.map((x: any) => {
|
||||
if (!x || typeof x !== 'object') {
|
||||
return null;
|
||||
}
|
||||
const value = String(
|
||||
x.key ?? x.id ?? x.value ?? x.Identifier ?? x.identifier ?? '',
|
||||
).trim();
|
||||
const label = String(
|
||||
x.label ?? x.name ?? x.text ?? x.value ?? x.Name ?? x.name ?? value,
|
||||
).trim();
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
return { label: label || value, value };
|
||||
})
|
||||
.filter(Boolean) as Array<{ label: string; value: string }>;
|
||||
}
|
||||
|
||||
function extractBreakerOperateTypeOptionsFromSecondValue(item: {
|
||||
secondValue?: null | string;
|
||||
} | null): Array<{ label: string; value: string }> {
|
||||
if (!item) {
|
||||
return [];
|
||||
}
|
||||
const parsed = parseJsonMaybe(item.secondValue);
|
||||
if (!parsed) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (Array.isArray(parsed)) {
|
||||
return toSecondValueSelectOptions(parsed);
|
||||
}
|
||||
|
||||
if (typeof parsed === 'object') {
|
||||
const obj = parsed as Record<string, unknown>;
|
||||
const candidateLists = [
|
||||
obj.operateType,
|
||||
obj.OperateType,
|
||||
obj.operateTypeList,
|
||||
obj.operateTypes,
|
||||
obj.OperateTypeList,
|
||||
obj.OperateTypes,
|
||||
obj.options,
|
||||
obj.list,
|
||||
obj.items,
|
||||
obj.data,
|
||||
];
|
||||
for (const c of candidateLists) {
|
||||
if (Array.isArray(c)) {
|
||||
const options = toSecondValueSelectOptions(c);
|
||||
if (options.length > 0) {
|
||||
return options;
|
||||
}
|
||||
}
|
||||
// secondValue 也可能是键值映射:{ "1":"拉闸", "2":"合闸" }
|
||||
if (c && typeof c === 'object' && !Array.isArray(c)) {
|
||||
const mapped = Object.entries(c as Record<string, unknown>).map(
|
||||
([k, v]) => ({
|
||||
label: String(v ?? k),
|
||||
value: String(k),
|
||||
}),
|
||||
);
|
||||
if (mapped.length > 0) {
|
||||
return mapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function mapSelectListToOptions(list: any[]): Array<{ label: string; value: string }> {
|
||||
return list
|
||||
.map((x: any) => ({
|
||||
@ -1026,7 +1127,6 @@ watch(
|
||||
() => currentServiceItem.value,
|
||||
async (item) => {
|
||||
valveCommandTypeOptions.value = [];
|
||||
breakerOperateTypeOptions.value = [];
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
@ -1047,21 +1147,6 @@ watch(
|
||||
}
|
||||
}
|
||||
|
||||
if (isOperateBreakerServiceItem(item)) {
|
||||
breakerOperateTypeLoading.value = true;
|
||||
try {
|
||||
const { data } = await getCommonGetSelectList({
|
||||
query: { typeName: DEVICE_THING_MODE_COMMAND_TYPE_ENUM },
|
||||
} as any);
|
||||
breakerOperateTypeOptions.value = mapSelectListToOptions(
|
||||
unwrapSelectListResponse(data),
|
||||
);
|
||||
} catch {
|
||||
breakerOperateTypeOptions.value = [];
|
||||
} finally {
|
||||
breakerOperateTypeLoading.value = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@ -1098,8 +1183,6 @@ const [ServiceCallModal, serviceCallModalApi] = useVbenModal({
|
||||
serviceCallFormValues.value = {};
|
||||
valveCommandTypeOptions.value = [];
|
||||
valveCommandTypeLoading.value = false;
|
||||
breakerOperateTypeOptions.value = [];
|
||||
breakerOperateTypeLoading.value = false;
|
||||
return true;
|
||||
},
|
||||
onOpenChange: async (isOpen: boolean) => {
|
||||
@ -1117,6 +1200,22 @@ const [ServiceCallModal, serviceCallModalApi] = useVbenModal({
|
||||
|
||||
const serviceCallModalState = serviceCallModalApi.useStore();
|
||||
|
||||
/** 服务入参:部分字段需为数值(如 Quantity),避免以字符串提交 */
|
||||
function coerceServiceCallParamValue(
|
||||
fieldName: string,
|
||||
raw: string,
|
||||
): { ok: true; value: unknown } | { ok: false; message: string } {
|
||||
const key = fieldName.trim();
|
||||
if (key.toLowerCase() === 'quantity') {
|
||||
const n = Number(raw);
|
||||
if (Number.isNaN(n)) {
|
||||
return { ok: false, message: '数量(Quantity)需填写有效数字' };
|
||||
}
|
||||
return { ok: true, value: n };
|
||||
}
|
||||
return { ok: true, value: raw };
|
||||
}
|
||||
|
||||
async function submitDeviceServiceCall() {
|
||||
const row = serviceCallRow.value;
|
||||
if (!row?.id) {
|
||||
@ -1140,7 +1239,12 @@ async function submitDeviceServiceCall() {
|
||||
for (const f of serviceParamFields.value) {
|
||||
const v = (serviceCallFormValues.value[f.name] ?? '').trim();
|
||||
if (v !== '') {
|
||||
serviceParams[f.name] = v;
|
||||
const coerced = coerceServiceCallParamValue(f.name, v);
|
||||
if (!coerced.ok) {
|
||||
Message.warning(coerced.message);
|
||||
return;
|
||||
}
|
||||
serviceParams[f.name] = coerced.value;
|
||||
}
|
||||
}
|
||||
try {
|
||||
@ -2023,8 +2127,9 @@ const sendCommand = async (property: ThingModelProperty) => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!property.ioTPlatformRawFieldName) {
|
||||
Message.warning('该属性缺少平台字段名,无法发送指令');
|
||||
const identifier = getPropertyIdentifier(property);
|
||||
if (!identifier) {
|
||||
Message.warning('该属性缺少标准物模型标识符,无法发送指令');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2036,7 +2141,7 @@ const sendCommand = async (property: ThingModelProperty) => {
|
||||
property.commandValue.trim(),
|
||||
property.ioTPlatformRawFieldDataType,
|
||||
);
|
||||
commandContent[property.ioTPlatformRawFieldName] = convertedValue;
|
||||
commandContent[identifier] = convertedValue;
|
||||
|
||||
const result = await postAggregationDeviceDeviceCommandForApiAsync({
|
||||
body: {
|
||||
@ -2075,8 +2180,9 @@ const readData = async (property: ThingModelProperty) => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!property.ioTPlatformRawFieldName) {
|
||||
Message.warning('该属性缺少平台字段名,无法抄读数据');
|
||||
const identifier = getPropertyIdentifier(property);
|
||||
if (!identifier) {
|
||||
Message.warning('该属性缺少标准物模型标识符,无法抄读数据');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2091,16 +2197,14 @@ const readData = async (property: ThingModelProperty) => {
|
||||
{
|
||||
body: {
|
||||
id: String(commandRow.value.id),
|
||||
propertyList: [property.ioTPlatformRawFieldName],
|
||||
propertyList: { [identifier]: '' },
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (result.data !== undefined && result.data !== null) {
|
||||
// 返回结果是一个对象,需要根据属性名获取对应的值
|
||||
const propertyValue = (result.data as any)[
|
||||
property.ioTPlatformRawFieldName
|
||||
];
|
||||
const propertyValue = (result.data as any)[identifier];
|
||||
if (propertyValue !== undefined && propertyValue !== null) {
|
||||
property.result =
|
||||
typeof propertyValue === 'string'
|
||||
@ -2141,7 +2245,7 @@ const submitBatchRead = async () => {
|
||||
// 获取所有选中的行,排除只写模式(w)的属性
|
||||
const selectedProperties = thingModelProperties.value.filter(
|
||||
(prop) =>
|
||||
prop.selected && prop.ioTPlatformRawFieldName && prop.accessMode !== 'w', // 只写模式不能抄读
|
||||
prop.selected && getPropertyIdentifier(prop) && prop.accessMode !== 'w', // 只写模式不能抄读
|
||||
);
|
||||
|
||||
if (selectedProperties.length === 0) {
|
||||
@ -2155,8 +2259,15 @@ const submitBatchRead = async () => {
|
||||
}
|
||||
|
||||
// 获取所有选中属性的字段名列表
|
||||
const propertyList = selectedProperties.map(
|
||||
(prop) => prop.ioTPlatformRawFieldName,
|
||||
const propertyList = selectedProperties.reduce<Record<string, string>>(
|
||||
(acc, prop) => {
|
||||
const identifier = getPropertyIdentifier(prop);
|
||||
if (identifier) {
|
||||
acc[identifier] = '';
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
try {
|
||||
@ -2180,9 +2291,10 @@ const submitBatchRead = async () => {
|
||||
if (result.data !== undefined && result.data !== null) {
|
||||
// 更新所有选中行的返回结果
|
||||
selectedProperties.forEach((prop) => {
|
||||
const propertyValue = (result.data as any)[
|
||||
prop.ioTPlatformRawFieldName
|
||||
];
|
||||
const identifier = getPropertyIdentifier(prop);
|
||||
const propertyValue = identifier
|
||||
? (result.data as any)[identifier]
|
||||
: undefined;
|
||||
if (propertyValue !== undefined && propertyValue !== null) {
|
||||
prop.result =
|
||||
typeof propertyValue === 'string'
|
||||
@ -2844,7 +2956,6 @@ const toolbarActions = computed(() => [
|
||||
v-else-if="shouldUseBreakerOperateTypeSelectForField(f)"
|
||||
v-model:value="serviceCallFormValues[f.name]"
|
||||
:options="breakerOperateTypeOptions"
|
||||
:loading="breakerOperateTypeLoading"
|
||||
allow-clear
|
||||
class="min-w-0 flex-1"
|
||||
size="small"
|
||||
|
||||
@ -7,16 +7,19 @@ import { useRoute } from 'vue-router';
|
||||
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { message as Message, Tag } from 'ant-design-vue';
|
||||
import { Button, Input, Select, message as Message, Tag } from 'ant-design-vue';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import {
|
||||
getCommonGetSelectList,
|
||||
postAggregationIoTplatformUpdateIoTplatformProductThingModelInfoAsync,
|
||||
postIoTplatformThingModelInfoCreateIoTplatformThingModelCommand,
|
||||
postIoTplatformThingModelInfoCopyAnotherThingModelAsync,
|
||||
postIoTplatformThingModelInfoCopyStandardThingModel,
|
||||
postIoTplatformThingModelInfoCreateAsync,
|
||||
postIoTplatformThingModelInfoDeleteAsync,
|
||||
postIoTplatformThingModelInfoGetIoTplatformThingModelService,
|
||||
postIoTplatformThingModelInfoPageAsync,
|
||||
postIoTplatformThingModelInfoUpdateAsync,
|
||||
} from '#/api-client';
|
||||
@ -224,6 +227,8 @@ const editRow: Record<string, any> = ref({});
|
||||
|
||||
// 跟踪数据状态,用于控制按钮显示
|
||||
const hasData = ref(true);
|
||||
// 模型刷新按钮 loading 状态
|
||||
const thingModelRefreshLoading = ref(false);
|
||||
|
||||
const [ThingModelModal, thingModelModalApi] = useVbenModal({
|
||||
draggable: true,
|
||||
@ -286,6 +291,14 @@ const [ThingModelModal, thingModelModalApi] = useVbenModal({
|
||||
|
||||
await formApi.setValues({
|
||||
...(isEdit ? editRow.value : {}),
|
||||
...(isEdit && {
|
||||
standardFieldFieldExtension: formatFieldExtensionForForm(
|
||||
editRow.value.standardFieldFieldExtension,
|
||||
),
|
||||
ioTPlatformRawFieldExtension: formatFieldExtensionForForm(
|
||||
editRow.value.ioTPlatformRawFieldExtension,
|
||||
),
|
||||
}),
|
||||
_ioTPlatform: platformValue,
|
||||
_ioTPlatformProductId: productIdValue,
|
||||
// 确保 identifierType 转换为字符串格式,以便与下拉框的 key 匹配
|
||||
@ -352,6 +365,105 @@ const [CopyStandardModal, copyStandardModalApi] = useVbenModal({
|
||||
},
|
||||
});
|
||||
|
||||
type OperateServiceItem = {
|
||||
key?: null | string;
|
||||
value?: null | string;
|
||||
secondValue?: null | string;
|
||||
thirdValue?: unknown;
|
||||
};
|
||||
|
||||
const commandEditRow = ref<Record<string, any>>({});
|
||||
const operateServiceLoading = ref(false);
|
||||
const createCommandLoading = ref(false);
|
||||
const operateServiceOptions = ref<OperateServiceItem[]>([]);
|
||||
const operateTypeOptions = ref<Array<{ label: string; value: number }>>([]);
|
||||
const selectedOperateType = ref<number>();
|
||||
const operateIssueCommandText = ref('');
|
||||
|
||||
function normalizeOperateTypeOptions(
|
||||
raw: unknown,
|
||||
): Array<{ label: string; value: number }> {
|
||||
if (raw == null || raw === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
let data: unknown = raw;
|
||||
if (typeof data === 'string') {
|
||||
const s = data.trim();
|
||||
if (!s) {
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
data = JSON.parse(s) as unknown;
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
return data
|
||||
.map((item: any) => {
|
||||
const valueRaw = item?.key ?? item?.value ?? item?.id ?? item?.operateType;
|
||||
const labelRaw =
|
||||
item?.value ??
|
||||
item?.label ??
|
||||
item?.name ??
|
||||
item?.displayName ??
|
||||
item?.key;
|
||||
const value = Number.parseInt(String(valueRaw ?? ''), 10);
|
||||
if (Number.isNaN(value)) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
value,
|
||||
label: String(labelRaw ?? value),
|
||||
};
|
||||
})
|
||||
.filter(Boolean) as Array<{ label: string; value: number }>;
|
||||
}
|
||||
|
||||
if (typeof data === 'object') {
|
||||
return Object.entries(data as Record<string, unknown>)
|
||||
.map(([k, v]) => {
|
||||
const value = Number.parseInt(String(k), 10);
|
||||
if (Number.isNaN(value)) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
value,
|
||||
label: String(v ?? k),
|
||||
};
|
||||
})
|
||||
.filter(Boolean) as Array<{ label: string; value: number }>;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
const [OperateCommandModal, operateCommandModalApi] = useVbenModal({
|
||||
draggable: true,
|
||||
footer: true,
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
confirmText: '添加',
|
||||
onConfirm: submitOperateCommand,
|
||||
onBeforeClose: () => {
|
||||
commandEditRow.value = {};
|
||||
operateServiceOptions.value = [];
|
||||
operateTypeOptions.value = [];
|
||||
selectedOperateType.value = undefined;
|
||||
operateIssueCommandText.value = '';
|
||||
createCommandLoading.value = false;
|
||||
return true;
|
||||
},
|
||||
onOpenChange: async (isOpen: boolean) => {
|
||||
if (!isOpen) {
|
||||
return;
|
||||
}
|
||||
await fetchOperateServiceOptions();
|
||||
},
|
||||
});
|
||||
|
||||
// 创建新增表单 schema(传入获取平台和产品ID的函数,作为后备方案)
|
||||
// 注意:实际使用时,值会从表单的 _ioTPlatform 和 _ioTPlatformProductId 字段获取
|
||||
const addThingModelFormSchema = getAddThingModelFormSchema(
|
||||
@ -522,6 +634,63 @@ onMounted(async () => {
|
||||
}, 300);
|
||||
});
|
||||
|
||||
function normalizeFieldExtensionValue(fieldValue: unknown) {
|
||||
if (typeof fieldValue !== 'string') {
|
||||
return fieldValue;
|
||||
}
|
||||
const trimmed = fieldValue.trim();
|
||||
if (!trimmed) {
|
||||
return '';
|
||||
}
|
||||
try {
|
||||
return JSON.parse(trimmed);
|
||||
} catch {
|
||||
return fieldValue;
|
||||
}
|
||||
}
|
||||
|
||||
function formatFieldExtensionForForm(fieldValue: unknown) {
|
||||
if (fieldValue == null || fieldValue === '') {
|
||||
return '';
|
||||
}
|
||||
if (typeof fieldValue === 'string') {
|
||||
return fieldValue;
|
||||
}
|
||||
try {
|
||||
return JSON.stringify(fieldValue, null, 2);
|
||||
} catch {
|
||||
return String(fieldValue);
|
||||
}
|
||||
}
|
||||
|
||||
function parseJsonFieldValue(
|
||||
fieldValue: unknown,
|
||||
fieldLabel: string,
|
||||
): { ok: boolean; value: unknown } {
|
||||
if (fieldValue == null || fieldValue === '') {
|
||||
return { ok: true, value: fieldValue };
|
||||
}
|
||||
|
||||
if (typeof fieldValue !== 'string') {
|
||||
return { ok: true, value: fieldValue };
|
||||
}
|
||||
|
||||
const trimmed = fieldValue.trim();
|
||||
if (!trimmed) {
|
||||
return { ok: true, value: '' };
|
||||
}
|
||||
|
||||
try {
|
||||
return {
|
||||
ok: true,
|
||||
value: JSON.parse(trimmed),
|
||||
};
|
||||
} catch {
|
||||
Message.error(`${fieldLabel}必须是合法JSON格式`);
|
||||
return { ok: false, value: fieldValue };
|
||||
}
|
||||
}
|
||||
|
||||
// 新增和编辑提交的逻辑
|
||||
async function submit() {
|
||||
const isEdit = !!editRow.value.id;
|
||||
@ -574,6 +743,14 @@ async function submit() {
|
||||
}
|
||||
|
||||
const formValues = await formApi.getValues();
|
||||
const ioTPlatformRawFieldExtensionParsed = parseJsonFieldValue(
|
||||
formValues.ioTPlatformRawFieldExtension,
|
||||
'平台物模型值类型扩展',
|
||||
);
|
||||
if (!ioTPlatformRawFieldExtensionParsed.ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchParams: any = {
|
||||
...formValues,
|
||||
// 自动添加平台和产品信息
|
||||
@ -588,6 +765,12 @@ async function submit() {
|
||||
}),
|
||||
// 编辑时需要添加ID
|
||||
...(isEdit && { id: editRow.value.id }),
|
||||
// 标准物模型扩展参数支持在表单中以 JSON 文本编辑,提交时转回对象
|
||||
standardFieldFieldExtension: normalizeFieldExtensionValue(
|
||||
formValues.standardFieldFieldExtension,
|
||||
),
|
||||
// 平台物模型值类型扩展必须按 JSON 格式传入后台
|
||||
ioTPlatformRawFieldExtension: ioTPlatformRawFieldExtensionParsed.value,
|
||||
};
|
||||
|
||||
try {
|
||||
@ -625,6 +808,12 @@ async function onEdit(record: any) {
|
||||
setTimeout(async () => {
|
||||
await editFormApi.setValues({
|
||||
...record,
|
||||
standardFieldFieldExtension: formatFieldExtensionForForm(
|
||||
record.standardFieldFieldExtension,
|
||||
),
|
||||
ioTPlatformRawFieldExtension: formatFieldExtensionForForm(
|
||||
record.ioTPlatformRawFieldExtension,
|
||||
),
|
||||
_ioTPlatform: platformValue,
|
||||
_ioTPlatformProductId: productIdValue,
|
||||
// 确保 identifierType 转换为字符串格式,以便与下拉框的 key 匹配
|
||||
@ -695,6 +884,148 @@ const openAddModal = async () => {
|
||||
}, 100);
|
||||
};
|
||||
|
||||
async function fetchOperateServiceOptions() {
|
||||
if (!commandEditRow.value?.ioTPlatformProductId) {
|
||||
Message.warning('当前物模型数据缺少产品ID,无法加载可操作指令');
|
||||
return;
|
||||
}
|
||||
if (!commandEditRow.value?.standardFieldName) {
|
||||
Message.warning('当前物模型数据缺少标准物模型标识符,无法加载可操作指令');
|
||||
return;
|
||||
}
|
||||
|
||||
operateServiceLoading.value = true;
|
||||
try {
|
||||
const { data } = await postIoTplatformThingModelInfoGetIoTplatformThingModelService(
|
||||
{
|
||||
body: {
|
||||
id: String(commandEditRow.value.ioTPlatformProductId),
|
||||
standardFieldName: String(commandEditRow.value.standardFieldName),
|
||||
isGetOperateService: true,
|
||||
},
|
||||
},
|
||||
);
|
||||
operateServiceOptions.value = Array.isArray(data)
|
||||
? (data as OperateServiceItem[])
|
||||
: [];
|
||||
const firstService = operateServiceOptions.value[0];
|
||||
operateTypeOptions.value = normalizeOperateTypeOptions(
|
||||
firstService?.secondValue,
|
||||
);
|
||||
selectedOperateType.value =
|
||||
operateTypeOptions.value.length > 0
|
||||
? operateTypeOptions.value[0]?.value
|
||||
: undefined;
|
||||
if (operateServiceOptions.value.length === 0) {
|
||||
Message.warning('当前属性标识符暂无可操作指令');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取可操作指令列表失败:', error);
|
||||
Message.error('获取可操作指令列表失败');
|
||||
operateServiceOptions.value = [];
|
||||
operateTypeOptions.value = [];
|
||||
selectedOperateType.value = undefined;
|
||||
} finally {
|
||||
operateServiceLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function openOperateCommandModal(record: Record<string, any>) {
|
||||
if (!record?.id) {
|
||||
Message.warning('当前物模型数据缺少ID,无法添加默认操作指令');
|
||||
return;
|
||||
}
|
||||
const filedType = String(record?.filedType ?? '');
|
||||
if (!filedType.includes('Service')) {
|
||||
Message.warning('仅服务类型物模型支持添加默认操作指令');
|
||||
return;
|
||||
}
|
||||
commandEditRow.value = record;
|
||||
operateCommandModalApi.open();
|
||||
}
|
||||
|
||||
async function submitOperateCommand() {
|
||||
if (!commandEditRow.value?.id) {
|
||||
return;
|
||||
}
|
||||
if (selectedOperateType.value == null) {
|
||||
Message.warning('请选择操作类型');
|
||||
return;
|
||||
}
|
||||
|
||||
let issueCommand = operateIssueCommandText.value.trim();
|
||||
if (!issueCommand) {
|
||||
Message.warning('请填写指令内容');
|
||||
return;
|
||||
}
|
||||
|
||||
createCommandLoading.value = true;
|
||||
try {
|
||||
const resp =
|
||||
await postIoTplatformThingModelInfoCreateIoTplatformThingModelCommand({
|
||||
body: {
|
||||
thingModelDataId: String(commandEditRow.value.id),
|
||||
operateType: selectedOperateType.value,
|
||||
issueCommand,
|
||||
},
|
||||
});
|
||||
if (resp.data) {
|
||||
Message.success('默认操作指令添加成功');
|
||||
operateCommandModalApi.close();
|
||||
await gridApi.reload();
|
||||
} else {
|
||||
Message.error('默认操作指令添加失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('默认操作指令添加失败:', error);
|
||||
Message.error('默认操作指令添加失败');
|
||||
} finally {
|
||||
createCommandLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 模型刷新
|
||||
async function onThingModelRefresh() {
|
||||
const formValues = gridApi?.formApi ? await gridApi.formApi.getValues() : {};
|
||||
const platformValue = formValues.ioTPlatform || ioTPlatform.value;
|
||||
const productIdValue = formValues.ioTPlatformProductId || productId.value;
|
||||
|
||||
if (!productIdValue) {
|
||||
Message.error('请选择产品后再刷新模型');
|
||||
return;
|
||||
}
|
||||
|
||||
const ioTPlatformType = Number.parseInt(String(platformValue || ''), 10);
|
||||
if (Number.isNaN(ioTPlatformType)) {
|
||||
Message.error('平台类型无效,无法刷新模型');
|
||||
return;
|
||||
}
|
||||
|
||||
thingModelRefreshLoading.value = true;
|
||||
try {
|
||||
const resp =
|
||||
await postAggregationIoTplatformUpdateIoTplatformProductThingModelInfoAsync(
|
||||
{
|
||||
body: {
|
||||
ioTPlatformType,
|
||||
ioTPlatformProductId: String(productIdValue),
|
||||
},
|
||||
},
|
||||
);
|
||||
if (resp.data) {
|
||||
Message.success('模型刷新成功');
|
||||
await gridApi.reload();
|
||||
} else {
|
||||
Message.error('模型刷新失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('模型刷新失败:', error);
|
||||
Message.error('模型刷新失败');
|
||||
} finally {
|
||||
thingModelRefreshLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 打开复制已有模型模态框
|
||||
const openCopyAnotherThingModelModal = async () => {
|
||||
console.log('打开复制模态框,当前参数:', {
|
||||
@ -851,6 +1182,15 @@ async function onDel(record: any) {
|
||||
ifShow: !hasData,
|
||||
disabled: !productId,
|
||||
},
|
||||
{
|
||||
label: '模型刷新',
|
||||
type: 'default',
|
||||
icon: 'ant-design:reload-outlined',
|
||||
onClick: onThingModelRefresh,
|
||||
auth: ['AbpIdentity.Users.Create'],
|
||||
disabled: !productId,
|
||||
loading: thingModelRefreshLoading,
|
||||
},
|
||||
]" />
|
||||
</template>
|
||||
|
||||
@ -912,6 +1252,14 @@ async function onDel(record: any) {
|
||||
confirm: onDel.bind(null, row),
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '指令',
|
||||
type: 'link',
|
||||
size: 'small',
|
||||
auth: ['AbpIdentity.Users.Update'],
|
||||
ifShow: String(row.filedType ?? '').includes('Service'),
|
||||
onClick: openOperateCommandModal.bind(null, row),
|
||||
},
|
||||
]" />
|
||||
</template>
|
||||
</Grid>
|
||||
@ -928,5 +1276,50 @@ async function onDel(record: any) {
|
||||
<CopyStandardModal title="复制标准模型" class="w-[600px]">
|
||||
<CopyStandardForm />
|
||||
</CopyStandardModal>
|
||||
|
||||
<OperateCommandModal title="默认操作指令添加" class="w-[640px]">
|
||||
<div v-if="operateServiceLoading" class="py-8 text-center text-gray-500">
|
||||
正在加载可操作指令列表...
|
||||
</div>
|
||||
<div v-else class="space-y-3">
|
||||
<div class="text-xs text-gray-500">
|
||||
属性标识符:{{ commandEditRow.ioTPlatformRawFieldName || '-' }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="w-24 flex-shrink-0 text-right text-sm text-gray-600">操作类型</span>
|
||||
<Select
|
||||
v-model:value="selectedOperateType"
|
||||
:options="operateTypeOptions"
|
||||
allow-clear
|
||||
class="min-w-0 flex-1"
|
||||
placeholder="请选择操作类型"
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-1">
|
||||
<div class="text-sm font-medium text-gray-700">指令内容</div>
|
||||
<Input.TextArea
|
||||
v-model:value="operateIssueCommandText"
|
||||
:rows="4"
|
||||
placeholder="请输入默认操作指令内容"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="flex w-full items-center justify-end gap-2">
|
||||
<Button @click="operateCommandModalApi.close()">
|
||||
{{ $t('common.cancel') }}
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
:loading="createCommandLoading"
|
||||
:disabled="operateServiceLoading"
|
||||
@click="submitOperateCommand"
|
||||
>
|
||||
添加
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
</OperateCommandModal>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
@ -30,6 +30,21 @@ function formatFieldExtensionCell(cellValue: unknown): string {
|
||||
return String(cellValue);
|
||||
}
|
||||
|
||||
/** 表单中的扩展字段统一转换为可编辑文本 */
|
||||
function formatFieldExtensionFormValue(fieldValue: unknown): string {
|
||||
if (fieldValue == null || fieldValue === '') {
|
||||
return '';
|
||||
}
|
||||
if (typeof fieldValue === 'string') {
|
||||
return fieldValue;
|
||||
}
|
||||
try {
|
||||
return JSON.stringify(fieldValue, null, 2);
|
||||
} catch {
|
||||
return String(fieldValue);
|
||||
}
|
||||
}
|
||||
|
||||
export const querySchema = computed(() => [
|
||||
{
|
||||
component: 'ApiSelect',
|
||||
@ -405,6 +420,10 @@ export const getAddThingModelFormSchema = (
|
||||
formValues.standardFieldValueType = (item?.extendedAttribute ?? '')
|
||||
.toString()
|
||||
.toUpperCase();
|
||||
// 选择后自动回填标准物模型扩展参数:extendedAttributeValue
|
||||
formValues.standardFieldFieldExtension = formatFieldExtensionFormValue(
|
||||
item?.extendedAttributeValue,
|
||||
);
|
||||
},
|
||||
placeholder:
|
||||
$t('common.pleaseSelect') +
|
||||
@ -425,6 +444,15 @@ export const getAddThingModelFormSchema = (
|
||||
$t('abp.thingModelInfos.StandardFieldDisplayName'),
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'Textarea',
|
||||
fieldName: 'standardFieldFieldExtension',
|
||||
label: $t('abp.thingModelInfos.StandardFieldFieldExtension'),
|
||||
componentProps: {
|
||||
rows: 4,
|
||||
placeholder: '请选择标准物模型后自动回填扩展参数(JSON格式)',
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'ApiSelect',
|
||||
fieldName: 'ioTPlatformRawFieldName',
|
||||
@ -800,9 +828,13 @@ export const getEditThingModelFormSchema = (
|
||||
disabled: true, // 编辑时禁用
|
||||
onResolve: (item: any | null) => {
|
||||
formValues.standardFieldDisplayName = item?.displayText ?? '';
|
||||
formValues.standardFieldName = item?.code ?? '';
|
||||
formValues.standardFieldValueType = (item?.extendedAttribute ?? '')
|
||||
.toString()
|
||||
.toUpperCase();
|
||||
formValues.standardFieldFieldExtension = formatFieldExtensionFormValue(
|
||||
item?.extendedAttributeValue,
|
||||
);
|
||||
},
|
||||
placeholder:
|
||||
$t('common.pleaseInput') +
|
||||
@ -821,6 +853,15 @@ export const getEditThingModelFormSchema = (
|
||||
$t('abp.thingModelInfos.StandardFieldName'),
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'Textarea',
|
||||
fieldName: 'standardFieldFieldExtension',
|
||||
label: $t('abp.thingModelInfos.StandardFieldFieldExtension'),
|
||||
componentProps: {
|
||||
rows: 4,
|
||||
placeholder: '请选择标准物模型后自动回填扩展参数(JSON格式)',
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'ApiSelect',
|
||||
fieldName: 'ioTPlatformRawFieldName',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user