设备端物模型属性完善

This commit is contained in:
ChenYi 2025-12-22 10:33:30 +08:00
parent cfbe8f4df0
commit f3ac09394c
6 changed files with 614 additions and 244 deletions

View File

@ -126,6 +126,7 @@ export type ComponentType =
| 'Select'
| 'Space'
| 'StandardThingModelCodeSelect'
| 'IoTPlatformThingModelDataSelect'
| 'Switch'
| 'Textarea'
| 'TimePicker'
@ -181,7 +182,14 @@ async function initComponentAdapter() {
StandardThingModelCodeSelect: defineAsyncComponent(
() =>
import(
'#/views/thingmodelinfo/ioTPlatformThingModelInfo/StandardThingModelCodeSelect.vue'
'#/views/thingmodelinfo/StandardThingModelCodeSelect.vue'
) as any,
),
// 自定义平台端物模型选择组件(分页搜索)
IoTPlatformThingModelDataSelect: defineAsyncComponent(
() =>
import(
'#/views/thingmodelinfo/IoTPlatformThingModelDataSelect.vue'
) as any,
),
// 自定义默认按钮

View File

@ -2765,7 +2765,7 @@ export const DeviceThingModelPageInputSchema = {
} as const;
export const DeviceThingModelPropertyCreateInputSchema = {
required: ['deviceThingModelId', 'ioTPlatformRawFieldDataType', 'ioTPlatformRawFieldName', 'nativeSkipNumber', 'nativeTakeNumber', 'parsingSequence', 'standardFieldDisplayName', 'standardFieldName', 'standardFieldValueType'],
required: ['deviceThingModelId', 'nativeSkipNumber', 'nativeTakeNumber', 'parsingSequence'],
type: 'object',
properties: {
deviceThingModelId: {
@ -2773,39 +2773,10 @@ export const DeviceThingModelPropertyCreateInputSchema = {
description: '设备端物模型Id',
format: 'uuid'
},
filedType: {
ioTPlatformThingModelDataId: {
type: 'string',
description: '物联网平台中对应产品物模型属性或者事件类型 JiShe.ServicePro.Core.DataDictionaryTypeConst',
nullable: true
},
ioTPlatformRawFieldName: {
minLength: 1,
type: 'string',
description: '物联网平台中对应的产品物模型属性或者事件名称'
},
ioTPlatformRawFieldDataType: {
minLength: 1,
type: 'string',
description: '物联网平台中对应的产品物模型属性或者事件数据类型JiShe.ServicePro.Core.OneNETAllThingModel'
},
standardFieldName: {
minLength: 1,
type: 'string',
description: '管理后台产品标准的物模型属性或者事件名称'
},
standardFieldValueType: {
minLength: 1,
type: 'string',
description: '标准物模型字段值类型'
},
standardFieldDisplayName: {
minLength: 1,
type: 'string',
description: '标准物模型字段显示名称'
},
isValueNeedConvert: {
type: 'boolean',
description: '是否需要值类型转换'
description: '平台端物模型数据Id',
format: 'uuid'
},
nativeSkipNumber: {
type: 'integer',
@ -3075,6 +3046,10 @@ export const DeviceThingModelPropertyUpdateInputSchema = {
required: ['deviceThingModelId', 'id', 'ioTPlatformRawFieldDataType', 'ioTPlatformRawFieldName', 'nativeSkipNumber', 'nativeTakeNumber', 'parsingSequence', 'standardFieldDisplayName', 'standardFieldName', 'standardFieldValueType'],
type: 'object',
properties: {
id: {
type: 'string',
format: 'uuid'
},
deviceThingModelId: {
type: 'string',
description: '设备端物模型Id',
@ -3138,10 +3113,6 @@ export const DeviceThingModelPropertyUpdateInputSchema = {
description: '反转获取数量',
format: 'int32',
nullable: true
},
id: {
type: 'string',
format: 'uuid'
}
},
additionalProperties: false,

View File

@ -1572,33 +1572,9 @@ export type DeviceThingModelPropertyCreateInput = {
*/
deviceThingModelId: string;
/**
* JiShe.ServicePro.Core.DataDictionaryTypeConst
* Id
*/
filedType?: (string) | null;
/**
*
*/
ioTPlatformRawFieldName: string;
/**
* JiShe.ServicePro.Core.OneNETAllThingModel
*/
ioTPlatformRawFieldDataType: string;
/**
*
*/
standardFieldName: string;
/**
*
*/
standardFieldValueType: string;
/**
*
*/
standardFieldDisplayName: string;
/**
*
*/
isValueNeedConvert?: boolean;
ioTPlatformThingModelDataId?: string;
/**
*
*/
@ -1771,6 +1747,7 @@ export type DeviceThingModelPropertyPageInput = {
*
*/
export type DeviceThingModelPropertyUpdateInput = {
id: string;
/**
* Id
*/
@ -1820,7 +1797,6 @@ export type DeviceThingModelPropertyUpdateInput = {
*
*/
reversalTakeNumber?: (number) | null;
id: string;
};
export type DeviceThingModelUpdateInput = {

View File

@ -0,0 +1,198 @@
<script setup lang="ts">
import { ref, watch, computed, h } from 'vue';
import { Select, Divider, Row } from 'ant-design-vue';
import { ChevronLeft, ChevronRight } from '@vben/icons';
import { postIoTplatformThingModelInfoPageAsync } from '#/api-client';
import { $t } from '#/locales';
import { useDebounceFn } from '@vueuse/core';
interface Props {
value?: string;
typeCode?: string | number | null;
filedType?: string | null;
ioTPlatform?: number | string | null;
ioTPlatformProductId?: string | null;
placeholder?: string;
disabled?: boolean;
allowClear?: boolean;
onResolve?: (item: any | null) => void;
}
const props = withDefaults(defineProps<Props>(), {
placeholder: $t('common.pleaseSelect') + $t('abp.thingModelInfos.StandardFieldName'),
disabled: false,
allowClear: true,
});
const emit = defineEmits<{
'update:value': [string | undefined];
change: [string | undefined];
'item-change': [any | null];
}>();
const VNodes = (props: any) => {
return props.vnodes;
};
const options = ref<any[]>([]);
const total = ref(0);
const loading = ref<boolean>(false);
const query = ref({
pageIndex: 1,
pageSize: 10,
filter: '',
});
const maxPage = computed(() => Math.ceil((total.value || 0) / query.value.pageSize) || 1);
const fetchData = async () => {
// ID
if (!props.ioTPlatform || !props.ioTPlatformProductId) {
options.value = [];
total.value = 0;
return;
}
loading.value = true;
try {
const requestBody: any = {
pageIndex: query.value.pageIndex,
pageSize: query.value.pageSize,
...(query.value.filter && { searchKeyWords: query.value.filter }),
...(props.ioTPlatform && {
ioTPlatform:
typeof props.ioTPlatform === 'string'
? Number.parseInt(props.ioTPlatform)
: props.ioTPlatform,
}),
...(props.ioTPlatformProductId && {
ioTPlatformProductId: String(props.ioTPlatformProductId),
}),
...(props.filedType && { filedType: String(props.filedType) }),
...(props.typeCode && !props.filedType && { filedType: String(props.typeCode) }),
};
const { data } = await postIoTplatformThingModelInfoPageAsync({
body: requestBody,
});
const items = Array.isArray(data?.items) ? data!.items : [];
const mappedItems = items.map((item: any) => ({
label: `${item.standardFieldDisplayName || item.ioTPlatformRawFieldName || item.id || ''}`,
value: item.id || '',
...item,
}));
//
if (props.value && props.value.trim() !== '' && !mappedItems.find(item => item.value === props.value)) {
//
mappedItems.unshift({
label: `当前值: ${props.value}`,
value: props.value,
displayText: props.value,
code: props.value,
});
}
options.value = mappedItems;
total.value = (data as any)?.totalCount || 0;
} catch (err) {
console.error('获取标准物模型编码失败:', err);
} finally {
loading.value = false;
}
};
const changePage = (next: number) => {
if (next === 1) {
if (query.value.pageIndex >= maxPage.value) return;
query.value.pageIndex += 1;
} else {
if (query.value.pageIndex <= 1) return;
query.value.pageIndex -= 1;
}
fetchData();
};
const onSearch = useDebounceFn((kw: string) => {
query.value.pageIndex = 1;
query.value.filter = kw;
fetchData();
}, 400);
const onChange = (val?: string) => {
emit('update:value', val);
emit('change', val);
if (val) {
const found = options.value.find((o) => o.value === val) || null;
emit('item-change', found);
props.onResolve && props.onResolve(found);
} else {
emit('item-change', null);
props.onResolve && props.onResolve(null);
}
};
watch(
() => [props.filedType, props.typeCode, props.ioTPlatform, props.ioTPlatformProductId],
() => {
// reset when filedType/typeCode/platform/product changes
query.value.pageIndex = 1;
query.value.filter = '';
options.value = [];
total.value = 0;
// IDfiledType/typeCode
if (props.ioTPlatform && props.ioTPlatformProductId) {
fetchData();
}
},
{ immediate: true },
);
//
watch(
() => props.value,
(newValue) => {
if (newValue && newValue.trim() !== '' && props.ioTPlatform && props.ioTPlatformProductId && !options.value.find(item => item.value === newValue)) {
//
fetchData();
}
},
{ immediate: true },
);
</script>
<template>
<Select
:value="value"
:showSearch="true"
:filter-option="false"
:options="options"
:placeholder="placeholder"
:disabled="disabled"
:allowClear="allowClear"
:loading="loading"
@search="onSearch"
@change="onChange"
>
<template #dropdownRender="{ menuNode: menu }">
<v-nodes :vnodes="menu" />
<Divider style="margin: 4px 0" />
<div @mousedown="(e) => e.preventDefault()">
<Row type="flex" justify="space-around" align="middle">
<ChevronLeft @click="changePage(0)" :class="{ 'text-gray-400': query.pageIndex <= 1 }"
style="cursor: pointer; width: 16px; height: 16px;" />
<div>{{ `${query.pageIndex}/${maxPage}` }}</div>
<ChevronRight @click="changePage(1)" :class="{ 'text-gray-400': query.pageIndex >= maxPage }"
style="cursor: pointer; width: 16px; height: 16px;" />
</Row>
</div>
</template>
</Select>
</template>
<style lang="less" scoped>
.text-gray-400 {
color: #9ca3af;
cursor: not-allowed !important;
}
</style>

View File

@ -22,6 +22,8 @@ import {
import { TableAction } from '#/components/table-action';
import { $t } from '#/locales';
import IoTPlatformThingModelDataSelect from '../IoTPlatformThingModelDataSelect.vue';
defineOptions({
name: 'DeviceThingModelPropertyModal',
});
@ -155,13 +157,34 @@ const [Grid, gridApi] = useVbenVxeGrid({
},
});
// /
const [PropertyFormModal, propertyFormModalApi] = useVbenModal({
//
const [AddPropertyFormModal, addPropertyFormModalApi] = useVbenModal({
draggable: true,
footer: true,
showCancelButton: true,
showConfirmButton: true,
onConfirm: submitProperty,
onConfirm: submitAddProperty,
onBeforeClose: () => {
return true;
},
onOpenChange: (isOpen: boolean) => {
if (isOpen) {
//
addPropertyFormApi.resetForm();
}
},
onCancel: () => {
addPropertyFormModalApi.close();
},
});
//
const [EditPropertyFormModal, editPropertyFormModalApi] = useVbenModal({
draggable: true,
footer: true,
showCancelButton: true,
showConfirmButton: true,
onConfirm: submitEditProperty,
onBeforeClose: () => {
return true;
},
@ -184,19 +207,16 @@ const [PropertyFormModal, propertyFormModalApi] = useVbenModal({
//
values.parsingSequence = String(values.parsingSequence);
}
propertyFormApi.setValues(values);
editPropertyFormApi.setValues(values);
}
} catch (error) {
console.error('加载属性详情失败:', error);
}
});
} else if (isOpen) {
//
propertyFormApi.resetForm();
}
},
onCancel: () => {
propertyFormModalApi.close();
editPropertyFormModalApi.close();
},
});
@ -230,151 +250,273 @@ const [CopyDeviceThingModelModal, copyDeviceThingModelModalApi] = useVbenModal({
},
});
// schema
const propertyFormSchema = computed(() => {
const isEdit = !!editRow.value.id;
// schema
const addPropertyFormSchema = computed(() => [
{
component: 'ApiSelect',
fieldName: 'filedType',
label: '物模型类型',
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
typeName: 'DataDictionaryTypeConst',
},
},
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',
},
},
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')}标准属性名称`,
disabled: isEdit, //
},
{
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')}标准属性标识符`,
disabled: isEdit, //
},
},
{
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',
},
},
labelField: 'value',
valueField: 'secondValue',
optionsPropName: 'options',
immediate: true,
allowClear: true,
disabled: isEdit, //
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 [];
},
{
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',
},
},
},
{
component: 'Input',
fieldName: 'ioTPlatformRawFieldName',
label: '平台属性标识符',
rules: z.preprocess(
(v) => (v == null ? '' : v),
z.string().min(1, $t('common.required')),
),
componentProps: {
placeholder: `${$t('common.pleaseInput')}平台属性标识符`,
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 [];
},
},
{
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',
},
},
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 [];
},
{
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',
},
},
},
{
component: 'Switch',
fieldName: 'isValueNeedConvert',
label: '值类型是否转换',
componentProps: {
checkedChildren: '是',
unCheckedChildren: '否',
style: { width: 'auto' }, //
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 [];
},
},
{
component: 'ApiSelect',
fieldName: 'parsingSequence',
label: '解析方式',
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
typeName: 'ParsingSequenceTypeEnum',
},
},
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: 'Switch',
fieldName: 'isValueNeedConvert',
label: '值类型是否转换',
componentProps: {
checkedChildren: '是',
unCheckedChildren: '否',
style: { width: 'auto' }, //
},
},
{
component: 'ApiSelect',
fieldName: 'parsingSequence',
label: '解析方式',
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
typeName: 'ParsingSequenceTypeEnum',
},
},
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',
@ -414,8 +556,8 @@ const propertyFormSchema = computed(() => {
];
});
//
const [PropertyForm, propertyFormApi] = useVbenForm({
//
const [AddPropertyForm, addPropertyFormApi] = useVbenForm({
collapsed: false,
commonConfig: {
labelWidth: 140,
@ -424,18 +566,34 @@ const [PropertyForm, propertyFormApi] = useVbenForm({
},
},
layout: 'horizontal',
schema: propertyFormSchema.value,
schema: addPropertyFormSchema,
showCollapseButton: false,
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
// editRow schema
//
const [EditPropertyForm, editPropertyFormApi] = useVbenForm({
collapsed: false,
commonConfig: {
labelWidth: 140,
componentProps: {
class: 'w-4/5',
},
},
layout: 'horizontal',
schema: editPropertyFormSchema.value,
showCollapseButton: false,
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
// editRow schema
watch(
() => editRow.value.id,
() => {
if (propertyFormApi && propertyFormApi.updateSchema) {
propertyFormApi.updateSchema(propertyFormSchema.value);
if (editPropertyFormApi && editPropertyFormApi.updateSchema) {
editPropertyFormApi.updateSchema(editPropertyFormSchema.value);
}
},
);
@ -588,14 +746,13 @@ const [CopyDeviceThingModelForm, copyDeviceThingModelFormApi] = useVbenForm({
//
function openAddPropertyModal() {
editRow.value = {};
propertyFormModalApi.open();
addPropertyFormModalApi.open();
}
//
function openEditPropertyModal(record: any) {
editRow.value = record;
propertyFormModalApi.open();
editPropertyFormModalApi.open();
}
//
@ -610,44 +767,105 @@ function openCopyDeviceThingModelModal() {
copyDeviceThingModelModalApi.open();
}
// /
async function submitProperty() {
const isEdit = !!editRow.value.id;
const { valid } = await propertyFormApi.validate();
//
async function submitAddProperty() {
const { valid } = await addPropertyFormApi.validate();
if (!valid) return;
const formValues = await propertyFormApi.getValues();
const formValues = await addPropertyFormApi.getValues();
const fetchParams: any = {
...formValues,
deviceThingModelId: deviceThingModelId.value,
...(formValues.parsingSequence && {
//
parsingSequence: Number.parseInt(String(formValues.parsingSequence)),
...(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,
}),
...(isEdit && { id: editRow.value.id }),
};
try {
const api = isEdit
? postDeviceThingModelManagementPropertyUpdateAsync
: postDeviceThingModelManagementPropertyCreateAsync;
const resp = await api({ body: fetchParams });
const resp = await postDeviceThingModelManagementPropertyCreateAsync({
body: fetchParams,
});
if (resp.data) {
Message.success(
isEdit ? $t('common.editSuccess') : $t('common.addSuccess'),
);
propertyFormModalApi.close();
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();
editRow.value = {};
await nextTick();
if (gridApi && gridApi.reload) {
await gridApi.reload();
}
} else {
Message.error(isEdit ? $t('common.editFail') : $t('common.addFail'));
Message.error($t('common.editFail'));
}
} catch (error) {
console.error('提交属性失败:', error);
Message.error(isEdit ? $t('common.editFail') : $t('common.addFail'));
}
}
@ -685,7 +903,6 @@ async function submitCopyDeviceThingModel() {
}
} catch (error) {
console.error('快速复制设备端物模型属性失败:', error);
Message.error('快速复制设备端物模型属性失败');
}
}
@ -727,7 +944,6 @@ async function submitCopyProperty() {
}
} catch (error) {
console.error('快速复制平台端物模型属性失败:', error);
Message.error('快速复制平台端物模型属性失败');
}
}
@ -748,7 +964,6 @@ async function onDeleteProperty(record: any) {
}
} catch (error) {
console.error('删除属性失败:', error);
Message.error($t('common.deleteFail'));
}
}
@ -824,10 +1039,15 @@ const [Modal, modalApi] = useVbenModal({
</template>
</Grid>
<!-- 属性新增/编辑弹窗 -->
<PropertyFormModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[900px]">
<PropertyForm />
</PropertyFormModal>
<!-- 属性新增弹窗 -->
<AddPropertyFormModal :title="$t('common.add')" class="w-[900px]">
<AddPropertyForm />
</AddPropertyFormModal>
<!-- 属性编辑弹窗 -->
<EditPropertyFormModal :title="$t('common.edit')" class="w-[900px]">
<EditPropertyForm />
</EditPropertyFormModal>
<!-- 快速复制平台端物模型属性弹窗 -->
<CopyPropertyModal title="快速复制平台端物模型属性" class="w-[600px]">
@ -835,10 +1055,7 @@ const [Modal, modalApi] = useVbenModal({
</CopyPropertyModal>
<!-- 快速复制设备端物模型属性弹窗 -->
<CopyDeviceThingModelModal
title="快速复制设备端物模型属性"
class="w-[600px]"
>
<CopyDeviceThingModelModal title="快速复制设备端物模型属性" class="w-[600px]">
<CopyDeviceThingModelForm />
</CopyDeviceThingModelModal>
</Modal>