物模型管理

This commit is contained in:
ChenYi 2025-10-22 15:09:56 +08:00
parent 2b19953855
commit 5e547f09b2
11 changed files with 926 additions and 40 deletions

View File

@ -1183,14 +1183,12 @@ export const ControllerInterfaceApiDescriptionModelSchema = {
export const CopyAnotherProductInputSchema = {
type: 'object',
properties: {
pendingCopyDataId: {
type: 'string',
description: '待复制设备物模型数据ID',
format: 'uuid'
ioTPlatform: {
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
},
ioTPlatformProductId: {
type: 'string',
description: '产品ID',
description: '平台产品ID',
nullable: true
}
},
@ -1198,6 +1196,35 @@ export const CopyAnotherProductInputSchema = {
description: '根据数据ID复制已存在物模型信息'
} as const;
export const CopyStandardThingModelInputSchema = {
type: 'object',
properties: {
filedType: {
type: 'string',
description: '物联网平台中对应产品物模型属性或者事件类型 JiShe.ServicePro.Core.DataDictionaryTypeConst',
nullable: true
},
ioTPlatform: {
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
},
ioTPlatformProductId: {
type: 'string',
description: '平台产品ID',
nullable: true
},
dataDictionaries: {
type: 'array',
items: {
'$ref': '#/components/schemas/DataDictionaryDetailInfoDto'
},
description: '标准物模型集合',
nullable: true
}
},
additionalProperties: false,
description: '复制标准物模型'
} as const;
export const CreateDataDictinaryDetailInputSchema = {
type: 'object',
properties: {
@ -1472,7 +1499,7 @@ export const CreateThingModelInputSchema = {
description: '物联网平台中对应产品物模型属性或者事件类型 JiShe.ServicePro.Core.DataDictionaryTypeConst',
nullable: true
},
rawFieldName: {
ioTPlatformRawFieldName: {
type: 'string',
description: '物联网平台中对应的产品物模型属性或者事件名称',
nullable: true
@ -1482,6 +1509,16 @@ export const CreateThingModelInputSchema = {
description: '管理后台产品标准的物模型属性或者事件名称',
nullable: true
},
standardFieldValueType: {
type: 'string',
description: '标准物模型字段值类型',
nullable: true
},
standardFieldDisplayName: {
type: 'string',
description: '标准物模型字段显示名称',
nullable: true
},
isValueNeedConvert: {
type: 'boolean',
description: '是否需要值类型转换'
@ -1625,6 +1662,58 @@ export const CurrentUserDtoSchema = {
additionalProperties: false
} as const;
export const DataDictionaryDetailInfoDtoSchema = {
type: 'object',
properties: {
dataDictionaryId: {
type: 'string',
description: '所属字典Id',
format: 'uuid'
},
dataDictionaryName: {
type: 'string',
description: '所属字典名称',
nullable: true
},
dataDictionaryCode: {
type: 'string',
description: '字典编码',
nullable: true
},
code: {
type: 'string',
description: '字典明细编码',
nullable: true
},
order: {
type: 'integer',
description: '展现列表时排序用',
format: 'int32'
},
displayText: {
type: 'string',
description: '显示名',
nullable: true
},
description: {
type: 'string',
description: '描述',
nullable: true
},
isEnabled: {
type: 'boolean',
description: '启/停用(默认启用)'
},
extendedAttribute: {
type: 'string',
description: '扩展属性',
nullable: true
}
},
additionalProperties: false,
description: '数据字典详情信息'
} as const;
export const DataEncryptionEnumSchema = {
enum: [1, 2, 3, 4, 5, 6],
type: 'integer',
@ -2226,7 +2315,7 @@ export const DeviceThingModelInfoDtoSchema = {
description: '物联网平台中对应产品物模型属性或者事件类型 JiShe.ServicePro.Core.DataDictionaryTypeConst',
nullable: true
},
rawFieldName: {
ioTPlatformRawFieldName: {
type: 'string',
description: '物联网平台中对应的产品物模型属性或者事件名称',
nullable: true
@ -2236,6 +2325,16 @@ export const DeviceThingModelInfoDtoSchema = {
description: '管理后台产品标准的物模型属性或者事件名称',
nullable: true
},
standardFieldValueType: {
type: 'string',
description: '标准物模型字段值类型',
nullable: true
},
standardFieldDisplayName: {
type: 'string',
description: '标准物模型字段显示名称',
nullable: true
},
isValueNeedConvert: {
type: 'boolean',
description: '是否需要值类型转换'
@ -5561,6 +5660,11 @@ export const PageDeviceInputSchema = {
ioTPlatform: {
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
},
ioTPlatformDeviceOpenInfo: {
type: 'string',
description: '物联网平台中对应的设备Id或者名称',
nullable: true
},
searchKeyword: {
type: 'string',
description: '搜索关键字',
@ -6378,9 +6482,9 @@ export const PageThingModelInputSchema = {
description: '物联网平台中对应产品物模型属性或者事件类型 JiShe.ServicePro.Core.DataDictionaryTypeConst',
nullable: true
},
rawFieldName: {
searchKeyWords: {
type: 'string',
description: '物联网平台中对应的产品物模型属性或者事件名称',
description: '搜索关键词',
nullable: true
}
},
@ -6719,6 +6823,11 @@ export const PagingDataDictionaryDetailOutputSchema = {
description: '描述',
nullable: true
},
extendedAttribute: {
type: 'string',
description: '扩展属性',
nullable: true
},
isEnabled: {
type: 'boolean',
description: '启/停用(默认启用)'
@ -9077,7 +9186,7 @@ export const UpdateThingModelInputSchema = {
description: '物联网平台中对应产品物模型属性或者事件类型 JiShe.ServicePro.Core.DataDictionaryTypeConst',
nullable: true
},
rawFieldName: {
ioTPlatformRawFieldName: {
type: 'string',
description: '物联网平台中对应的产品物模型属性或者事件名称',
nullable: true
@ -9087,6 +9196,16 @@ export const UpdateThingModelInputSchema = {
description: '管理后台产品标准的物模型属性或者事件名称',
nullable: true
},
standardFieldValueType: {
type: 'string',
description: '标准物模型字段值类型',
nullable: true
},
standardFieldDisplayName: {
type: 'string',
description: '标准物模型字段显示名称',
nullable: true
},
isValueNeedConvert: {
type: 'boolean',
description: '是否需要值类型转换'

File diff suppressed because one or more lines are too long

View File

@ -204,16 +204,32 @@ export type ControllerInterfaceApiDescriptionModel = {
* ID复制已存在物模型信息
*/
export type CopyAnotherProductInput = {
ioTPlatform?: IoTPlatformTypeEnum;
/**
* ID
*/
pendingCopyDataId?: string;
/**
* ID
* ID
*/
ioTPlatformProductId?: (string) | null;
};
/**
*
*/
export type CopyStandardThingModelInput = {
/**
* JiShe.ServicePro.Core.DataDictionaryTypeConst
*/
filedType?: (string) | null;
ioTPlatform?: IoTPlatformTypeEnum;
/**
* ID
*/
ioTPlatformProductId?: (string) | null;
/**
*
*/
dataDictionaries?: Array<DataDictionaryDetailInfoDto> | null;
};
export type CreateDataDictinaryDetailInput = {
id?: string;
code?: (string) | null;
@ -393,11 +409,19 @@ export type CreateThingModelInput = {
/**
*
*/
rawFieldName?: (string) | null;
ioTPlatformRawFieldName?: (string) | null;
/**
*
*/
standardFieldName?: (string) | null;
/**
*
*/
standardFieldValueType?: (string) | null;
/**
*
*/
standardFieldDisplayName?: (string) | null;
/**
*
*/
@ -857,6 +881,48 @@ export type CurrentUserDto = {
sessionId?: (string) | null;
};
/**
*
*/
export type DataDictionaryDetailInfoDto = {
/**
* Id
*/
dataDictionaryId?: string;
/**
*
*/
dataDictionaryName?: (string) | null;
/**
*
*/
dataDictionaryCode?: (string) | null;
/**
*
*/
code?: (string) | null;
/**
*
*/
order?: number;
/**
*
*/
displayText?: (string) | null;
/**
*
*/
description?: (string) | null;
/**
* /()
*/
isEnabled?: boolean;
/**
*
*/
extendedAttribute?: (string) | null;
};
/**
*
*/
@ -1206,11 +1272,19 @@ export type DeviceThingModelInfoDto = {
/**
*
*/
rawFieldName?: (string) | null;
ioTPlatformRawFieldName?: (string) | null;
/**
*
*/
standardFieldName?: (string) | null;
/**
*
*/
standardFieldValueType?: (string) | null;
/**
*
*/
standardFieldDisplayName?: (string) | null;
/**
*
*/
@ -2760,6 +2834,10 @@ export type PageDeviceInput = {
*/
deviceAddress?: (string) | null;
ioTPlatform?: IoTPlatformTypeEnum;
/**
* Id或者名称
*/
ioTPlatformDeviceOpenInfo?: (string) | null;
/**
*
*/
@ -3260,9 +3338,9 @@ export type PageThingModelInput = {
*/
filedType?: (string) | null;
/**
*
*
*/
rawFieldName?: (string) | null;
searchKeyWords?: (string) | null;
};
export type PagingAuditLogActionOutput = {
@ -3422,6 +3500,10 @@ export type PagingDataDictionaryDetailOutput = {
*
*/
description?: (string) | null;
/**
*
*/
extendedAttribute?: (string) | null;
/**
* /()
*/
@ -4660,11 +4742,19 @@ export type UpdateThingModelInput = {
/**
*
*/
rawFieldName?: (string) | null;
ioTPlatformRawFieldName?: (string) | null;
/**
*
*/
standardFieldName?: (string) | null;
/**
*
*/
standardFieldValueType?: (string) | null;
/**
*
*/
standardFieldDisplayName?: (string) | null;
/**
*
*/
@ -5132,7 +5222,7 @@ export type PostThingModelInfoFindByPlatformProductIdAsyncData = {
};
};
export type PostThingModelInfoFindByPlatformProductIdAsyncResponse = (DeviceThingModelInfoDto);
export type PostThingModelInfoFindByPlatformProductIdAsyncResponse = (Array<DeviceThingModelInfoDto>);
export type PostThingModelInfoFindByPlatformProductIdAsyncError = unknown;
@ -5142,29 +5232,33 @@ export type PostThingModelInfoCopyAnotherThingModelAsyncData = {
};
};
export type PostThingModelInfoCopyAnotherThingModelAsyncResponse = (DeviceThingModelInfoDto);
export type PostThingModelInfoCopyAnotherThingModelAsyncResponse = (boolean);
export type PostThingModelInfoCopyAnotherThingModelAsyncError = unknown;
export type PostThingModelInfoCopyStandardThingModelData = {
query?: {
input?: StringIdInput;
input?: CopyStandardThingModelInput;
};
};
export type PostThingModelInfoCopyStandardThingModelResponse = (DeviceThingModelInfoDto);
export type PostThingModelInfoCopyStandardThingModelResponse = (boolean);
export type PostThingModelInfoCopyStandardThingModelError = unknown;
export type PostThingModelInfoPageData = {
export type PostThingModelInfoPageAsyncData = {
query?: {
input?: PageThingModelInput;
};
};
export type PostThingModelInfoPageResponse = (DeviceThingModelInfoDtoPagedResultDto);
export type PostThingModelInfoPageAsyncResponse = (DeviceThingModelInfoDtoPagedResultDto);
export type PostThingModelInfoPageError = unknown;
export type PostThingModelInfoPageAsyncError = unknown;
export type PostThingModelInfoStandardThingModelPageAsyncResponse = (Array<DataDictionaryDetailInfoDto>);
export type PostThingModelInfoStandardThingModelPageAsyncError = unknown;
export type PostFeaturesListData = {
body?: GetFeatureListResultInput;

View File

@ -218,6 +218,14 @@
"deviceInfoManage": "DeviceInfoManage",
"thingModelInfoManage": "ThingModelInfoManage"
},
"thingModelInfos": {
"FiledType": "FiledType",
"IoTPlatformRawFieldName": "IoTPlatformRawFieldName",
"StandardFieldName": "StandardFieldName",
"StandardFieldDisplayName": "StandardFieldDisplayName",
"IsValueNeedConvert": "IsValueNeedConvert",
"StandardFieldValueType": "StandardFieldValueType"
},
"IoTDBBase": {
"IoTDataType": "IoTDataType",
"DataBaseName": "DataBaseName",

View File

@ -66,5 +66,6 @@
"AppSecret": "AppSecret",
"operationSuccess": "OperationSuccess",
"operationFailed": "OperationFailed",
"required":"Required",
"loading": "Loading"
}

View File

@ -211,6 +211,14 @@
"deviceInfoManage": "设备管理",
"thingModelInfoManage": "物模型管理"
},
"thingModelInfos": {
"FiledType": "物模型类型",
"IoTPlatformRawFieldName": "平台物模型编码",
"StandardFieldName": "标准物模型编码",
"StandardFieldDisplayName": "标准物模型名称",
"IsValueNeedConvert": "是否需要值类型转换",
"StandardFieldValueType": "标准物模型值类型"
},
"IoTDBBase": {
"IoTDataType": "数据类型",
"DataBaseName": "所属数据库",

View File

@ -67,5 +67,6 @@
"AppSecret": "应用Secret",
"operationSuccess": "操作成功",
"operationFailed": "操作失败",
"required": "必填",
"loading": "正在处理"
}

View File

@ -23,6 +23,8 @@ import {
import { TableAction } from '#/components/table-action';
import { $t } from '#/locales';
import ThingModelInfoModal from '#/views/devicemanagement/thingmodelinfo/index.vue';
import {
addProductFormSchema,
editProductFormSchemaEdit,
@ -76,6 +78,10 @@ const editRow: Record<string, any> = ref({});
//
let selectedFile: File | null = null;
//
const thingModelModalVisible = ref(false);
const currentProductInfo = ref<any>({});
//
setFileSelectedCallback((file) => {
selectedFile = file;
@ -305,6 +311,25 @@ async function onStatusChange(record: any) {
Message.error(record.isEnabled ? '禁用失败' : '启用失败');
}
}
//
function onThingModelManagement(record: any) {
console.log('物模型管理按钮被点击', record);
//
currentProductInfo.value = {
productId: record.ioTPlatformProductId,
productName: record.productName,
ioTPlatform: '1', // CTWing1
};
//
thingModelModalVisible.value = true;
}
//
function closeThingModelModal() {
thingModelModalVisible.value = false;
currentProductInfo.value = {};
}
</script>
<template>
@ -346,6 +371,12 @@ async function onStatusChange(record: any) {
auth: ['AbpIdentity.Users.Update'],
onClick: onEdit.bind(null, row),
},
{
label: $t('abp.deviceInfos.thingModelInfoManage'),
type: 'link',
size: 'small',
onClick: onThingModelManagement.bind(null, row),
},
{
label: row.isEnabled ? '禁用' : '启用',
type: 'link',
@ -374,5 +405,14 @@ async function onStatusChange(record: any) {
<UserModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
<component :is="editRow.id ? EditForm : AddForm" />
</UserModal>
<!-- 物模型信息模态框 -->
<ThingModelInfoModal
v-model:visible="thingModelModalVisible"
:product-id="currentProductInfo.productId"
:product-name="currentProductInfo.productName"
:io-t-platform="currentProductInfo.ioTPlatform"
@close="closeThingModelModal"
/>
</Page>
</template>

View File

@ -0,0 +1,351 @@
<script setup lang="ts">
import type { VbenFormProps } from '#/adapter/form';
import type { VxeGridProps } from '#/adapter/vxe-table';
import { computed, h, nextTick, ref, watch } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { message as Message, Tag, Modal } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
postThingModelInfoPageAsync,
postThingModelInfoDeleteAsync,
postThingModelInfoCreateAsync,
postThingModelInfoUpdateAsync,
postThingModelInfoCopyStandardThingModel,
} from '#/api-client';
import { TableAction } from '#/components/table-action';
import { $t } from '#/locales';
import {
addThingModelFormSchema,
editThingModelFormSchema,
querySchema,
tableSchema,
} from './schema';
defineOptions({
name: 'ThingModelInfoModal',
});
// props
interface Props {
visible?: boolean;
productId?: string;
productName?: string;
ioTPlatform?: string;
}
const props = withDefaults(defineProps<Props>(), {
visible: false,
productId: '',
productName: '',
ioTPlatform: '2',
});
// emits
const emit = defineEmits<{
'update:visible': [value: boolean];
'close': [];
}>();
const formOptions: VbenFormProps = {
schema: querySchema.value,
};
const gridOptions: VxeGridProps<any> = {
checkboxConfig: {
highlight: true,
labelField: 'thingModelName',
},
columns: tableSchema.value,
height: 'auto',
keepSource: true,
pagerConfig: {},
toolbarConfig: {
custom: true,
},
customConfig: {
storage: true,
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
const { data } = await postThingModelInfoPageAsync({
body: {
pageIndex: page.currentPage,
pageSize: page.pageSize,
...formValues,
},
});
return data;
},
},
},
};
const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });
const editRow: Record<string, any> = ref({});
const [ThingModelModal, thingModelModalApi] = useVbenModal({
draggable: true,
footer: true,
showCancelButton: true,
showConfirmButton: true,
onConfirm: submit,
onBeforeClose: () => {
return true;
},
onOpenChange: (isOpen: boolean) => {
if (isOpen && editRow.value.id) {
//
nextTick(() => {
editFormApi.setValues({ ...editRow.value });
});
}
},
onCancel: () => {
thingModelModalApi.close();
},
});
const [AddForm, addFormApi] = useVbenForm({
collapsed: false,
commonConfig: {
labelWidth: 110,
componentProps: {
class: 'w-4/5',
},
},
layout: 'horizontal',
schema: addThingModelFormSchema.value,
showCollapseButton: false,
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
const [EditForm, editFormApi] = useVbenForm({
collapsed: false,
commonConfig: {
labelWidth: 110,
componentProps: {
class: 'w-4/5',
},
},
layout: 'horizontal',
schema: editThingModelFormSchema.value,
showCollapseButton: false,
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
// props
watch(
() => [props.visible, props.productId, props.ioTPlatform],
async ([visible, productId, ioTPlatform]) => {
console.log('物模型模态框props变化:', { visible, productId, ioTPlatform });
if (visible && productId) {
//
setTimeout(async () => {
try {
//
const filterValues: any = {};
if (ioTPlatform) {
filterValues.ioTPlatform = ioTPlatform;
}
if (productId) {
filterValues.oneNETProductId = productId;
}
console.log('设置筛选条件:', filterValues);
//
if (Object.keys(filterValues).length > 0) {
await gridApi.formApi.setValues(filterValues);
//
await gridApi.reload();
}
} catch (error) {
console.error('设置筛选条件时出错:', error);
}
}, 100);
}
},
{ immediate: true }
);
//
async function submit() {
const isEdit = !!editRow.value.id;
const formApi = isEdit ? editFormApi : addFormApi;
const api = isEdit
? postThingModelInfoUpdateAsync
: postThingModelInfoCreateAsync;
const { valid } = await formApi.validate();
if (!valid) return;
const formValues = await formApi.getValues();
const fetchParams: any = {
query: {
input: {
...formValues,
//
ioTPlatform: parseInt(props.ioTPlatform) as 1 | 2,
ioTPlatformProductId: props.productId,
// ID
...(isEdit && { id: editRow.value.id }),
},
},
};
try {
const resp = await api({ body: fetchParams });
if (resp.data) {
Message.success(
editRow.value.id ? $t('common.editSuccess') : $t('common.addSuccess'),
);
thingModelModalApi.close();
editRow.value = {};
gridApi.reload();
} else {
Message.error(
editRow.value.id ? $t('common.editFail') : $t('common.addFail'),
);
}
} catch (error) {
console.error('提交失败:', error);
Message.error(
editRow.value.id ? $t('common.editFail') : $t('common.addFail'),
);
}
}
async function onEdit(record: any) {
editRow.value = record;
thingModelModalApi.open();
}
const openAddModal = async () => {
editRow.value = {};
thingModelModalApi.open();
};
//
async function onDel(record: any) {
try {
const resp = await postThingModelInfoDeleteAsync({
body: { id: record.id },
});
if (resp.data) {
Message.success($t('common.deleteSuccess'));
gridApi.reload();
} else {
Message.error($t('common.deleteFail'));
}
} catch (error) {
console.error('删除失败:', error);
Message.error($t('common.deleteFail'));
}
}
//
async function copyStandardThingModel() {
try {
const resp = await postThingModelInfoCopyStandardThingModel({
body: {
ioTPlatform: props.ioTPlatform,
ioTPlatformProductId: props.productId,
},
});
if (resp.data) {
Message.success('复制标准模型成功');
gridApi.reload();
} else {
Message.error('复制标准模型失败');
}
} catch (error) {
console.error('复制标准模型失败:', error);
Message.error('复制标准模型失败');
}
}
//
function closeModal() {
emit('update:visible', false);
emit('close');
}
</script>
<template>
<Modal
:open="visible"
:title="`物模型管理 - ${productName || '产品'}`"
width="90%"
:footer="null"
@cancel="closeModal"
@ok="closeModal"
:body-style="{ height: '70vh', overflow: 'hidden' }"
>
<div style="height: 100%; display: flex; flex-direction: column;">
<Grid style="flex: 1; overflow: hidden;">
<template #toolbar-actions>
<TableAction :actions="[
{
label: $t('common.add'),
type: 'primary',
icon: 'ant-design:plus-outlined',
onClick: openAddModal.bind(null),
auth: ['AbpIdentity.Users.Create'],
},
{
label: '复制标准模型',
type: 'default',
icon: 'ant-design:copy-outlined',
onClick: copyStandardThingModel,
auth: ['AbpIdentity.Users.Create'],
},
]" />
</template>
<template #isValueNeedConvert="{ row }">
<component :is="h(Tag, { color: row.isValueNeedConvert ? 'blue' : 'default' }, () =>
row.isValueNeedConvert ? '是' : '否',
)
" />
</template>
<template #action="{ row }">
<TableAction :actions="[
{
label: $t('common.edit'),
type: 'link',
size: 'small',
auth: ['AbpIdentity.Users.Update'],
onClick: onEdit.bind(null, row),
},
]" :drop-down-actions="[
{
label: $t('common.delete'),
icon: 'ant-design:delete-outlined',
type: 'primary',
popConfirm: {
title: $t('common.askConfirmDelete'),
confirm: onDel.bind(null, row),
},
},
]" />
</template>
</Grid>
</div>
<ThingModelModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
<component :is="editRow.id ? EditForm : AddForm" />
</ThingModelModal>
</Modal>
</template>

View File

@ -0,0 +1,232 @@
import { computed } from 'vue';
import { z } from '@vben/common-ui';
import dayjs from 'dayjs';
import { $t } from '#/locales';
export const querySchema = computed(() => [
{
component: 'Input',
fieldName: 'SearchKeyWords',
label: $t('common.keyword'),
},
]);
export const tableSchema = computed(() => [
{
field: 'filedType',
title: '物模型类型',
minWidth: 120,
showOverflow: 'tooltip',
formatter: ({ cellValue }: { cellValue: any }) => {
const typeMap: Record<string, string> = {
'Property': '属性',
'Service': '服务',
'Event': '事件',
};
return typeMap[cellValue] || cellValue;
},
},
{
field: 'ioTPlatformRawFieldName',
title: '平台原始字段名',
minWidth: 150,
showOverflow: 'tooltip',
},
{
field: 'standardFieldName',
title: '标准字段名',
minWidth: 150,
showOverflow: 'tooltip',
},
{
field: 'standardFieldDisplayName',
title: '标准字段显示名称',
minWidth: 150,
showOverflow: 'tooltip',
},
{
field: 'standardFieldValueType',
title: '标准字段值类型',
minWidth: 120,
showOverflow: 'tooltip',
formatter: ({ cellValue }: { cellValue: any }) => {
const typeMap: Record<string, string> = {
'String': '字符串',
'Int32': '整数',
'Int64': '长整数',
'Float': '浮点数',
'Double': '双精度',
'Boolean': '布尔值',
'DateTime': '日期时间',
'Object': 'JSON对象',
'Array': '数组',
};
return typeMap[cellValue] || cellValue;
},
},
{
field: 'isValueNeedConvert',
title: '需要值类型转换',
minWidth: 120,
slots: { default: 'isValueNeedConvert' },
},
{
field: 'creationTime',
title: $t('common.creationTime'),
minWidth: 180,
formatter: ({ cellValue }: { cellValue: any }) => {
return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : '-';
},
},
{
field: 'action',
title: $t('common.action'),
width: 200,
fixed: 'right',
slots: { default: 'action' },
},
]);
// 添加物模型表单schema
export const addThingModelFormSchema = computed(() => [
{
component: 'Select',
fieldName: 'filedType',
label: '物模型类型',
rules: z.string().min(1, $t('common.required')),
componentProps: {
options: [
{ label: '属性', value: 'Property' },
{ label: '服务', value: 'Service' },
{ label: '事件', value: 'Event' },
],
placeholder: '请选择物模型类型',
},
},
{
component: 'Input',
fieldName: 'ioTPlatformRawFieldName',
label: '平台原始字段名',
rules: z.string().min(1, $t('common.required')),
componentProps: {
placeholder: '请输入物联网平台中的原始字段名',
},
},
{
component: 'Input',
fieldName: 'standardFieldName',
label: '标准字段名',
rules: z.string().min(1, $t('common.required')),
componentProps: {
placeholder: '请输入管理后台产品标准的字段名',
},
},
{
component: 'Select',
fieldName: 'standardFieldValueType',
label: '标准字段值类型',
rules: z.string().min(1, $t('common.required')),
componentProps: {
options: [
{ label: '字符串', value: 'String' },
{ label: '整数', value: 'Int32' },
{ label: '长整数', value: 'Int64' },
{ label: '浮点数', value: 'Float' },
{ label: '双精度', value: 'Double' },
{ label: '布尔值', value: 'Boolean' },
{ label: '日期时间', value: 'DateTime' },
{ label: 'JSON对象', value: 'Object' },
{ label: '数组', value: 'Array' },
],
placeholder: '请选择标准字段值类型',
},
},
{
component: 'Input',
fieldName: 'standardFieldDisplayName',
label: '标准字段显示名称',
rules: z.string().min(1, $t('common.required')),
componentProps: {
placeholder: '请输入标准字段的显示名称',
},
},
{
component: 'Switch',
fieldName: 'isValueNeedConvert',
label: '是否需要值类型转换',
defaultValue: false,
},
]);
// 编辑物模型表单schema
export const editThingModelFormSchema = computed(() => [
{
component: 'Select',
fieldName: 'filedType',
label: '物模型类型',
rules: z.string().min(1, $t('common.required')),
componentProps: {
options: [
{ label: '属性', value: 'Property' },
{ label: '服务', value: 'Service' },
{ label: '事件', value: 'Event' },
],
placeholder: '请选择物模型类型',
},
},
{
component: 'Input',
fieldName: 'ioTPlatformRawFieldName',
label: '平台原始字段名',
rules: z.string().min(1, $t('common.required')),
componentProps: {
placeholder: '请输入物联网平台中的原始字段名',
},
},
{
component: 'Input',
fieldName: 'standardFieldName',
label: '标准字段名',
rules: z.string().min(1, $t('common.required')),
componentProps: {
placeholder: '请输入管理后台产品标准的字段名',
},
},
{
component: 'Select',
fieldName: 'standardFieldValueType',
label: '标准字段值类型',
rules: z.string().min(1, $t('common.required')),
componentProps: {
options: [
{ label: '字符串', value: 'String' },
{ label: '整数', value: 'Int32' },
{ label: '长整数', value: 'Int64' },
{ label: '浮点数', value: 'Float' },
{ label: '双精度', value: 'Double' },
{ label: '布尔值', value: 'Boolean' },
{ label: '日期时间', value: 'DateTime' },
{ label: 'JSON对象', value: 'Object' },
{ label: '数组', value: 'Array' },
],
placeholder: '请选择标准字段值类型',
},
},
{
component: 'Input',
fieldName: 'standardFieldDisplayName',
label: '标准字段显示名称',
rules: z.string().min(1, $t('common.required')),
componentProps: {
placeholder: '请输入标准字段的显示名称',
},
},
{
component: 'Switch',
fieldName: 'isValueNeedConvert',
label: '是否需要值类型转换',
},
]);

View File

@ -23,6 +23,8 @@ import {
import { TableAction } from '#/components/table-action';
import { $t } from '#/locales';
import ThingModelInfoModal from '#/views/devicemanagement/thingmodelinfo/index.vue';
import {
addProductFormSchema,
editProductFormSchemaEdit,
@ -76,6 +78,10 @@ const editRow: Record<string, any> = ref({});
//
let selectedFile: File | null = null;
//
const thingModelModalVisible = ref(false);
const currentProductInfo = ref<any>({});
//
setFileSelectedCallback((file) => {
selectedFile = file;
@ -324,15 +330,22 @@ function onDeviceManagement(record: any) {
//
function onThingModelManagement(record: any) {
console.log('物模型管理按钮被点击', record);
// ID
router.push({
path: '/devicemanagement/thingmodelinfo',
query: {
ioTPlatform: '2', // OneNET2
ioTPlatformDeviceOpenInfo: record.ioTPlatformProductId, // ID
productName: record.productName,
},
});
//
currentProductInfo.value = {
productId: record.ioTPlatformProductId,
productName: record.productName,
ioTPlatform: '2', // OneNET2
};
console.log('设置产品信息:', currentProductInfo.value);
//
thingModelModalVisible.value = true;
console.log('模态框状态设置为:', thingModelModalVisible.value);
}
//
function closeThingModelModal() {
thingModelModalVisible.value = false;
currentProductInfo.value = {};
}
</script>
@ -415,5 +428,14 @@ function onThingModelManagement(record: any) {
<UserModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
<component :is="editRow.id ? EditForm : AddForm" />
</UserModal>
<!-- 物模型信息模态框 -->
<ThingModelInfoModal
v-model:visible="thingModelModalVisible"
:product-id="currentProductInfo.productId"
:product-name="currentProductInfo.productName"
:io-t-platform="currentProductInfo.ioTPlatform"
@close="closeThingModelModal"
/>
</Page>
</template>