2025-12-18 22:05:55 +08:00
|
|
|
|
<script setup lang="ts">
|
2025-12-19 14:57:43 +08:00
|
|
|
|
import { computed, nextTick, ref, watch } from 'vue';
|
2025-12-18 22:05:55 +08:00
|
|
|
|
|
2025-12-19 14:57:43 +08:00
|
|
|
|
import { useVbenModal, z } from '@vben/common-ui';
|
2025-12-18 22:05:55 +08:00
|
|
|
|
|
2025-12-19 14:57:43 +08:00
|
|
|
|
import { message as Message } from 'ant-design-vue';
|
|
|
|
|
|
|
|
|
|
|
|
import { useVbenForm } from '#/adapter/form';
|
2025-12-18 22:05:55 +08:00
|
|
|
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
2025-12-19 14:57:43 +08:00
|
|
|
|
import {
|
|
|
|
|
|
getCommonGetSelectList,
|
|
|
|
|
|
postAggregationIoTplatformGetIoTplatformProductInfoAsync,
|
|
|
|
|
|
postDeviceThingModelManagementCopyAnotherDeviceThingModelAsync,
|
|
|
|
|
|
postDeviceThingModelManagementCopyIoTplatformThingModelToDeviceAsync,
|
|
|
|
|
|
postDeviceThingModelManagementPageAsync,
|
|
|
|
|
|
postDeviceThingModelManagementPropertyCreateAsync,
|
|
|
|
|
|
postDeviceThingModelManagementPropertyDeleteAsync,
|
|
|
|
|
|
postDeviceThingModelManagementPropertyFindByIdAsync,
|
|
|
|
|
|
postDeviceThingModelManagementPropertyPageAsync,
|
|
|
|
|
|
postDeviceThingModelManagementPropertyUpdateAsync,
|
|
|
|
|
|
} from '#/api-client';
|
|
|
|
|
|
import { TableAction } from '#/components/table-action';
|
2025-12-18 22:05:55 +08:00
|
|
|
|
import { $t } from '#/locales';
|
|
|
|
|
|
|
2025-12-22 10:33:30 +08:00
|
|
|
|
import IoTPlatformThingModelDataSelect from '../IoTPlatformThingModelDataSelect.vue';
|
|
|
|
|
|
|
2025-12-18 22:05:55 +08:00
|
|
|
|
defineOptions({
|
|
|
|
|
|
name: 'DeviceThingModelPropertyModal',
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const deviceThingModelId = ref<string>('');
|
|
|
|
|
|
const deviceModelName = ref<string>('');
|
2025-12-19 14:57:43 +08:00
|
|
|
|
const ioTPlatform = ref<number | string>('');
|
|
|
|
|
|
const ioTPlatformProductId = ref<string>('');
|
|
|
|
|
|
|
|
|
|
|
|
const editRow: Record<string, any> = ref({});
|
2025-12-18 22:05:55 +08:00
|
|
|
|
|
2025-12-19 14:57:43 +08:00
|
|
|
|
// 属性列表
|
2025-12-18 22:05:55 +08:00
|
|
|
|
const [Grid, gridApi] = useVbenVxeGrid({
|
|
|
|
|
|
formOptions: {
|
|
|
|
|
|
schema: [],
|
|
|
|
|
|
showDefaultActions: false,
|
|
|
|
|
|
},
|
|
|
|
|
|
gridOptions: {
|
|
|
|
|
|
columns: [
|
2025-12-19 14:57:43 +08:00
|
|
|
|
{
|
|
|
|
|
|
field: 'filedType',
|
|
|
|
|
|
title: '物模型类型',
|
|
|
|
|
|
minWidth: 160,
|
|
|
|
|
|
showOverflow: 'tooltip',
|
|
|
|
|
|
},
|
2025-12-18 22:05:55 +08:00
|
|
|
|
{
|
2025-12-19 10:32:13 +08:00
|
|
|
|
field: 'standardFieldDisplayName',
|
|
|
|
|
|
title: '标准属性名称',
|
2025-12-18 22:05:55 +08:00
|
|
|
|
minWidth: 160,
|
|
|
|
|
|
showOverflow: 'tooltip',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
2025-12-19 10:32:13 +08:00
|
|
|
|
field: 'standardFieldName',
|
|
|
|
|
|
title: '标准属性标识符',
|
|
|
|
|
|
minWidth: 160,
|
|
|
|
|
|
showOverflow: 'tooltip',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'standardFieldValueType',
|
|
|
|
|
|
title: '标准属性值类型',
|
|
|
|
|
|
minWidth: 160,
|
|
|
|
|
|
showOverflow: 'tooltip',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'ioTPlatformRawFieldName',
|
|
|
|
|
|
title: '平台属性标识符',
|
|
|
|
|
|
minWidth: 160,
|
|
|
|
|
|
showOverflow: 'tooltip',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'ioTPlatformRawFieldDataType',
|
|
|
|
|
|
title: '平台属性值类型',
|
|
|
|
|
|
minWidth: 160,
|
2025-12-18 22:05:55 +08:00
|
|
|
|
showOverflow: 'tooltip',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
2025-12-19 10:32:13 +08:00
|
|
|
|
field: 'isValueNeedConvert',
|
|
|
|
|
|
title: '值类型是否转换',
|
2025-12-18 22:05:55 +08:00
|
|
|
|
minWidth: 120,
|
|
|
|
|
|
showOverflow: 'tooltip',
|
2025-12-19 14:57:43 +08:00
|
|
|
|
formatter: ({ cellValue }: { cellValue: any }) => {
|
|
|
|
|
|
return cellValue ? '是' : '否';
|
|
|
|
|
|
},
|
2025-12-18 22:05:55 +08:00
|
|
|
|
},
|
2025-12-19 10:32:13 +08:00
|
|
|
|
{
|
|
|
|
|
|
field: 'parsingSequence',
|
|
|
|
|
|
title: '解析方式',
|
|
|
|
|
|
minWidth: 140,
|
|
|
|
|
|
showOverflow: 'tooltip',
|
2025-12-19 14:57:43 +08:00
|
|
|
|
formatter: ({ cellValue }: { cellValue: any }) => {
|
|
|
|
|
|
if (cellValue === 1) return '正序';
|
|
|
|
|
|
if (cellValue === 2) return '高低位反转';
|
|
|
|
|
|
return cellValue ?? '-';
|
|
|
|
|
|
},
|
2025-12-19 10:32:13 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'nativeSkipNumber',
|
|
|
|
|
|
title: '正序跳过数量',
|
|
|
|
|
|
minWidth: 140,
|
|
|
|
|
|
showOverflow: 'tooltip',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'nativeTakeNumber',
|
|
|
|
|
|
title: '正序获取数量',
|
|
|
|
|
|
minWidth: 140,
|
|
|
|
|
|
showOverflow: 'tooltip',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'reversalSkipNumber',
|
|
|
|
|
|
title: '反转跳过数量',
|
|
|
|
|
|
minWidth: 140,
|
|
|
|
|
|
showOverflow: 'tooltip',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'reversalTakeNumber',
|
|
|
|
|
|
title: '反转获取数量',
|
|
|
|
|
|
minWidth: 140,
|
|
|
|
|
|
showOverflow: 'tooltip',
|
|
|
|
|
|
},
|
2025-12-18 22:05:55 +08:00
|
|
|
|
{
|
|
|
|
|
|
field: 'action',
|
|
|
|
|
|
title: $t('common.action'),
|
|
|
|
|
|
width: 200,
|
|
|
|
|
|
fixed: 'right',
|
|
|
|
|
|
slots: { default: 'action' },
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
height: 400,
|
|
|
|
|
|
pagerConfig: {},
|
2025-12-19 14:57:43 +08:00
|
|
|
|
toolbarConfig: {
|
|
|
|
|
|
custom: true,
|
|
|
|
|
|
},
|
2025-12-18 22:05:55 +08:00
|
|
|
|
proxyConfig: {
|
|
|
|
|
|
ajax: {
|
|
|
|
|
|
query: async ({ page }) => {
|
|
|
|
|
|
if (!deviceThingModelId.value) {
|
|
|
|
|
|
return { items: [], totalCount: 0 };
|
|
|
|
|
|
}
|
2025-12-19 10:32:13 +08:00
|
|
|
|
const { data } =
|
|
|
|
|
|
await postDeviceThingModelManagementPropertyPageAsync({
|
|
|
|
|
|
body: {
|
|
|
|
|
|
pageIndex: page.currentPage,
|
|
|
|
|
|
pageSize: page.pageSize,
|
|
|
|
|
|
deviceThingModelId: deviceThingModelId.value,
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
2025-12-18 22:05:55 +08:00
|
|
|
|
return data || { items: [], totalCount: 0 };
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-12-22 10:33:30 +08:00
|
|
|
|
// 属性新增弹窗(独立)
|
|
|
|
|
|
const [AddPropertyFormModal, addPropertyFormModalApi] = useVbenModal({
|
|
|
|
|
|
draggable: true,
|
|
|
|
|
|
footer: true,
|
|
|
|
|
|
showCancelButton: true,
|
|
|
|
|
|
showConfirmButton: true,
|
|
|
|
|
|
onConfirm: submitAddProperty,
|
|
|
|
|
|
onBeforeClose: () => {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
},
|
|
|
|
|
|
onOpenChange: (isOpen: boolean) => {
|
|
|
|
|
|
if (isOpen) {
|
|
|
|
|
|
// 新增模式下,清空表单
|
|
|
|
|
|
addPropertyFormApi.resetForm();
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
onCancel: () => {
|
|
|
|
|
|
addPropertyFormModalApi.close();
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 属性编辑弹窗(独立)
|
|
|
|
|
|
const [EditPropertyFormModal, editPropertyFormModalApi] = useVbenModal({
|
2025-12-19 14:57:43 +08:00
|
|
|
|
draggable: true,
|
|
|
|
|
|
footer: true,
|
|
|
|
|
|
showCancelButton: true,
|
|
|
|
|
|
showConfirmButton: true,
|
2025-12-22 10:33:30 +08:00
|
|
|
|
onConfirm: submitEditProperty,
|
2025-12-19 14:57:43 +08:00
|
|
|
|
onBeforeClose: () => {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
},
|
|
|
|
|
|
onOpenChange: (isOpen: boolean) => {
|
|
|
|
|
|
if (isOpen && editRow.value.id) {
|
|
|
|
|
|
// 编辑模式下,加载属性详情
|
|
|
|
|
|
nextTick(async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { data } =
|
|
|
|
|
|
await postDeviceThingModelManagementPropertyFindByIdAsync({
|
|
|
|
|
|
body: { id: editRow.value.id },
|
|
|
|
|
|
});
|
|
|
|
|
|
if (data) {
|
|
|
|
|
|
const values: any = { ...data };
|
|
|
|
|
|
// 处理解析方式字段(从后端获取的可能是数字,需要转换成字符串)
|
|
|
|
|
|
if (
|
|
|
|
|
|
values.parsingSequence !== undefined &&
|
|
|
|
|
|
values.parsingSequence !== null
|
|
|
|
|
|
) {
|
|
|
|
|
|
// 如果后端返回的是数字,转换为字符串;如果已经是字符串,保持原样
|
|
|
|
|
|
values.parsingSequence = String(values.parsingSequence);
|
|
|
|
|
|
}
|
2025-12-22 10:33:30 +08:00
|
|
|
|
editPropertyFormApi.setValues(values);
|
2025-12-19 14:57:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('加载属性详情失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
onCancel: () => {
|
2025-12-22 10:33:30 +08:00
|
|
|
|
editPropertyFormModalApi.close();
|
2025-12-19 14:57:43 +08:00
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 快速复制平台端物模型属性弹窗
|
|
|
|
|
|
const [CopyPropertyModal, copyPropertyModalApi] = useVbenModal({
|
|
|
|
|
|
draggable: true,
|
|
|
|
|
|
footer: true,
|
|
|
|
|
|
showCancelButton: true,
|
|
|
|
|
|
showConfirmButton: true,
|
|
|
|
|
|
onConfirm: submitCopyProperty,
|
|
|
|
|
|
onBeforeClose: () => {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
},
|
|
|
|
|
|
onCancel: () => {
|
|
|
|
|
|
copyPropertyModalApi.close();
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 快速复制设备端物模型弹窗
|
|
|
|
|
|
const [CopyDeviceThingModelModal, copyDeviceThingModelModalApi] = useVbenModal({
|
|
|
|
|
|
draggable: true,
|
|
|
|
|
|
footer: true,
|
|
|
|
|
|
showCancelButton: true,
|
|
|
|
|
|
showConfirmButton: true,
|
|
|
|
|
|
onConfirm: submitCopyDeviceThingModel,
|
|
|
|
|
|
onBeforeClose: () => {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
},
|
|
|
|
|
|
onCancel: () => {
|
|
|
|
|
|
copyDeviceThingModelModalApi.close();
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-12-22 10:33:30 +08:00
|
|
|
|
// 新增属性表单 schema(只包含新增接口需要的字段)
|
|
|
|
|
|
const addPropertyFormSchema = computed(() => [
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'ApiSelect',
|
|
|
|
|
|
fieldName: 'filedType',
|
|
|
|
|
|
label: '物模型类型',
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
api: getCommonGetSelectList,
|
|
|
|
|
|
params: {
|
|
|
|
|
|
query: {
|
|
|
|
|
|
typeName: 'DataDictionaryTypeConst',
|
2025-12-19 14:57:43 +08:00
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-12-22 10:33:30 +08:00
|
|
|
|
labelField: 'value',
|
|
|
|
|
|
valueField: 'key',
|
|
|
|
|
|
optionsPropName: 'options',
|
|
|
|
|
|
immediate: true,
|
|
|
|
|
|
allowClear: true,
|
|
|
|
|
|
placeholder: '请选择物模型类型',
|
|
|
|
|
|
afterFetch: (res: any) => {
|
|
|
|
|
|
if (Array.isArray(res)) return res;
|
|
|
|
|
|
if (res && Array.isArray(res.items)) return res.items;
|
|
|
|
|
|
if (res && Array.isArray(res.data)) return res.data;
|
|
|
|
|
|
return [];
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: IoTPlatformThingModelDataSelect,
|
|
|
|
|
|
fieldName: 'ioTPlatformThingModelDataId',
|
|
|
|
|
|
label: '平台端物模型数据选择',
|
|
|
|
|
|
modelPropName: 'value',
|
|
|
|
|
|
dependencies: {
|
|
|
|
|
|
triggerFields: ['filedType'],
|
|
|
|
|
|
},
|
|
|
|
|
|
componentProps: (formValues: any) => ({
|
|
|
|
|
|
filedType: formValues?.filedType || null,
|
|
|
|
|
|
ioTPlatform: ioTPlatform.value,
|
|
|
|
|
|
ioTPlatformProductId: ioTPlatformProductId.value,
|
|
|
|
|
|
placeholder: '请选择平台端物模型数据',
|
|
|
|
|
|
}),
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'ApiSelect',
|
|
|
|
|
|
fieldName: 'parsingSequence',
|
|
|
|
|
|
label: '解析方式',
|
|
|
|
|
|
rules: z.preprocess(
|
|
|
|
|
|
(v) => (v == null ? '' : v),
|
|
|
|
|
|
z.string().min(1, $t('common.required')),
|
|
|
|
|
|
),
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
api: getCommonGetSelectList,
|
|
|
|
|
|
params: {
|
|
|
|
|
|
query: {
|
|
|
|
|
|
typeName: 'ParsingSequenceTypeEnum',
|
2025-12-19 14:57:43 +08:00
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-12-22 10:33:30 +08:00
|
|
|
|
labelField: 'value',
|
|
|
|
|
|
valueField: 'key',
|
|
|
|
|
|
optionsPropName: 'options',
|
|
|
|
|
|
immediate: true,
|
|
|
|
|
|
allowClear: true,
|
|
|
|
|
|
placeholder: `${$t('common.pleaseSelect')}解析方式`,
|
|
|
|
|
|
afterFetch: (res: any) => {
|
|
|
|
|
|
let items = [];
|
|
|
|
|
|
if (Array.isArray(res)) {
|
|
|
|
|
|
items = res;
|
|
|
|
|
|
} else if (res && Array.isArray(res.items)) {
|
|
|
|
|
|
items = res.items;
|
|
|
|
|
|
} else if (res && Array.isArray(res.data)) {
|
|
|
|
|
|
items = res.data;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 将 key 转换为字符串,因为表单需要字符串类型
|
|
|
|
|
|
return items.map((item: any) => ({
|
|
|
|
|
|
...item,
|
|
|
|
|
|
key: String(item.key || item.value),
|
|
|
|
|
|
}));
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'InputNumber',
|
|
|
|
|
|
fieldName: 'nativeSkipNumber',
|
|
|
|
|
|
label: '正序跳过数量',
|
|
|
|
|
|
rules: z.preprocess(
|
|
|
|
|
|
(v) => (v == null ? 0 : v),
|
|
|
|
|
|
z.number().min(0, '正序跳过数量不能小于0'),
|
|
|
|
|
|
),
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
placeholder: `${$t('common.pleaseInput')}正序跳过数量`,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'InputNumber',
|
|
|
|
|
|
fieldName: 'nativeTakeNumber',
|
|
|
|
|
|
label: '正序获取数量',
|
|
|
|
|
|
rules: z.preprocess(
|
|
|
|
|
|
(v) => (v == null ? 0 : v),
|
|
|
|
|
|
z.number().min(0, '正序获取数量不能小于0'),
|
|
|
|
|
|
),
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
placeholder: `${$t('common.pleaseInput')}正序获取数量`,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'InputNumber',
|
|
|
|
|
|
fieldName: 'reversalSkipNumber',
|
|
|
|
|
|
label: '反转跳过数量',
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
placeholder: `${$t('common.pleaseInput')}反转跳过数量`,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'InputNumber',
|
|
|
|
|
|
fieldName: 'reversalTakeNumber',
|
|
|
|
|
|
label: '反转获取数量',
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
placeholder: `${$t('common.pleaseInput')}反转获取数量`,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
// 编辑属性表单 schema(包含编辑接口需要的所有字段)
|
|
|
|
|
|
const editPropertyFormSchema = computed(() => {
|
|
|
|
|
|
return [
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'Input',
|
|
|
|
|
|
fieldName: 'standardFieldDisplayName',
|
|
|
|
|
|
label: '标准属性名称',
|
|
|
|
|
|
rules: z.preprocess(
|
|
|
|
|
|
(v) => (v == null ? '' : v),
|
|
|
|
|
|
z.string().min(1, $t('common.required')),
|
|
|
|
|
|
),
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
placeholder: `${$t('common.pleaseInput')}标准属性名称`,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'Input',
|
|
|
|
|
|
fieldName: 'standardFieldName',
|
|
|
|
|
|
label: '标准属性标识符',
|
|
|
|
|
|
rules: z.preprocess(
|
|
|
|
|
|
(v) => (v == null ? '' : v),
|
|
|
|
|
|
z.string().min(1, $t('common.required')),
|
|
|
|
|
|
),
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
placeholder: `${$t('common.pleaseInput')}标准属性标识符`,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'ApiSelect',
|
|
|
|
|
|
fieldName: 'standardFieldValueType',
|
|
|
|
|
|
label: '标准属性值类型',
|
|
|
|
|
|
rules: z.preprocess(
|
|
|
|
|
|
(v) => (v == null ? '' : v),
|
|
|
|
|
|
z.string().min(1, $t('common.required')),
|
|
|
|
|
|
),
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
api: getCommonGetSelectList,
|
|
|
|
|
|
params: {
|
|
|
|
|
|
query: {
|
|
|
|
|
|
typeName: 'StandardThingModelDataTypeEnum',
|
2025-12-19 14:57:43 +08:00
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-12-22 10:33:30 +08:00
|
|
|
|
labelField: 'value',
|
|
|
|
|
|
valueField: 'secondValue',
|
|
|
|
|
|
optionsPropName: 'options',
|
|
|
|
|
|
immediate: true,
|
|
|
|
|
|
allowClear: true,
|
|
|
|
|
|
placeholder: `${$t('common.pleaseSelect')}标准属性值类型`,
|
|
|
|
|
|
afterFetch: (res: any) => {
|
|
|
|
|
|
if (Array.isArray(res)) return res;
|
|
|
|
|
|
if (res && Array.isArray(res.items)) return res.items;
|
|
|
|
|
|
if (res && Array.isArray(res.data)) return res.data;
|
|
|
|
|
|
return [];
|
2025-12-19 14:57:43 +08:00
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-12-22 10:33:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'Input',
|
|
|
|
|
|
fieldName: 'ioTPlatformRawFieldName',
|
|
|
|
|
|
label: '平台属性标识符',
|
|
|
|
|
|
rules: z.preprocess(
|
|
|
|
|
|
(v) => (v == null ? '' : v),
|
|
|
|
|
|
z.string().min(1, $t('common.required')),
|
|
|
|
|
|
),
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
placeholder: `${$t('common.pleaseInput')}平台属性标识符`,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'ApiSelect',
|
|
|
|
|
|
fieldName: 'ioTPlatformRawFieldDataType',
|
|
|
|
|
|
label: '平台属性值类型',
|
|
|
|
|
|
rules: z.preprocess(
|
|
|
|
|
|
(v) => (v == null ? '' : v),
|
|
|
|
|
|
z.string().min(1, $t('common.required')),
|
|
|
|
|
|
),
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
api: getCommonGetSelectList,
|
|
|
|
|
|
params: {
|
|
|
|
|
|
query: {
|
|
|
|
|
|
typeName: 'StandardThingModelDataTypeEnum',
|
2025-12-19 14:57:43 +08:00
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-12-22 10:33:30 +08:00
|
|
|
|
labelField: 'value',
|
|
|
|
|
|
valueField: 'secondValue',
|
|
|
|
|
|
optionsPropName: 'options',
|
|
|
|
|
|
immediate: true,
|
|
|
|
|
|
allowClear: true,
|
|
|
|
|
|
placeholder: `${$t('common.pleaseSelect')}平台属性值类型`,
|
|
|
|
|
|
afterFetch: (res: any) => {
|
|
|
|
|
|
if (Array.isArray(res)) return res;
|
|
|
|
|
|
if (res && Array.isArray(res.items)) return res.items;
|
|
|
|
|
|
if (res && Array.isArray(res.data)) return res.data;
|
|
|
|
|
|
return [];
|
2025-12-19 14:57:43 +08:00
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-12-22 10:33:30 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'Switch',
|
|
|
|
|
|
fieldName: 'isValueNeedConvert',
|
|
|
|
|
|
label: '值类型是否转换',
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
checkedChildren: '是',
|
|
|
|
|
|
unCheckedChildren: '否',
|
|
|
|
|
|
style: { width: 'auto' }, // 优化宽度显示
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'ApiSelect',
|
|
|
|
|
|
fieldName: 'parsingSequence',
|
|
|
|
|
|
label: '解析方式',
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
api: getCommonGetSelectList,
|
|
|
|
|
|
params: {
|
|
|
|
|
|
query: {
|
|
|
|
|
|
typeName: 'ParsingSequenceTypeEnum',
|
2025-12-19 14:57:43 +08:00
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-12-22 10:33:30 +08:00
|
|
|
|
labelField: 'value',
|
|
|
|
|
|
valueField: 'key',
|
|
|
|
|
|
optionsPropName: 'options',
|
|
|
|
|
|
immediate: true,
|
|
|
|
|
|
allowClear: true,
|
|
|
|
|
|
placeholder: `${$t('common.pleaseSelect')}解析方式`,
|
|
|
|
|
|
afterFetch: (res: any) => {
|
|
|
|
|
|
let items = [];
|
|
|
|
|
|
if (Array.isArray(res)) {
|
|
|
|
|
|
items = res;
|
|
|
|
|
|
} else if (res && Array.isArray(res.items)) {
|
|
|
|
|
|
items = res.items;
|
|
|
|
|
|
} else if (res && Array.isArray(res.data)) {
|
|
|
|
|
|
items = res.data;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 将 key 转换为字符串,因为表单需要字符串类型
|
|
|
|
|
|
return items.map((item: any) => ({
|
|
|
|
|
|
...item,
|
|
|
|
|
|
key: String(item.key || item.value),
|
|
|
|
|
|
}));
|
|
|
|
|
|
},
|
2025-12-19 14:57:43 +08:00
|
|
|
|
},
|
2025-12-22 10:33:30 +08:00
|
|
|
|
},
|
2025-12-19 14:57:43 +08:00
|
|
|
|
{
|
|
|
|
|
|
component: 'InputNumber',
|
|
|
|
|
|
fieldName: 'nativeSkipNumber',
|
|
|
|
|
|
label: '正序跳过数量',
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
placeholder: `${$t('common.pleaseInput')}正序跳过数量`,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'InputNumber',
|
|
|
|
|
|
fieldName: 'nativeTakeNumber',
|
|
|
|
|
|
label: '正序获取数量',
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
placeholder: `${$t('common.pleaseInput')}正序获取数量`,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'InputNumber',
|
|
|
|
|
|
fieldName: 'reversalSkipNumber',
|
|
|
|
|
|
label: '反转跳过数量',
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
placeholder: `${$t('common.pleaseInput')}反转跳过数量`,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'InputNumber',
|
|
|
|
|
|
fieldName: 'reversalTakeNumber',
|
|
|
|
|
|
label: '反转获取数量',
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
placeholder: `${$t('common.pleaseInput')}反转获取数量`,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
];
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-12-22 10:33:30 +08:00
|
|
|
|
// 新增属性表单
|
|
|
|
|
|
const [AddPropertyForm, addPropertyFormApi] = useVbenForm({
|
|
|
|
|
|
collapsed: false,
|
|
|
|
|
|
commonConfig: {
|
|
|
|
|
|
labelWidth: 140,
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
class: 'w-4/5',
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
layout: 'horizontal',
|
|
|
|
|
|
schema: addPropertyFormSchema,
|
|
|
|
|
|
showCollapseButton: false,
|
|
|
|
|
|
showDefaultActions: false,
|
|
|
|
|
|
wrapperClass: 'grid-cols-2',
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 编辑属性表单
|
|
|
|
|
|
const [EditPropertyForm, editPropertyFormApi] = useVbenForm({
|
2025-12-19 14:57:43 +08:00
|
|
|
|
collapsed: false,
|
|
|
|
|
|
commonConfig: {
|
|
|
|
|
|
labelWidth: 140,
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
class: 'w-4/5',
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
layout: 'horizontal',
|
2025-12-22 10:33:30 +08:00
|
|
|
|
schema: editPropertyFormSchema.value,
|
2025-12-19 14:57:43 +08:00
|
|
|
|
showCollapseButton: false,
|
|
|
|
|
|
showDefaultActions: false,
|
|
|
|
|
|
wrapperClass: 'grid-cols-2',
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-12-22 10:33:30 +08:00
|
|
|
|
// 监听 editRow 变化,动态更新编辑表单 schema
|
2025-12-19 14:57:43 +08:00
|
|
|
|
watch(
|
|
|
|
|
|
() => editRow.value.id,
|
|
|
|
|
|
() => {
|
2025-12-22 10:33:30 +08:00
|
|
|
|
if (editPropertyFormApi && editPropertyFormApi.updateSchema) {
|
|
|
|
|
|
editPropertyFormApi.updateSchema(editPropertyFormSchema.value);
|
2025-12-19 14:57:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// 快速复制表单(选择平台和产品)
|
|
|
|
|
|
const [CopyPropertyForm, copyPropertyFormApi] = useVbenForm({
|
|
|
|
|
|
collapsed: false,
|
|
|
|
|
|
commonConfig: {
|
|
|
|
|
|
labelWidth: 140,
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
class: 'w-4/5',
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
layout: 'horizontal',
|
|
|
|
|
|
schema: [
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'ApiSelect',
|
|
|
|
|
|
fieldName: 'ioTPlatform',
|
|
|
|
|
|
label: $t('abp.deviceInfos.ioTPlatform'),
|
|
|
|
|
|
rules: z.preprocess(
|
|
|
|
|
|
(v) => (v == null ? '' : v),
|
|
|
|
|
|
z.string().min(1, $t('common.required')),
|
|
|
|
|
|
),
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
api: getCommonGetSelectList,
|
|
|
|
|
|
params: {
|
|
|
|
|
|
query: {
|
|
|
|
|
|
typeName: 'IoTPlatformTypeEnum',
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
labelField: 'value',
|
|
|
|
|
|
valueField: 'key',
|
|
|
|
|
|
optionsPropName: 'options',
|
|
|
|
|
|
immediate: true,
|
|
|
|
|
|
allowClear: true,
|
|
|
|
|
|
placeholder:
|
|
|
|
|
|
$t('common.pleaseSelect') + $t('abp.deviceInfos.ioTPlatform'),
|
|
|
|
|
|
afterFetch: (res: any) => {
|
|
|
|
|
|
if (Array.isArray(res)) return res;
|
|
|
|
|
|
if (res && Array.isArray(res.items)) return res.items;
|
|
|
|
|
|
if (res && Array.isArray(res.data)) return res.data;
|
|
|
|
|
|
return [];
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'ApiSelect',
|
|
|
|
|
|
fieldName: 'ioTPlatformProductId',
|
|
|
|
|
|
label: $t('common.BelongingProductName'),
|
|
|
|
|
|
rules: z.preprocess(
|
|
|
|
|
|
(v) => (v == null ? '' : v),
|
|
|
|
|
|
z.string().min(1, $t('common.required')),
|
|
|
|
|
|
),
|
|
|
|
|
|
dependencies: {
|
|
|
|
|
|
show(values: any) {
|
|
|
|
|
|
return !!values.ioTPlatform;
|
|
|
|
|
|
},
|
|
|
|
|
|
triggerFields: ['ioTPlatform'],
|
|
|
|
|
|
},
|
|
|
|
|
|
componentProps: (formValues: any) => {
|
|
|
|
|
|
const platform = formValues?.ioTPlatform;
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
api: platform
|
|
|
|
|
|
? postAggregationIoTplatformGetIoTplatformProductInfoAsync
|
|
|
|
|
|
: null,
|
|
|
|
|
|
params: {
|
|
|
|
|
|
body: {
|
|
|
|
|
|
ioTPlatformType:
|
|
|
|
|
|
typeof platform === 'string'
|
|
|
|
|
|
? Number.parseInt(platform)
|
|
|
|
|
|
: platform,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
labelField: 'productName',
|
|
|
|
|
|
valueField: 'ioTPlatformProductId',
|
|
|
|
|
|
optionsPropName: 'options',
|
|
|
|
|
|
immediate: false,
|
|
|
|
|
|
allowClear: true,
|
|
|
|
|
|
placeholder:
|
|
|
|
|
|
$t('common.pleaseSelect') + $t('common.BelongingProductName'),
|
|
|
|
|
|
afterFetch: (res: any) => {
|
|
|
|
|
|
if (Array.isArray(res)) return res;
|
|
|
|
|
|
if (res && Array.isArray(res.items)) return res.items;
|
|
|
|
|
|
if (res && Array.isArray(res.data)) return res.data;
|
|
|
|
|
|
if (res && res.data && Array.isArray(res.data.items)) {
|
|
|
|
|
|
return res.data.items;
|
|
|
|
|
|
}
|
|
|
|
|
|
return [];
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
showCollapseButton: false,
|
|
|
|
|
|
showDefaultActions: false,
|
|
|
|
|
|
wrapperClass: 'grid-cols-2',
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 快速复制设备端物模型表单
|
|
|
|
|
|
const [CopyDeviceThingModelForm, copyDeviceThingModelFormApi] = useVbenForm({
|
|
|
|
|
|
collapsed: false,
|
|
|
|
|
|
commonConfig: {
|
|
|
|
|
|
labelWidth: 140,
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
class: 'w-4/5',
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
layout: 'horizontal',
|
|
|
|
|
|
schema: [
|
|
|
|
|
|
{
|
|
|
|
|
|
component: 'ApiSelect',
|
|
|
|
|
|
fieldName: 'sourceDeviceThingModelId',
|
|
|
|
|
|
label: '选择设备端物模型',
|
|
|
|
|
|
rules: z.preprocess(
|
|
|
|
|
|
(v) => (v == null ? '' : v),
|
|
|
|
|
|
z.string().min(1, $t('common.required')),
|
|
|
|
|
|
),
|
|
|
|
|
|
componentProps: {
|
|
|
|
|
|
api: postDeviceThingModelManagementPageAsync,
|
|
|
|
|
|
params: {
|
|
|
|
|
|
body: {
|
|
|
|
|
|
pageIndex: 1,
|
|
|
|
|
|
pageSize: 1000,
|
|
|
|
|
|
isPage: false, // 不分页,获取全部数据
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
labelField: 'deviceModelName',
|
|
|
|
|
|
valueField: 'id',
|
|
|
|
|
|
optionsPropName: 'options',
|
|
|
|
|
|
immediate: true,
|
|
|
|
|
|
allowClear: true,
|
|
|
|
|
|
placeholder: '请选择要复制的设备端物模型',
|
|
|
|
|
|
afterFetch: (res: any) => {
|
|
|
|
|
|
if (Array.isArray(res)) return res;
|
|
|
|
|
|
if (res && Array.isArray(res.items)) return res.items;
|
|
|
|
|
|
if (res && Array.isArray(res.data)) return res.data;
|
|
|
|
|
|
if (res && res.data && Array.isArray(res.data.items)) {
|
|
|
|
|
|
return res.data.items;
|
|
|
|
|
|
}
|
|
|
|
|
|
return [];
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
showCollapseButton: false,
|
|
|
|
|
|
showDefaultActions: false,
|
|
|
|
|
|
wrapperClass: 'grid-cols-1',
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 打开新增属性弹窗
|
|
|
|
|
|
function openAddPropertyModal() {
|
2025-12-22 10:33:30 +08:00
|
|
|
|
addPropertyFormModalApi.open();
|
2025-12-19 14:57:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打开编辑属性弹窗
|
|
|
|
|
|
function openEditPropertyModal(record: any) {
|
|
|
|
|
|
editRow.value = record;
|
2025-12-22 10:33:30 +08:00
|
|
|
|
editPropertyFormModalApi.open();
|
2025-12-19 14:57:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打开快速复制平台端物模型弹窗
|
|
|
|
|
|
function openCopyPropertyModal() {
|
|
|
|
|
|
copyPropertyFormApi.resetForm();
|
|
|
|
|
|
copyPropertyModalApi.open();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打开快速复制设备端物模型弹窗
|
|
|
|
|
|
function openCopyDeviceThingModelModal() {
|
|
|
|
|
|
copyDeviceThingModelFormApi.resetForm();
|
|
|
|
|
|
copyDeviceThingModelModalApi.open();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-22 10:33:30 +08:00
|
|
|
|
// 提交新增属性
|
|
|
|
|
|
async function submitAddProperty() {
|
|
|
|
|
|
const { valid } = await addPropertyFormApi.validate();
|
2025-12-19 14:57:43 +08:00
|
|
|
|
if (!valid) return;
|
|
|
|
|
|
|
2025-12-22 10:33:30 +08:00
|
|
|
|
const formValues = await addPropertyFormApi.getValues();
|
2025-12-19 14:57:43 +08:00
|
|
|
|
const fetchParams: any = {
|
|
|
|
|
|
deviceThingModelId: deviceThingModelId.value,
|
2025-12-22 10:33:30 +08:00
|
|
|
|
...(formValues.ioTPlatformThingModelDataId && {
|
|
|
|
|
|
ioTPlatformThingModelDataId: String(
|
|
|
|
|
|
formValues.ioTPlatformThingModelDataId,
|
|
|
|
|
|
),
|
|
|
|
|
|
}),
|
|
|
|
|
|
nativeSkipNumber: formValues.nativeSkipNumber || 0,
|
|
|
|
|
|
nativeTakeNumber: formValues.nativeTakeNumber || 0,
|
|
|
|
|
|
parsingSequence:
|
|
|
|
|
|
typeof formValues.parsingSequence === 'string'
|
|
|
|
|
|
? Number.parseInt(formValues.parsingSequence)
|
|
|
|
|
|
: formValues.parsingSequence,
|
|
|
|
|
|
...(formValues.reversalSkipNumber !== undefined &&
|
|
|
|
|
|
formValues.reversalSkipNumber !== null && {
|
|
|
|
|
|
reversalSkipNumber: formValues.reversalSkipNumber,
|
|
|
|
|
|
}),
|
|
|
|
|
|
...(formValues.reversalTakeNumber !== undefined &&
|
|
|
|
|
|
formValues.reversalTakeNumber !== null && {
|
|
|
|
|
|
reversalTakeNumber: formValues.reversalTakeNumber,
|
2025-12-19 14:57:43 +08:00
|
|
|
|
}),
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
2025-12-22 10:33:30 +08:00
|
|
|
|
const resp = await postDeviceThingModelManagementPropertyCreateAsync({
|
|
|
|
|
|
body: fetchParams,
|
|
|
|
|
|
});
|
2025-12-19 14:57:43 +08:00
|
|
|
|
if (resp.data) {
|
2025-12-22 10:33:30 +08:00
|
|
|
|
Message.success($t('common.addSuccess'));
|
|
|
|
|
|
addPropertyFormModalApi.close();
|
|
|
|
|
|
await nextTick();
|
|
|
|
|
|
if (gridApi && gridApi.reload) {
|
|
|
|
|
|
await gridApi.reload();
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Message.error($t('common.addFail'));
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('提交属性失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提交编辑属性
|
|
|
|
|
|
async function submitEditProperty() {
|
|
|
|
|
|
const { valid } = await editPropertyFormApi.validate();
|
|
|
|
|
|
if (!valid) return;
|
|
|
|
|
|
|
|
|
|
|
|
const formValues = await editPropertyFormApi.getValues();
|
|
|
|
|
|
const fetchParams: any = {
|
|
|
|
|
|
id: editRow.value.id,
|
|
|
|
|
|
deviceThingModelId: deviceThingModelId.value,
|
|
|
|
|
|
...(formValues.filedType && { filedType: formValues.filedType }),
|
|
|
|
|
|
ioTPlatformRawFieldName: formValues.ioTPlatformRawFieldName,
|
|
|
|
|
|
ioTPlatformRawFieldDataType: formValues.ioTPlatformRawFieldDataType,
|
|
|
|
|
|
standardFieldName: formValues.standardFieldName,
|
|
|
|
|
|
standardFieldValueType: formValues.standardFieldValueType,
|
|
|
|
|
|
standardFieldDisplayName: formValues.standardFieldDisplayName,
|
|
|
|
|
|
...(formValues.isValueNeedConvert !== undefined && {
|
|
|
|
|
|
isValueNeedConvert: formValues.isValueNeedConvert,
|
|
|
|
|
|
}),
|
|
|
|
|
|
nativeSkipNumber: formValues.nativeSkipNumber || 0,
|
|
|
|
|
|
nativeTakeNumber: formValues.nativeTakeNumber || 0,
|
|
|
|
|
|
parsingSequence:
|
|
|
|
|
|
typeof formValues.parsingSequence === 'string'
|
|
|
|
|
|
? Number.parseInt(formValues.parsingSequence)
|
|
|
|
|
|
: formValues.parsingSequence,
|
|
|
|
|
|
...(formValues.reversalSkipNumber !== undefined &&
|
|
|
|
|
|
formValues.reversalSkipNumber !== null && {
|
|
|
|
|
|
reversalSkipNumber: formValues.reversalSkipNumber,
|
|
|
|
|
|
}),
|
|
|
|
|
|
...(formValues.reversalTakeNumber !== undefined &&
|
|
|
|
|
|
formValues.reversalTakeNumber !== null && {
|
|
|
|
|
|
reversalTakeNumber: formValues.reversalTakeNumber,
|
|
|
|
|
|
}),
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const resp = await postDeviceThingModelManagementPropertyUpdateAsync({
|
|
|
|
|
|
body: fetchParams,
|
|
|
|
|
|
});
|
|
|
|
|
|
if (resp.data) {
|
|
|
|
|
|
Message.success($t('common.editSuccess'));
|
|
|
|
|
|
editPropertyFormModalApi.close();
|
2025-12-19 14:57:43 +08:00
|
|
|
|
editRow.value = {};
|
|
|
|
|
|
await nextTick();
|
|
|
|
|
|
if (gridApi && gridApi.reload) {
|
|
|
|
|
|
await gridApi.reload();
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2025-12-22 10:33:30 +08:00
|
|
|
|
Message.error($t('common.editFail'));
|
2025-12-19 14:57:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('提交属性失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提交快速复制设备端物模型
|
|
|
|
|
|
async function submitCopyDeviceThingModel() {
|
|
|
|
|
|
const { valid } = await copyDeviceThingModelFormApi.validate();
|
|
|
|
|
|
if (!valid) return;
|
|
|
|
|
|
|
|
|
|
|
|
const formValues = await copyDeviceThingModelFormApi.getValues();
|
|
|
|
|
|
|
|
|
|
|
|
if (!formValues.sourceDeviceThingModelId) {
|
|
|
|
|
|
Message.warning('请选择要复制的设备端物模型');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const resp =
|
|
|
|
|
|
await postDeviceThingModelManagementCopyAnotherDeviceThingModelAsync({
|
|
|
|
|
|
body: {
|
|
|
|
|
|
ioTPlatform: Number.parseInt(String(ioTPlatform.value)) as 1 | 2,
|
|
|
|
|
|
deviceThingModelId: deviceThingModelId.value,
|
|
|
|
|
|
sourceProductId: formValues.sourceDeviceThingModelId,
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (resp.data) {
|
|
|
|
|
|
Message.success('快速复制设备端物模型属性成功');
|
|
|
|
|
|
copyDeviceThingModelModalApi.close();
|
|
|
|
|
|
await nextTick();
|
|
|
|
|
|
if (gridApi && gridApi.reload) {
|
|
|
|
|
|
await gridApi.reload();
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Message.error('快速复制设备端物模型属性失败');
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('快速复制设备端物模型属性失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提交快速复制平台端物模型
|
|
|
|
|
|
async function submitCopyProperty() {
|
|
|
|
|
|
const { valid } = await copyPropertyFormApi.validate();
|
|
|
|
|
|
if (!valid) return;
|
|
|
|
|
|
|
|
|
|
|
|
const formValues = await copyPropertyFormApi.getValues();
|
|
|
|
|
|
|
|
|
|
|
|
if (!formValues.ioTPlatform || !formValues.ioTPlatformProductId) {
|
|
|
|
|
|
Message.warning('请选择平台和产品');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const resp =
|
|
|
|
|
|
await postDeviceThingModelManagementCopyIoTplatformThingModelToDeviceAsync(
|
|
|
|
|
|
{
|
|
|
|
|
|
body: {
|
|
|
|
|
|
ioTPlatform: Number.parseInt(String(formValues.ioTPlatform)) as
|
|
|
|
|
|
| 1
|
|
|
|
|
|
| 2,
|
|
|
|
|
|
ioTPlatformProductId: String(formValues.ioTPlatformProductId),
|
|
|
|
|
|
deviceThingModelId: deviceThingModelId.value,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (resp.data) {
|
|
|
|
|
|
Message.success('快速复制平台端物模型属性成功');
|
|
|
|
|
|
copyPropertyModalApi.close();
|
|
|
|
|
|
await nextTick();
|
|
|
|
|
|
if (gridApi && gridApi.reload) {
|
|
|
|
|
|
await gridApi.reload();
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Message.error('快速复制平台端物模型属性失败');
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('快速复制平台端物模型属性失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 删除属性
|
|
|
|
|
|
async function onDeleteProperty(record: any) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const resp = await postDeviceThingModelManagementPropertyDeleteAsync({
|
|
|
|
|
|
body: { id: record.id },
|
|
|
|
|
|
});
|
|
|
|
|
|
if (resp.data) {
|
|
|
|
|
|
Message.success($t('common.deleteSuccess'));
|
|
|
|
|
|
await nextTick();
|
|
|
|
|
|
if (gridApi && gridApi.reload) {
|
|
|
|
|
|
await gridApi.reload();
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
Message.error($t('common.deleteFail'));
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('删除属性失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-18 22:05:55 +08:00
|
|
|
|
const [Modal, modalApi] = useVbenModal({
|
|
|
|
|
|
onOpenChange(isOpen: boolean) {
|
|
|
|
|
|
if (isOpen) {
|
|
|
|
|
|
const data = modalApi.getData<Record<string, any>>();
|
|
|
|
|
|
deviceThingModelId.value = data?.deviceThingModelId || '';
|
|
|
|
|
|
deviceModelName.value = data?.deviceModelName || '';
|
2025-12-19 14:57:43 +08:00
|
|
|
|
ioTPlatform.value = data?.ioTPlatform || '';
|
|
|
|
|
|
ioTPlatformProductId.value = data?.ioTPlatformProductId || '';
|
|
|
|
|
|
// 使用 nextTick 确保 Grid 组件已完全初始化
|
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
|
if (gridApi && gridApi.reload) {
|
|
|
|
|
|
gridApi.reload();
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2025-12-18 22:05:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
2025-12-19 14:57:43 +08:00
|
|
|
|
<Modal :title="`属性管理 - ${deviceModelName || ''}`" class="w-[1200px]">
|
2025-12-18 22:05:55 +08:00
|
|
|
|
<Grid>
|
2025-12-19 14:57:43 +08:00
|
|
|
|
<template #toolbar-actions>
|
|
|
|
|
|
<TableAction :actions="[
|
|
|
|
|
|
{
|
|
|
|
|
|
label: $t('common.add'),
|
|
|
|
|
|
type: 'primary',
|
|
|
|
|
|
icon: 'ant-design:plus-outlined',
|
|
|
|
|
|
onClick: openAddPropertyModal,
|
|
|
|
|
|
auth: ['AbpIdentity.Users.Create'],
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '快速复制平台端物模型',
|
|
|
|
|
|
type: 'default',
|
|
|
|
|
|
icon: 'ant-design:copy-outlined',
|
|
|
|
|
|
onClick: openCopyPropertyModal,
|
|
|
|
|
|
auth: ['AbpIdentity.Users.Create'],
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: '快速复制设备端物模型',
|
|
|
|
|
|
type: 'default',
|
|
|
|
|
|
icon: 'ant-design:copy-outlined',
|
|
|
|
|
|
onClick: openCopyDeviceThingModelModal,
|
|
|
|
|
|
auth: ['AbpIdentity.Users.Create'],
|
|
|
|
|
|
},
|
|
|
|
|
|
]" />
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<template #action="{ row }">
|
|
|
|
|
|
<TableAction :actions="[
|
|
|
|
|
|
{
|
|
|
|
|
|
label: $t('common.edit'),
|
|
|
|
|
|
type: 'link',
|
|
|
|
|
|
size: 'small',
|
|
|
|
|
|
auth: ['AbpIdentity.Users.Update'],
|
|
|
|
|
|
onClick: openEditPropertyModal.bind(null, row),
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: $t('common.delete'),
|
|
|
|
|
|
icon: 'ant-design:delete-outlined',
|
|
|
|
|
|
type: 'link',
|
|
|
|
|
|
size: 'small',
|
|
|
|
|
|
auth: ['AbpIdentity.Users.Delete'],
|
|
|
|
|
|
popConfirm: {
|
|
|
|
|
|
title: $t('common.askConfirmDelete'),
|
|
|
|
|
|
confirm: onDeleteProperty.bind(null, row),
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
]" />
|
|
|
|
|
|
</template>
|
2025-12-18 22:05:55 +08:00
|
|
|
|
</Grid>
|
2025-12-19 14:57:43 +08:00
|
|
|
|
|
2025-12-22 10:33:30 +08:00
|
|
|
|
<!-- 属性新增弹窗 -->
|
|
|
|
|
|
<AddPropertyFormModal :title="$t('common.add')" class="w-[900px]">
|
|
|
|
|
|
<AddPropertyForm />
|
|
|
|
|
|
</AddPropertyFormModal>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 属性编辑弹窗 -->
|
|
|
|
|
|
<EditPropertyFormModal :title="$t('common.edit')" class="w-[900px]">
|
|
|
|
|
|
<EditPropertyForm />
|
|
|
|
|
|
</EditPropertyFormModal>
|
2025-12-19 14:57:43 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 快速复制平台端物模型属性弹窗 -->
|
|
|
|
|
|
<CopyPropertyModal title="快速复制平台端物模型属性" class="w-[600px]">
|
|
|
|
|
|
<CopyPropertyForm />
|
|
|
|
|
|
</CopyPropertyModal>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 快速复制设备端物模型属性弹窗 -->
|
2025-12-22 10:33:30 +08:00
|
|
|
|
<CopyDeviceThingModelModal title="快速复制设备端物模型属性" class="w-[600px]">
|
2025-12-19 14:57:43 +08:00
|
|
|
|
<CopyDeviceThingModelForm />
|
|
|
|
|
|
</CopyDeviceThingModelModal>
|
2025-12-18 22:05:55 +08:00
|
|
|
|
</Modal>
|
|
|
|
|
|
</template>
|