平台端物模型导入导出
This commit is contained in:
parent
15cc3c7b14
commit
7d2fd92c32
@ -2489,7 +2489,7 @@ export const DeviceFirmwareInfoDtoPagedResultDtoSchema = {
|
|||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const DeviceLifeTypeEnumSchema = {
|
export const DeviceLifeTypeEnumSchema = {
|
||||||
enum: ['Unspecified', 'Production', 'FactoryTest', 'AgingSource', 'FactoryDelivery', 'Running', 'Maintenance', 'ReturnToFactory', 'Deactivated'],
|
enum: ['Unspecified', 'Production', 'FactoryTest', 'AgingSource', 'FactoryDelivery', 'Running', 'Maintenance', 'ReturnToFactory', 'Deactivated', 'Banned'],
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: `设备生命周期类型(业务运行态,与物模型上报 DataType、OneNET 连接生命周期无关)。
|
description: `设备生命周期类型(业务运行态,与物模型上报 DataType、OneNET 连接生命周期无关)。
|
||||||
软件侧可见起点为 JiShe.ServicePro.Enums.DeviceLifeTypeEnum.FactoryTest:组件完成且固件烧录通过后,上位机设置运行参数并接入平台。`
|
软件侧可见起点为 JiShe.ServicePro.Enums.DeviceLifeTypeEnum.FactoryTest:组件完成且固件烧录通过后,上位机设置运行参数并接入平台。`
|
||||||
@ -2650,7 +2650,17 @@ export const DeviceManagementInfoDtoSchema = {
|
|||||||
},
|
},
|
||||||
platformPassword: {
|
platformPassword: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: '物联网平台设备密码',
|
description: '物联网平台设备密码(目标密钥:设备切到目标平台后应当使用的鉴权密钥)',
|
||||||
|
nullable: true
|
||||||
|
},
|
||||||
|
deviceEffectiveSecKey: {
|
||||||
|
type: 'string',
|
||||||
|
description: '设备当前实际持有的密钥(生效密钥),指令报文的 AES 加密与签名用它',
|
||||||
|
nullable: true
|
||||||
|
},
|
||||||
|
pendingSecKey: {
|
||||||
|
type: 'string',
|
||||||
|
description: '已下发、等待设备确认生效的目标密钥',
|
||||||
nullable: true
|
nullable: true
|
||||||
},
|
},
|
||||||
ioTPlatformProductId: {
|
ioTPlatformProductId: {
|
||||||
@ -2801,6 +2811,14 @@ export const DeviceManagementInfoDtoSchema = {
|
|||||||
description: '最后主站地址',
|
description: '最后主站地址',
|
||||||
nullable: true
|
nullable: true
|
||||||
},
|
},
|
||||||
|
masterStationConfigs: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
'$ref': '#/components/schemas/DeviceMasterStationEndpoint'
|
||||||
|
},
|
||||||
|
description: '本次下发的主站配置集合(主用 + 备用),记录每个端点的地址与所属平台。',
|
||||||
|
nullable: true
|
||||||
|
},
|
||||||
dataPushOverride: {
|
dataPushOverride: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: '是否覆盖产品级推送配置:true 用本设备的推送配置,false 继承所属产品配置'
|
description: '是否覆盖产品级推送配置:true 用本设备的推送配置,false 继承所属产品配置'
|
||||||
@ -2951,6 +2969,26 @@ export const DeviceManagementInfoDtoPagedResultDtoHttpDataResultSchema = {
|
|||||||
description: 'HTTP 请求返回结果'
|
description: 'HTTP 请求返回结果'
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export const DeviceMasterStationEndpointSchema = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
masterStationAddress: {
|
||||||
|
type: 'string',
|
||||||
|
description: '主站地址(host:port)',
|
||||||
|
nullable: true
|
||||||
|
},
|
||||||
|
ioTPlatform: {
|
||||||
|
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
additionalProperties: false,
|
||||||
|
description: `设备主站端点:一个主站的地址 + 所属物联网平台。
|
||||||
|
设备一次切主站会下发主用 + 备用两个端点,主备共用同一把接入密钥。
|
||||||
|
服务端据此在切换确认后判断"主或备是否含 OneNET",进而决定是否要把设备当前密钥同步到 OneNET(一机一密)——
|
||||||
|
否则设备自主回落到 OneNET 备用主站时,OneNET 侧仍是旧密钥、鉴权不过、连不上也报不了事件,彻底失联。
|
||||||
|
以 JSON 序列化存 jsonb,供实体 / DTO / 缓存共用。`
|
||||||
|
} as const;
|
||||||
|
|
||||||
export const DeviceMasterSwitchInputSchema = {
|
export const DeviceMasterSwitchInputSchema = {
|
||||||
required: ['backupMasterStation', 'id', 'ioTPlatformProductId', 'masterStation'],
|
required: ['backupMasterStation', 'id', 'ioTPlatformProductId', 'masterStation'],
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@ -4479,6 +4517,23 @@ export const EntityExtensionDtoSchema = {
|
|||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export const ExportPlatformThingModelInputSchema = {
|
||||||
|
required: ['ioTPlatformProductId'],
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
ioTPlatformProductId: {
|
||||||
|
minLength: 1,
|
||||||
|
type: 'string',
|
||||||
|
description: '平台产品ID'
|
||||||
|
},
|
||||||
|
platform: {
|
||||||
|
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
additionalProperties: false,
|
||||||
|
description: '导出平台端物模型入参(单个产品)'
|
||||||
|
} as const;
|
||||||
|
|
||||||
export const ExtensionEnumDtoSchema = {
|
export const ExtensionEnumDtoSchema = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
@ -6381,6 +6436,43 @@ export const IdentityUserUpdateDtoSchema = {
|
|||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export const ImportPlatformThingModelResultDtoSchema = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
ioTPlatformProductId: {
|
||||||
|
type: 'string',
|
||||||
|
description: '导入目标产品ID',
|
||||||
|
nullable: true
|
||||||
|
},
|
||||||
|
sourceProductId: {
|
||||||
|
type: 'string',
|
||||||
|
description: '导入文件中记录的源产品ID',
|
||||||
|
nullable: true
|
||||||
|
},
|
||||||
|
thingModelCount: {
|
||||||
|
type: 'integer',
|
||||||
|
description: '导入的物模型标识符条数',
|
||||||
|
format: 'int32'
|
||||||
|
},
|
||||||
|
extensionCount: {
|
||||||
|
type: 'integer',
|
||||||
|
description: '导入的扩展子字段条数',
|
||||||
|
format: 'int32'
|
||||||
|
},
|
||||||
|
commandCount: {
|
||||||
|
type: 'integer',
|
||||||
|
description: '导入的默认操作指令条数',
|
||||||
|
format: 'int32'
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
type: 'boolean',
|
||||||
|
description: '是否导入成功(已覆盖数据库并刷新 Redis 缓存)'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
additionalProperties: false,
|
||||||
|
description: '平台端物模型导入结果(单个产品)'
|
||||||
|
} as const;
|
||||||
|
|
||||||
export const InterfaceMethodApiDescriptionModelSchema = {
|
export const InterfaceMethodApiDescriptionModelSchema = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -1410,7 +1410,7 @@ export type DeviceFirmwareInfoDtoPagedResultDto = {
|
|||||||
* 设备生命周期类型(业务运行态,与物模型上报 DataType、OneNET 连接生命周期无关)。
|
* 设备生命周期类型(业务运行态,与物模型上报 DataType、OneNET 连接生命周期无关)。
|
||||||
* 软件侧可见起点为 JiShe.ServicePro.Enums.DeviceLifeTypeEnum.FactoryTest:组件完成且固件烧录通过后,上位机设置运行参数并接入平台。
|
* 软件侧可见起点为 JiShe.ServicePro.Enums.DeviceLifeTypeEnum.FactoryTest:组件完成且固件烧录通过后,上位机设置运行参数并接入平台。
|
||||||
*/
|
*/
|
||||||
export type DeviceLifeTypeEnum = 'Unspecified' | 'Production' | 'FactoryTest' | 'AgingSource' | 'FactoryDelivery' | 'Running' | 'Maintenance' | 'ReturnToFactory' | 'Deactivated';
|
export type DeviceLifeTypeEnum = 'Unspecified' | 'Production' | 'FactoryTest' | 'AgingSource' | 'FactoryDelivery' | 'Running' | 'Maintenance' | 'ReturnToFactory' | 'Deactivated' | 'Banned';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设备登录(EMQX HTTP 认证回调请求体)
|
* 设备登录(EMQX HTTP 认证回调请求体)
|
||||||
@ -1507,9 +1507,17 @@ export type DeviceManagementInfoDto = {
|
|||||||
*/
|
*/
|
||||||
ioTPlatformDeviceOpenInfo?: (string) | null;
|
ioTPlatformDeviceOpenInfo?: (string) | null;
|
||||||
/**
|
/**
|
||||||
* 物联网平台设备密码
|
* 物联网平台设备密码(目标密钥:设备切到目标平台后应当使用的鉴权密钥)
|
||||||
*/
|
*/
|
||||||
platformPassword?: (string) | null;
|
platformPassword?: (string) | null;
|
||||||
|
/**
|
||||||
|
* 设备当前实际持有的密钥(生效密钥),指令报文的 AES 加密与签名用它
|
||||||
|
*/
|
||||||
|
deviceEffectiveSecKey?: (string) | null;
|
||||||
|
/**
|
||||||
|
* 已下发、等待设备确认生效的目标密钥
|
||||||
|
*/
|
||||||
|
pendingSecKey?: (string) | null;
|
||||||
/**
|
/**
|
||||||
* 物联网平台中对应的产品Id
|
* 物联网平台中对应的产品Id
|
||||||
*/
|
*/
|
||||||
@ -1610,6 +1618,10 @@ export type DeviceManagementInfoDto = {
|
|||||||
* 最后主站地址
|
* 最后主站地址
|
||||||
*/
|
*/
|
||||||
finalMainStation?: (string) | null;
|
finalMainStation?: (string) | null;
|
||||||
|
/**
|
||||||
|
* 本次下发的主站配置集合(主用 + 备用),记录每个端点的地址与所属平台。
|
||||||
|
*/
|
||||||
|
masterStationConfigs?: Array<DeviceMasterStationEndpoint> | null;
|
||||||
/**
|
/**
|
||||||
* 是否覆盖产品级推送配置:true 用本设备的推送配置,false 继承所属产品配置
|
* 是否覆盖产品级推送配置:true 用本设备的推送配置,false 继承所属产品配置
|
||||||
*/
|
*/
|
||||||
@ -1713,6 +1725,21 @@ export type DeviceManagementInfoDtoPagedResultDtoHttpDataResult = {
|
|||||||
total?: number;
|
total?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备主站端点:一个主站的地址 + 所属物联网平台。
|
||||||
|
* 设备一次切主站会下发主用 + 备用两个端点,主备共用同一把接入密钥。
|
||||||
|
* 服务端据此在切换确认后判断"主或备是否含 OneNET",进而决定是否要把设备当前密钥同步到 OneNET(一机一密)——
|
||||||
|
* 否则设备自主回落到 OneNET 备用主站时,OneNET 侧仍是旧密钥、鉴权不过、连不上也报不了事件,彻底失联。
|
||||||
|
* 以 JSON 序列化存 jsonb,供实体 / DTO / 缓存共用。
|
||||||
|
*/
|
||||||
|
export type DeviceMasterStationEndpoint = {
|
||||||
|
/**
|
||||||
|
* 主站地址(host:port)
|
||||||
|
*/
|
||||||
|
masterStationAddress?: (string) | null;
|
||||||
|
ioTPlatform?: IoTPlatformTypeEnum;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设备切换主站入参
|
* 设备切换主站入参
|
||||||
*/
|
*/
|
||||||
@ -2685,6 +2712,17 @@ export type EntityExtensionDto = {
|
|||||||
} | null;
|
} | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出平台端物模型入参(单个产品)
|
||||||
|
*/
|
||||||
|
export type ExportPlatformThingModelInput = {
|
||||||
|
/**
|
||||||
|
* 平台产品ID
|
||||||
|
*/
|
||||||
|
ioTPlatformProductId: string;
|
||||||
|
platform?: IoTPlatformTypeEnum;
|
||||||
|
};
|
||||||
|
|
||||||
export type ExtensionEnumDto = {
|
export type ExtensionEnumDto = {
|
||||||
fields?: Array<ExtensionEnumFieldDto> | null;
|
fields?: Array<ExtensionEnumFieldDto> | null;
|
||||||
localizationResource?: (string) | null;
|
localizationResource?: (string) | null;
|
||||||
@ -3381,6 +3419,36 @@ export type IdInput = {
|
|||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平台端物模型导入结果(单个产品)
|
||||||
|
*/
|
||||||
|
export type ImportPlatformThingModelResultDto = {
|
||||||
|
/**
|
||||||
|
* 导入目标产品ID
|
||||||
|
*/
|
||||||
|
ioTPlatformProductId?: (string) | null;
|
||||||
|
/**
|
||||||
|
* 导入文件中记录的源产品ID
|
||||||
|
*/
|
||||||
|
sourceProductId?: (string) | null;
|
||||||
|
/**
|
||||||
|
* 导入的物模型标识符条数
|
||||||
|
*/
|
||||||
|
thingModelCount?: number;
|
||||||
|
/**
|
||||||
|
* 导入的扩展子字段条数
|
||||||
|
*/
|
||||||
|
extensionCount?: number;
|
||||||
|
/**
|
||||||
|
* 导入的默认操作指令条数
|
||||||
|
*/
|
||||||
|
commandCount?: number;
|
||||||
|
/**
|
||||||
|
* 是否导入成功(已覆盖数据库并刷新 Redis 缓存)
|
||||||
|
*/
|
||||||
|
success?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export type InterfaceMethodApiDescriptionModel = {
|
export type InterfaceMethodApiDescriptionModel = {
|
||||||
name?: (string) | null;
|
name?: (string) | null;
|
||||||
parametersOnMethod?: Array<MethodParameterApiDescriptionModel> | null;
|
parametersOnMethod?: Array<MethodParameterApiDescriptionModel> | null;
|
||||||
@ -8187,6 +8255,42 @@ export type PostIoTplatformThingModelInfoCreateIoTplatformThingModelCommandRespo
|
|||||||
|
|
||||||
export type PostIoTplatformThingModelInfoCreateIoTplatformThingModelCommandError = unknown;
|
export type PostIoTplatformThingModelInfoCreateIoTplatformThingModelCommandError = unknown;
|
||||||
|
|
||||||
|
export type PostIoTplatformThingModelInfoExportPlatformThingModelData = {
|
||||||
|
query?: {
|
||||||
|
/**
|
||||||
|
* 导出参数(产品ID 必填,平台类型默认 OneNET)
|
||||||
|
*/
|
||||||
|
input?: ExportPlatformThingModelInput;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PostIoTplatformThingModelInfoExportPlatformThingModelResponse = ((Blob | File));
|
||||||
|
|
||||||
|
export type PostIoTplatformThingModelInfoExportPlatformThingModelError = unknown;
|
||||||
|
|
||||||
|
export type PostIoTplatformThingModelInfoImportPlatformThingModelData = {
|
||||||
|
body?: {
|
||||||
|
/**
|
||||||
|
* 导出的 JSON 文件
|
||||||
|
*/
|
||||||
|
file?: (Blob | File);
|
||||||
|
};
|
||||||
|
query?: {
|
||||||
|
/**
|
||||||
|
* 导入目标产品ID
|
||||||
|
*/
|
||||||
|
ioTPlatformProductId?: string;
|
||||||
|
/**
|
||||||
|
* 平台类型,默认 OneNET
|
||||||
|
*/
|
||||||
|
platform?: IoTPlatformTypeEnum;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PostIoTplatformThingModelInfoImportPlatformThingModelResponse = (ImportPlatformThingModelResultDto);
|
||||||
|
|
||||||
|
export type PostIoTplatformThingModelInfoImportPlatformThingModelError = unknown;
|
||||||
|
|
||||||
export type PostLanguagesAllResponse = (Array<PageLanguageOutput>);
|
export type PostLanguagesAllResponse = (Array<PageLanguageOutput>);
|
||||||
|
|
||||||
export type PostLanguagesAllError = (RemoteServiceErrorResponse);
|
export type PostLanguagesAllError = (RemoteServiceErrorResponse);
|
||||||
|
|||||||
@ -19,7 +19,9 @@ import {
|
|||||||
postIoTplatformThingModelInfoCopyStandardThingModel,
|
postIoTplatformThingModelInfoCopyStandardThingModel,
|
||||||
postIoTplatformThingModelInfoCreateAsync,
|
postIoTplatformThingModelInfoCreateAsync,
|
||||||
postIoTplatformThingModelInfoDeleteAsync,
|
postIoTplatformThingModelInfoDeleteAsync,
|
||||||
|
postIoTplatformThingModelInfoExportPlatformThingModel,
|
||||||
postIoTplatformThingModelInfoGetIoTplatformThingModelService,
|
postIoTplatformThingModelInfoGetIoTplatformThingModelService,
|
||||||
|
postIoTplatformThingModelInfoImportPlatformThingModel,
|
||||||
postIoTplatformThingModelInfoPageAsync,
|
postIoTplatformThingModelInfoPageAsync,
|
||||||
postIoTplatformThingModelInfoUpdateAsync,
|
postIoTplatformThingModelInfoUpdateAsync,
|
||||||
} from '#/api-client';
|
} from '#/api-client';
|
||||||
@ -229,6 +231,11 @@ const editRow: Record<string, any> = ref({});
|
|||||||
const hasData = ref(true);
|
const hasData = ref(true);
|
||||||
// 模型刷新按钮 loading 状态
|
// 模型刷新按钮 loading 状态
|
||||||
const thingModelRefreshLoading = ref(false);
|
const thingModelRefreshLoading = ref(false);
|
||||||
|
// 导出/导入按钮 loading 状态
|
||||||
|
const exportLoading = ref(false);
|
||||||
|
const importLoading = ref(false);
|
||||||
|
// 导入文件选择框引用(隐藏 input)
|
||||||
|
const importFileInputRef = ref<HTMLInputElement | null>(null);
|
||||||
|
|
||||||
const [ThingModelModal, thingModelModalApi] = useVbenModal({
|
const [ThingModelModal, thingModelModalApi] = useVbenModal({
|
||||||
draggable: true,
|
draggable: true,
|
||||||
@ -1063,6 +1070,121 @@ async function onThingModelRefresh() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取当前搜索表单中的平台/产品(导出、导入共用)
|
||||||
|
async function getCurrentPlatformAndProduct() {
|
||||||
|
const formValues = gridApi?.formApi ? await gridApi.formApi.getValues() : {};
|
||||||
|
const currentProductId = String(
|
||||||
|
formValues.ioTPlatformProductId || productId.value || '',
|
||||||
|
);
|
||||||
|
const platformNum =
|
||||||
|
Number.parseInt(
|
||||||
|
String(formValues.ioTPlatform || ioTPlatform.value || '2'),
|
||||||
|
10,
|
||||||
|
) || 2;
|
||||||
|
return { currentProductId, platformNum };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出当前产品的平台端物模型 JSON
|
||||||
|
async function onExportThingModel() {
|
||||||
|
const { currentProductId, platformNum } =
|
||||||
|
await getCurrentPlatformAndProduct();
|
||||||
|
if (!currentProductId) {
|
||||||
|
Message.error('请先选择产品再导出');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!hasData.value) {
|
||||||
|
Message.error('当前产品暂无可导出的平台端物模型');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
exportLoading.value = true;
|
||||||
|
try {
|
||||||
|
const { data } = await postIoTplatformThingModelInfoExportPlatformThingModel(
|
||||||
|
{
|
||||||
|
// 后端复杂入参按 body 绑定(生成的 query.input 为 nswag 产物)
|
||||||
|
body: {
|
||||||
|
ioTPlatformProductId: currentProductId,
|
||||||
|
platform: platformNum,
|
||||||
|
},
|
||||||
|
responseType: 'blob',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const url = window.URL.createObjectURL(new Blob([data as Blob]));
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
const now = new Date();
|
||||||
|
const pad = (n: number) => String(n).padStart(2, '0');
|
||||||
|
const stamp = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
|
||||||
|
link.setAttribute(
|
||||||
|
'download',
|
||||||
|
`平台端物模型_${currentProductId}_${stamp}.json`,
|
||||||
|
);
|
||||||
|
document.body.append(link);
|
||||||
|
link.click();
|
||||||
|
link.remove();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
Message.success('导出成功');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('导出平台端物模型失败:', error);
|
||||||
|
Message.error('导出失败,请确认该产品已配置平台端物模型');
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触发隐藏文件选择框
|
||||||
|
function triggerImportThingModel() {
|
||||||
|
if (!productId.value) {
|
||||||
|
Message.error('请先选择导入目标产品');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
importFileInputRef.value?.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择文件后执行导入
|
||||||
|
async function onImportThingModelFileChange(e: Event) {
|
||||||
|
const input = e.target as HTMLInputElement;
|
||||||
|
const file = input.files?.[0];
|
||||||
|
// 重置 input 值,保证同一文件可再次选择触发 change
|
||||||
|
input.value = '';
|
||||||
|
if (!file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { currentProductId, platformNum } =
|
||||||
|
await getCurrentPlatformAndProduct();
|
||||||
|
if (!currentProductId) {
|
||||||
|
Message.error('请先选择导入目标产品');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
importLoading.value = true;
|
||||||
|
try {
|
||||||
|
const { data } = await postIoTplatformThingModelInfoImportPlatformThingModel(
|
||||||
|
{
|
||||||
|
query: {
|
||||||
|
ioTPlatformProductId: currentProductId,
|
||||||
|
platform: platformNum as any,
|
||||||
|
},
|
||||||
|
body: { file },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (data?.success) {
|
||||||
|
Message.success(
|
||||||
|
`导入成功:物模型 ${data.thingModelCount ?? 0} 条、扩展 ${data.extensionCount ?? 0} 条、指令 ${data.commandCount ?? 0} 条`,
|
||||||
|
);
|
||||||
|
await gridApi.reload();
|
||||||
|
} else {
|
||||||
|
Message.error('导入失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// 具体失败原因(如目标产品不存在、文件解析失败)由全局错误拦截器统一提示
|
||||||
|
console.error('导入平台端物模型失败:', error);
|
||||||
|
} finally {
|
||||||
|
importLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 打开复制已有模型模态框
|
// 打开复制已有模型模态框
|
||||||
const openCopyAnotherThingModelModal = async () => {
|
const openCopyAnotherThingModelModal = async () => {
|
||||||
console.log('打开复制模态框,当前参数:', {
|
console.log('打开复制模态框,当前参数:', {
|
||||||
@ -1228,6 +1350,24 @@ async function onDel(record: any) {
|
|||||||
disabled: !productId,
|
disabled: !productId,
|
||||||
loading: thingModelRefreshLoading,
|
loading: thingModelRefreshLoading,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '导出JSON',
|
||||||
|
type: 'default',
|
||||||
|
icon: 'ant-design:download-outlined',
|
||||||
|
onClick: onExportThingModel,
|
||||||
|
auth: ['AbpIdentity.Users.Create'],
|
||||||
|
disabled: !productId,
|
||||||
|
loading: exportLoading,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '导入JSON',
|
||||||
|
type: 'default',
|
||||||
|
icon: 'ant-design:upload-outlined',
|
||||||
|
onClick: triggerImportThingModel,
|
||||||
|
auth: ['AbpIdentity.Users.Create'],
|
||||||
|
disabled: !productId,
|
||||||
|
loading: importLoading,
|
||||||
|
},
|
||||||
]" />
|
]" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -1300,6 +1440,15 @@ async function onDel(record: any) {
|
|||||||
]" />
|
]" />
|
||||||
</template>
|
</template>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<!-- 隐藏的导入文件选择框 -->
|
||||||
|
<input
|
||||||
|
ref="importFileInputRef"
|
||||||
|
type="file"
|
||||||
|
accept=".json,application/json"
|
||||||
|
style="display: none"
|
||||||
|
@change="onImportThingModelFileChange"
|
||||||
|
/>
|
||||||
|
|
||||||
<ThingModelModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
|
<ThingModelModal :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>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user