完善设备端物模型管理

This commit is contained in:
ChenYi 2025-12-24 11:51:37 +08:00
parent 0ffc2a3098
commit 142584be52
8 changed files with 837 additions and 682 deletions

View File

@ -1312,20 +1312,23 @@ export const CopyIoTPlatformThingModelToDeviceInputSchema = {
} as const;
export const CopyStandardThingModelInputSchema = {
required: ['filedTypes', 'ioTPlatform', 'ioTPlatformProductId'],
type: 'object',
properties: {
filedType: {
type: 'string',
description: '物联网平台中对应产品物模型属性或者事件类型 JiShe.ServicePro.Core.DataDictionaryTypeConst',
nullable: true
filedTypes: {
type: 'array',
items: {
type: 'string'
},
description: '物联网平台中对应产品物模型属性或者事件类型 JiShe.ServicePro.Core.DataDictionaryTypeConst'
},
ioTPlatform: {
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
},
ioTPlatformProductId: {
minLength: 1,
type: 'string',
description: '平台产品ID',
nullable: true
description: '平台产品ID'
},
dataDictionaries: {
type: 'array',
@ -2990,6 +2993,11 @@ export const DeviceThingModelPropertyInfoDtoSchema = {
description: '反转获取数量',
format: 'int32',
nullable: true
},
filedTypeName: {
type: 'string',
description: '物模型属性或者事件类型名称',
nullable: true
}
},
additionalProperties: false,
@ -5492,6 +5500,11 @@ export const IoTPlatformThingModelInfoDtoSchema = {
type: 'string',
description: '物联网平台中对应产品物模型标识符扩展,用于扩展结构体类型',
nullable: true
},
filedTypeName: {
type: 'string',
description: '物模型属性或者事件类型名称',
nullable: true
}
},
additionalProperties: false,

View File

@ -547,7 +547,7 @@ export const postDeviceThingModelManagementBuildAnalysisScriptAsync = <ThrowOnEr
};
/**
* ID将解析脚本更新Redis并发布订阅
* ID和解析标识决定是否将解析脚本更新Redis并发布订阅
*/
export const postDeviceThingModelManagementUpdateAnalysisScriptByIdAsync = <ThrowOnError extends boolean = false>(options?: Options<PostDeviceThingModelManagementUpdateAnalysisScriptByIdAsyncData, ThrowOnError>) => {
return (options?.client ?? client).post<PostDeviceThingModelManagementUpdateAnalysisScriptByIdAsyncResponse, PostDeviceThingModelManagementUpdateAnalysisScriptByIdAsyncError, ThrowOnError>({

View File

@ -302,12 +302,12 @@ export type CopyStandardThingModelInput = {
/**
* JiShe.ServicePro.Core.DataDictionaryTypeConst
*/
filedType?: (string) | null;
ioTPlatform?: IoTPlatformTypeEnum;
filedTypes: Array<(string)>;
ioTPlatform: IoTPlatformTypeEnum;
/**
* ID
*/
ioTPlatformProductId?: (string) | null;
ioTPlatformProductId: string;
/**
*
*/
@ -1712,6 +1712,10 @@ export type DeviceThingModelPropertyInfoDto = {
*
*/
reversalTakeNumber?: (number) | null;
/**
*
*/
filedTypeName?: (string) | null;
};
export type DeviceThingModelPropertyInfoDtoPagedResultDto = {
@ -2782,6 +2786,10 @@ export type IoTPlatformThingModelInfoDto = {
*
*/
ioTPlatformRawFieldExtension?: (string) | null;
/**
*
*/
filedTypeName?: (string) | null;
};
export type IoTPlatformThingModelInfoDtoPagedResultDto = {

View File

@ -44,7 +44,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
gridOptions: {
columns: [
{
field: 'filedType',
field: 'filedTypeName',
title: '物模型类型',
minWidth: 160,
showOverflow: 'tooltip',
@ -223,6 +223,7 @@ const [EditPropertyFormModal, editPropertyFormModalApi] = useVbenModal({
//
const [CopyPropertyModal, copyPropertyModalApi] = useVbenModal({
draggable: true,
centered: true,
footer: true,
showCancelButton: true,
showConfirmButton: true,
@ -598,16 +599,16 @@ watch(
},
);
//
//
const [CopyPropertyForm, copyPropertyFormApi] = useVbenForm({
collapsed: false,
commonConfig: {
labelWidth: 140,
componentProps: {
class: 'w-4/5',
class: 'w-full',
},
},
layout: 'horizontal',
layout: 'vertical',
schema: [
{
component: 'ApiSelect',
@ -690,7 +691,7 @@ const [CopyPropertyForm, copyPropertyFormApi] = useVbenForm({
],
showCollapseButton: false,
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
wrapperClass: 'grid-cols-1',
});
//

View File

@ -634,14 +634,14 @@ onMounted(async () => {
auth: ['AbpIdentity.Users.Update'],
onClick: openPropertyModal.bind(null, row),
},
{
label: '指令管理',
type: 'link',
size: 'small',
auth: ['AbpIdentity.Users.Update'],
onClick: openCommandModal.bind(null, row),
},
]" :drop-down-actions="[
{
label: '指令管理',
type: 'link',
size: 'small',
auth: ['AbpIdentity.Users.Update'],
onClick: openCommandModal.bind(null, row),
},
{
label: row.functionAnalysisFlag ? '禁用解析' : '启用解析',
type: 'input',

View File

@ -152,7 +152,7 @@ export const tableSchema = computed(() => [
{
field: 'action',
title: $t('common.action'),
width: 160,
width: 250,
fixed: 'right',
slots: { default: 'action' },
},

View File

@ -23,8 +23,9 @@ import { TableAction } from '#/components/table-action';
import { $t } from '#/locales';
import {
getAddThingModelFormSchema,
copyStandardThingModelFormSchema,
copyThingModelFormSchema,
getAddThingModelFormSchema,
getEditThingModelFormSchema,
querySchema,
tableSchema,
@ -44,26 +45,28 @@ const ioTPlatform = ref<string>((route.query.ioTPlatform as string) || '2');
const formOptions: VbenFormProps = {
schema: querySchema.value,
initialValues: {
ioTPlatform: route.query.ioTPlatform ? String(route.query.ioTPlatform) : undefined,
ioTPlatformProductId: route.query.productId ? String(route.query.productId) : undefined,
ioTPlatform: route.query.ioTPlatform
? String(route.query.ioTPlatform)
: undefined,
ioTPlatformProductId: route.query.productId
? String(route.query.productId)
: undefined,
},
submitOnChange: false,
handleValuesChange: async (values, changedFields) => {
// ID
if (changedFields.includes('ioTPlatform')) {
if (values.ioTPlatform) {
ioTPlatform.value = String(values.ioTPlatform);
// ID
if (gridApi?.formApi) {
await gridApi.formApi.setValues({
ioTPlatformProductId: undefined,
});
}
productId.value = '';
productName.value = '';
if (changedFields.includes('ioTPlatform') && values.ioTPlatform) {
ioTPlatform.value = String(values.ioTPlatform);
// ID
if (gridApi?.formApi) {
await gridApi.formApi.setValues({
ioTPlatformProductId: undefined,
});
}
productId.value = '';
productName.value = '';
}
// ID
if (changedFields.includes('ioTPlatformProductId')) {
if (values.ioTPlatformProductId) {
@ -74,7 +77,7 @@ const formOptions: VbenFormProps = {
productId.value = '';
productName.value = '';
}
//
await nextTick();
setTimeout(async () => {
@ -115,7 +118,7 @@ const gridOptions: VxeGridProps<any> = {
: formValues || {};
// 使API使formValues
const finalFormValues = { ...(formValues || {}), ...currentFormValues };
const finalFormValues = { ...formValues, ...currentFormValues };
const currentPlatform = finalFormValues?.ioTPlatform;
const currentProductId = finalFormValues?.ioTPlatformProductId;
@ -135,7 +138,9 @@ const gridOptions: VxeGridProps<any> = {
//
if (currentPlatform) {
queryParams.ioTPlatform = Number.parseInt(String(currentPlatform)) as 1 | 2;
queryParams.ioTPlatform = Number.parseInt(
String(currentPlatform),
) as 1 | 2;
}
// ID
@ -184,29 +189,31 @@ const [ThingModelModal, thingModelModalApi] = useVbenModal({
await nextTick();
const formApi = editRow.value.id ? editFormApi : addFormApi;
const isEdit = !!editRow.value.id;
//
let platformValue: 1 | 2;
let productIdValue: string;
if (isEdit) {
// editRow.value
platformValue = editRow.value.ioTPlatform
? (typeof editRow.value.ioTPlatform === 'string'
? Number.parseInt(editRow.value.ioTPlatform)
: editRow.value.ioTPlatform) as 1 | 2
: Number.parseInt(ioTPlatform.value) as 1 | 2;
? ((typeof editRow.value.ioTPlatform === 'string'
? Number.parseInt(editRow.value.ioTPlatform)
: editRow.value.ioTPlatform) as 1 | 2)
: (Number.parseInt(ioTPlatform.value) as 1 | 2);
productIdValue = editRow.value.ioTPlatformProductId || productId.value;
} else {
//
const formValues = gridApi?.formApi ? await gridApi.formApi.getValues() : {};
const formValues = gridApi?.formApi
? await gridApi.formApi.getValues()
: {};
platformValue = formValues.ioTPlatform
? (typeof formValues.ioTPlatform === 'string'
? Number.parseInt(formValues.ioTPlatform)
: formValues.ioTPlatform) as 1 | 2
: Number.parseInt(ioTPlatform.value) as 1 | 2;
? ((typeof formValues.ioTPlatform === 'string'
? Number.parseInt(formValues.ioTPlatform)
: formValues.ioTPlatform) as 1 | 2)
: (Number.parseInt(ioTPlatform.value) as 1 | 2);
productIdValue = formValues.ioTPlatformProductId || productId.value;
//
if (formValues.ioTPlatform) {
ioTPlatform.value = String(formValues.ioTPlatform);
@ -215,23 +222,25 @@ const [ThingModelModal, thingModelModalApi] = useVbenModal({
productId.value = String(formValues.ioTPlatformProductId);
}
}
console.log('设置表单值:', {
isEdit,
platformValue,
productIdValue,
editRowValue: isEdit ? editRow.value : null,
});
await formApi.setValues({
...(isEdit ? editRow.value : {}),
_ioTPlatform: platformValue,
_ioTPlatformProductId: productIdValue,
});
//
setTimeout(() => {
const fieldRef = formApi.getFieldComponentRef('ioTPlatformRawFieldName');
const fieldRef = formApi.getFieldComponentRef(
'ioTPlatformRawFieldName',
);
if (fieldRef && typeof fieldRef.updateParam === 'function') {
fieldRef.updateParam({
body: {
@ -262,12 +271,29 @@ const [CopyModal, copyModalApi] = useVbenModal({
},
});
//
const [CopyStandardModal, copyStandardModalApi] = useVbenModal({
draggable: true,
footer: true,
showCancelButton: true,
showConfirmButton: true,
onConfirm: submitCopyStandard,
onBeforeClose: () => {
return true;
},
onCancel: () => {
copyStandardModalApi.close();
},
});
// schemaID
// 使 _ioTPlatform _ioTPlatformProductId
const addThingModelFormSchema = getAddThingModelFormSchema(
() => {
//
return ioTPlatform.value ? Number.parseInt(ioTPlatform.value) as 1 | 2 : undefined;
return ioTPlatform.value
? (Number.parseInt(ioTPlatform.value) as 1 | 2)
: undefined;
},
() => {
//
@ -301,7 +327,9 @@ const editThingModelFormSchema = getEditThingModelFormSchema(
: editRow.value.ioTPlatform;
}
// 使
return ioTPlatform.value ? Number.parseInt(ioTPlatform.value) as 1 | 2 : undefined;
return ioTPlatform.value
? (Number.parseInt(ioTPlatform.value) as 1 | 2)
: undefined;
},
() => {
// editRow
@ -340,6 +368,22 @@ const [CopyForm, copyFormApi] = useVbenForm({
wrapperClass: 'grid-cols-2',
});
//
const [CopyStandardForm, copyStandardFormApi] = useVbenForm({
collapsed: false,
commonConfig: {
labelWidth: 160,
componentProps: {
class: 'w-4/5',
},
},
layout: 'horizontal',
schema: copyStandardThingModelFormSchema.value,
showCollapseButton: false,
showDefaultActions: false,
wrapperClass: 'grid-cols-1',
});
//
watch(
() => [route.query.productId, route.query.ioTPlatform],
@ -353,7 +397,7 @@ watch(
if (route.query.productName) {
productName.value = route.query.productName as string;
}
//
if (gridApi) {
setTimeout(async () => {
@ -380,7 +424,7 @@ onMounted(async () => {
if (route.query.ioTPlatform) {
ioTPlatform.value = route.query.ioTPlatform as string;
}
//
// 使 productId
await nextTick();
@ -425,7 +469,7 @@ async function submit() {
const { valid } = await formApi.validate();
if (!valid) return;
const formValues = await formApi.getValues();
const formValues = await formApi.getValues();
const fetchParams: any = {
...formValues,
//
@ -451,9 +495,6 @@ async function submit() {
}
} catch (error) {
console.error('提交失败:', error);
Message.error(
editRow.value.id ? $t('common.editFail') : $t('common.addFail'),
);
}
}
@ -461,12 +502,12 @@ async function onEdit(record: any) {
editRow.value = record;
// ID
const platformValue = record.ioTPlatform
? (typeof record.ioTPlatform === 'string'
? Number.parseInt(record.ioTPlatform)
: record.ioTPlatform) as 1 | 2
: Number.parseInt(ioTPlatform.value) as 1 | 2;
? ((typeof record.ioTPlatform === 'string'
? Number.parseInt(record.ioTPlatform)
: record.ioTPlatform) as 1 | 2)
: (Number.parseInt(ioTPlatform.value) as 1 | 2);
const productIdValue = record.ioTPlatformProductId || productId.value;
thingModelModalApi.open();
await nextTick();
setTimeout(async () => {
@ -475,9 +516,11 @@ async function onEdit(record: any) {
_ioTPlatform: platformValue,
_ioTPlatformProductId: productIdValue,
});
//
const fieldRef = editFormApi.getFieldComponentRef('ioTPlatformRawFieldName');
const fieldRef = editFormApi.getFieldComponentRef(
'ioTPlatformRawFieldName',
);
if (fieldRef && typeof fieldRef.updateParam === 'function') {
fieldRef.updateParam({
body: {
@ -494,12 +537,12 @@ const openAddModal = async () => {
// ID
const formValues = gridApi?.formApi ? await gridApi.formApi.getValues() : {};
const platformValue = formValues.ioTPlatform
? (typeof formValues.ioTPlatform === 'string'
? Number.parseInt(formValues.ioTPlatform)
: formValues.ioTPlatform) as 1 | 2
: Number.parseInt(ioTPlatform.value) as 1 | 2;
? ((typeof formValues.ioTPlatform === 'string'
? Number.parseInt(formValues.ioTPlatform)
: formValues.ioTPlatform) as 1 | 2)
: (Number.parseInt(ioTPlatform.value) as 1 | 2);
const productIdValue = formValues.ioTPlatformProductId || productId.value;
//
if (formValues.ioTPlatform) {
ioTPlatform.value = String(formValues.ioTPlatform);
@ -507,7 +550,7 @@ const openAddModal = async () => {
if (formValues.ioTPlatformProductId) {
productId.value = String(formValues.ioTPlatformProductId);
}
thingModelModalApi.open();
//
await nextTick();
@ -516,7 +559,7 @@ const openAddModal = async () => {
_ioTPlatform: platformValue,
_ioTPlatformProductId: productIdValue,
});
//
const fieldRef = addFormApi.getFieldComponentRef('ioTPlatformRawFieldName');
if (fieldRef && typeof fieldRef.updateParam === 'function') {
@ -580,7 +623,59 @@ async function submitCopy() {
}
} catch (error) {
console.error('复制模型失败:', error);
Message.error('复制模型失败');
}
}
//
const openCopyStandardThingModelModal = () => {
console.log('打开复制标准模型模态框,当前参数:', {
productId: productId.value,
productName: productName.value,
ioTPlatform: ioTPlatform.value,
});
copyStandardModalApi.open();
};
//
async function submitCopyStandard() {
// ID
if (!productId.value) {
Message.error('产品ID不存在无法复制标准模型');
return;
}
const { valid } = await copyStandardFormApi.validate();
if (!valid) return;
const formValues = await copyStandardFormApi.getValues();
console.log('复制标准模型提交参数:', {
formValues,
params: {
productId: productId.value,
productName: productName.value,
ioTPlatform: ioTPlatform.value,
},
});
try {
const resp = await postIoTplatformThingModelInfoCopyStandardThingModel({
body: {
ioTPlatform: Number.parseInt(ioTPlatform.value) as 1 | 2,
ioTPlatformProductId: productId.value,
// 使 filedTypes key
filedTypes: formValues.filedTypes,
},
});
if (resp.data) {
Message.success('复制标准模型成功');
copyStandardModalApi.close();
gridApi.reload();
} else {
Message.error('复制标准模型失败');
}
} catch (error) {
console.error('复制标准模型失败:', error);
}
}
@ -598,36 +693,10 @@ async function onDel(record: any) {
}
} catch (error) {
console.error('删除失败:', error);
Message.error($t('common.deleteFail'));
}
}
//
async function copyStandardThingModel() {
// ID
if (!productId.value) {
Message.error('产品ID不存在无法复制标准模型');
return;
}
try {
const resp = await postIoTplatformThingModelInfoCopyStandardThingModel({
body: {
ioTPlatform: Number.parseInt(ioTPlatform.value) as 1 | 2,
ioTPlatformProductId: productId.value,
},
});
if (resp.data) {
Message.success('复制标准模型成功');
gridApi.reload();
} else {
Message.error('复制标准模型失败');
}
} catch (error) {
console.error('复制标准模型失败:', error);
Message.error('复制标准模型失败');
}
}
// 使 + submitCopyStandard
</script>
<template>
@ -647,7 +716,7 @@ async function copyStandardThingModel() {
label: $t('abp.thingModelInfos.copyStandardThingModel'),
type: 'default',
icon: 'ant-design:copy-outlined',
onClick: copyStandardThingModel,
onClick: openCopyStandardThingModelModal,
auth: ['AbpIdentity.Users.Create'],
disabled: !productId,
},
@ -703,5 +772,10 @@ async function copyStandardThingModel() {
<CopyModal title="复制已有模型" class="w-[600px]">
<CopyForm />
</CopyModal>
<!-- 复制标准模型按物模型类型多选模态框 -->
<CopyStandardModal title="复制标准模型" class="w-[600px]">
<CopyStandardForm />
</CopyStandardModal>
</Page>
</template>