设备端物模型管理界面
This commit is contained in:
parent
288b153e43
commit
031364ba7e
@ -2544,6 +2544,9 @@ export const DeviceThingModelCreateInputSchema = {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
description: '脚本函数体',
|
description: '脚本函数体',
|
||||||
nullable: true
|
nullable: true
|
||||||
|
},
|
||||||
|
parsingSequence: {
|
||||||
|
'$ref': '#/components/schemas/ParsingSequenceTypeEnum'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
@ -3105,6 +3108,9 @@ export const DeviceThingModelUpdateInputSchema = {
|
|||||||
description: '脚本函数体',
|
description: '脚本函数体',
|
||||||
nullable: true
|
nullable: true
|
||||||
},
|
},
|
||||||
|
parsingSequence: {
|
||||||
|
'$ref': '#/components/schemas/ParsingSequenceTypeEnum'
|
||||||
|
},
|
||||||
id: {
|
id: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'uuid'
|
format: 'uuid'
|
||||||
|
|||||||
@ -1433,6 +1433,7 @@ export type DeviceThingModelCreateInput = {
|
|||||||
* 脚本函数体
|
* 脚本函数体
|
||||||
*/
|
*/
|
||||||
functionScript?: (string) | null;
|
functionScript?: (string) | null;
|
||||||
|
parsingSequence?: ParsingSequenceTypeEnum;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1796,6 +1797,7 @@ export type DeviceThingModelUpdateInput = {
|
|||||||
* 脚本函数体
|
* 脚本函数体
|
||||||
*/
|
*/
|
||||||
functionScript?: (string) | null;
|
functionScript?: (string) | null;
|
||||||
|
parsingSequence?: ParsingSequenceTypeEnum;
|
||||||
id?: string;
|
id?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,188 +0,0 @@
|
|||||||
<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 { postDataDictionarySelectDetail } from '#/api-client';
|
|
||||||
import { $t } from '#/locales';
|
|
||||||
import { useDebounceFn } from '@vueuse/core';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
value?: string;
|
|
||||||
typeCode?: string | number | 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 () => {
|
|
||||||
if (!props.typeCode) {
|
|
||||||
options.value = [];
|
|
||||||
total.value = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
loading.value = true;
|
|
||||||
try {
|
|
||||||
const { data } = await postDataDictionarySelectDetail({
|
|
||||||
body: {
|
|
||||||
filter: query.value.filter,
|
|
||||||
typeCode: String(props.typeCode),
|
|
||||||
pageIndex: query.value.pageIndex,
|
|
||||||
pageSize: query.value.pageSize,
|
|
||||||
} as any,
|
|
||||||
});
|
|
||||||
const items = Array.isArray(data?.items) ? data!.items : [];
|
|
||||||
const mappedItems = items.map((item: any) => ({
|
|
||||||
label: `${item.displayText}`,
|
|
||||||
value: item.code,
|
|
||||||
...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.typeCode,
|
|
||||||
() => {
|
|
||||||
// reset when type changes, do not auto-fetch until user searches
|
|
||||||
query.value.pageIndex = 1;
|
|
||||||
query.value.filter = '';
|
|
||||||
options.value = [];
|
|
||||||
total.value = 0;
|
|
||||||
if (props.typeCode) {
|
|
||||||
fetchData();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
// 监听初始值变化,确保编辑时能正确显示
|
|
||||||
watch(
|
|
||||||
() => props.value,
|
|
||||||
(newValue) => {
|
|
||||||
if (newValue && newValue.trim() !== '' && props.typeCode && !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>
|
|
||||||
|
|
||||||
|
|
||||||
@ -2,66 +2,91 @@
|
|||||||
import type { VbenFormProps } from '#/adapter/form';
|
import type { VbenFormProps } from '#/adapter/form';
|
||||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||||
|
|
||||||
import { h, nextTick, ref, watch } from 'vue';
|
import { h, nextTick, ref } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
import { message as Message, Modal, Tag } from 'ant-design-vue';
|
import { message as Message, Tag } from 'ant-design-vue';
|
||||||
|
|
||||||
import { useVbenForm } from '#/adapter/form';
|
import { useVbenForm } from '#/adapter/form';
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import {
|
import {
|
||||||
postIoTplatformThingModelInfoCopyAnotherThingModelAsync,
|
postDeviceThingModelManagementCreateAsync,
|
||||||
postIoTplatformThingModelInfoCopyStandardThingModel,
|
postDeviceThingModelManagementDeleteAsync,
|
||||||
postIoTplatformThingModelInfoCreateAsync,
|
postDeviceThingModelManagementPageAsync,
|
||||||
postIoTplatformThingModelInfoDeleteAsync,
|
postDeviceThingModelManagementUpdateAsync,
|
||||||
postIoTplatformThingModelInfoPageAsync,
|
|
||||||
postIoTplatformThingModelInfoUpdateAsync,
|
|
||||||
} from '#/api-client';
|
} from '#/api-client';
|
||||||
import { TableAction } from '#/components/table-action';
|
import { TableAction } from '#/components/table-action';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
addThingModelFormSchema,
|
addDeviceThingModelFormSchema,
|
||||||
copyThingModelFormSchema,
|
editDeviceThingModelFormSchema,
|
||||||
editThingModelFormSchema,
|
|
||||||
querySchema,
|
querySchema,
|
||||||
tableSchema,
|
tableSchema,
|
||||||
} from './schema';
|
} from './schema';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'ThingModelInfoModal',
|
name: 'DeviceThingModelManagement',
|
||||||
});
|
});
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const route = useRoute();
|
||||||
visible: false,
|
|
||||||
productId: '',
|
|
||||||
productName: '',
|
|
||||||
ioTPlatform: '2',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 定义emits
|
// 从路由参数获取初始平台和产品信息(如果有)
|
||||||
const emit = defineEmits<{
|
const productId = ref<string>((route.query.productId as string) || '');
|
||||||
close: [];
|
const ioTPlatform = ref<string>((route.query.ioTPlatform as string) || '');
|
||||||
'update:visible': [value: boolean];
|
|
||||||
}>();
|
|
||||||
|
|
||||||
// 定义props
|
|
||||||
interface Props {
|
|
||||||
visible?: boolean;
|
|
||||||
productId?: string;
|
|
||||||
productName?: string;
|
|
||||||
ioTPlatform?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const formOptions: VbenFormProps = {
|
const formOptions: VbenFormProps = {
|
||||||
schema: querySchema.value,
|
schema: querySchema.value,
|
||||||
|
initialValues: {
|
||||||
|
ioTPlatform: route.query.ioTPlatform
|
||||||
|
? String(route.query.ioTPlatform)
|
||||||
|
: undefined,
|
||||||
|
ioTPlatformProductId: route.query.productId
|
||||||
|
? String(route.query.productId)
|
||||||
|
: undefined,
|
||||||
|
},
|
||||||
|
submitOnChange: false,
|
||||||
|
handleValuesChange: async (values, changedFields) => {
|
||||||
|
// 平台变化时,清空产品并更新状态
|
||||||
|
if (changedFields.includes('ioTPlatform')) {
|
||||||
|
if (values.ioTPlatform) {
|
||||||
|
ioTPlatform.value = String(values.ioTPlatform);
|
||||||
|
if (gridApi?.formApi) {
|
||||||
|
await gridApi.formApi.setValues({
|
||||||
|
ioTPlatformProductId: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
productId.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 产品变化时,更新 productId 并刷新列表
|
||||||
|
if (changedFields.includes('ioTPlatformProductId')) {
|
||||||
|
if (values.ioTPlatformProductId) {
|
||||||
|
productId.value = String(values.ioTPlatformProductId);
|
||||||
|
} else {
|
||||||
|
productId.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(async () => {
|
||||||
|
if (gridApi && gridApi.reload) {
|
||||||
|
try {
|
||||||
|
await gridApi.reload();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('重新加载设备端物模型列表时出错:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const gridOptions: VxeGridProps<any> = {
|
const gridOptions: VxeGridProps<any> = {
|
||||||
checkboxConfig: {
|
checkboxConfig: {
|
||||||
highlight: true,
|
highlight: true,
|
||||||
labelField: 'thingModelName',
|
labelField: 'deviceModelName',
|
||||||
},
|
},
|
||||||
columns: tableSchema.value,
|
columns: tableSchema.value,
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
@ -76,20 +101,40 @@ const gridOptions: VxeGridProps<any> = {
|
|||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
query: async ({ page }, formValues) => {
|
query: async ({ page }, formValues) => {
|
||||||
const { data } = await postIoTplatformThingModelInfoPageAsync({
|
// 优先使用表单值,如果没有则使用响应式变量
|
||||||
query: {
|
const currentPlatform = formValues?.ioTPlatform || ioTPlatform.value;
|
||||||
input: {
|
const currentProductId =
|
||||||
|
formValues?.ioTPlatformProductId || productId.value;
|
||||||
|
|
||||||
|
if (!currentPlatform || !currentProductId) {
|
||||||
|
return {
|
||||||
|
items: [],
|
||||||
|
totalCount: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { data } = await postDeviceThingModelManagementPageAsync({
|
||||||
|
body: {
|
||||||
pageIndex: page.currentPage,
|
pageIndex: page.currentPage,
|
||||||
pageSize: page.pageSize,
|
pageSize: page.pageSize,
|
||||||
ioTPlatform: Number.parseInt(props.ioTPlatform) as 1 | 2,
|
ioTPlatform:
|
||||||
ioTPlatformProductId: props.productId,
|
typeof currentPlatform === 'string'
|
||||||
...(formValues?.SearchKeyWords && { searchKeyWords: formValues.SearchKeyWords }),
|
? Number.parseInt(currentPlatform)
|
||||||
},
|
: currentPlatform,
|
||||||
|
ioTPlatformProductId: String(currentProductId),
|
||||||
|
searchKeyWords: formValues?.SearchKeyWords,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// 更新数据状态,检查是否有数据
|
|
||||||
hasData.value = data?.items && data.items.length > 0;
|
return data || { items: [], totalCount: 0 };
|
||||||
return data;
|
} catch (error) {
|
||||||
|
console.error('查询设备端物模型列表失败:', error);
|
||||||
|
return {
|
||||||
|
items: [],
|
||||||
|
totalCount: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -99,9 +144,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });
|
|||||||
|
|
||||||
const editRow: Record<string, any> = ref({});
|
const editRow: Record<string, any> = ref({});
|
||||||
|
|
||||||
// 跟踪数据状态,用于控制按钮显示
|
|
||||||
const hasData = ref(true);
|
|
||||||
|
|
||||||
const [ThingModelModal, thingModelModalApi] = useVbenModal({
|
const [ThingModelModal, thingModelModalApi] = useVbenModal({
|
||||||
draggable: true,
|
draggable: true,
|
||||||
footer: true,
|
footer: true,
|
||||||
@ -124,20 +166,6 @@ const [ThingModelModal, thingModelModalApi] = useVbenModal({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const [CopyModal, copyModalApi] = useVbenModal({
|
|
||||||
draggable: true,
|
|
||||||
footer: true,
|
|
||||||
showCancelButton: true,
|
|
||||||
showConfirmButton: true,
|
|
||||||
onConfirm: submitCopy,
|
|
||||||
onBeforeClose: () => {
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
onCancel: () => {
|
|
||||||
copyModalApi.close();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const [AddForm, addFormApi] = useVbenForm({
|
const [AddForm, addFormApi] = useVbenForm({
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
commonConfig: {
|
commonConfig: {
|
||||||
@ -147,7 +175,7 @@ const [AddForm, addFormApi] = useVbenForm({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
layout: 'horizontal',
|
layout: 'horizontal',
|
||||||
schema: addThingModelFormSchema.value,
|
schema: addDeviceThingModelFormSchema.value,
|
||||||
showCollapseButton: false,
|
showCollapseButton: false,
|
||||||
showDefaultActions: false,
|
showDefaultActions: false,
|
||||||
wrapperClass: 'grid-cols-2',
|
wrapperClass: 'grid-cols-2',
|
||||||
@ -162,98 +190,49 @@ const [EditForm, editFormApi] = useVbenForm({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
layout: 'horizontal',
|
layout: 'horizontal',
|
||||||
schema: editThingModelFormSchema.value,
|
schema: editDeviceThingModelFormSchema.value,
|
||||||
showCollapseButton: false,
|
showCollapseButton: false,
|
||||||
showDefaultActions: false,
|
showDefaultActions: false,
|
||||||
wrapperClass: 'grid-cols-2',
|
wrapperClass: 'grid-cols-2',
|
||||||
});
|
});
|
||||||
|
|
||||||
const [CopyForm, copyFormApi] = useVbenForm({
|
// 新增 / 编辑提交
|
||||||
collapsed: false,
|
|
||||||
commonConfig: {
|
|
||||||
labelWidth: 110,
|
|
||||||
componentProps: {
|
|
||||||
class: 'w-4/5',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
layout: 'horizontal',
|
|
||||||
schema: copyThingModelFormSchema.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 });
|
|
||||||
console.log('所有props:', props);
|
|
||||||
if (visible && productId) {
|
|
||||||
// 延迟执行,确保组件完全初始化
|
|
||||||
setTimeout(async () => {
|
|
||||||
try {
|
|
||||||
// 设置表单筛选条件(如果有搜索关键词等筛选字段)
|
|
||||||
const filterValues: any = {};
|
|
||||||
|
|
||||||
// 注意:ioTPlatformProductId 已经在 API 调用中通过 props.productId 传递
|
|
||||||
// 这里只需要设置查询表单中存在的字段(如 SearchKeyWords)
|
|
||||||
|
|
||||||
console.log('设置筛选条件:', filterValues);
|
|
||||||
|
|
||||||
// 设置筛选表单的值
|
|
||||||
if (Object.keys(filterValues).length > 0) {
|
|
||||||
await gridApi.formApi.setValues(filterValues);
|
|
||||||
}
|
|
||||||
// 重新加载数据(即使没有筛选条件也要重新加载,因为 productId 可能已变化)
|
|
||||||
await gridApi.reload();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('设置筛选条件时出错:', error);
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
// 新增和编辑提交的逻辑
|
|
||||||
async function submit() {
|
async function submit() {
|
||||||
const isEdit = !!editRow.value.id;
|
const isEdit = !!editRow.value.id;
|
||||||
const formApi = isEdit ? editFormApi : addFormApi;
|
const formApi = isEdit ? editFormApi : addFormApi;
|
||||||
const api = isEdit
|
const api = isEdit
|
||||||
? postIoTplatformThingModelInfoUpdateAsync
|
? postDeviceThingModelManagementUpdateAsync
|
||||||
: postIoTplatformThingModelInfoCreateAsync;
|
: postDeviceThingModelManagementCreateAsync;
|
||||||
|
|
||||||
const { valid } = await formApi.validate();
|
const { valid } = await formApi.validate();
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
|
|
||||||
const formValues = await formApi.getValues();
|
const formValues = await formApi.getValues();
|
||||||
|
|
||||||
|
// 表单中已经包含 ioTPlatform / ioTPlatformProductId,不再强制从查询条件取
|
||||||
const fetchParams: any = {
|
const fetchParams: any = {
|
||||||
...formValues,
|
...formValues,
|
||||||
// 自动添加平台和产品信息
|
|
||||||
ioTPlatform: Number.parseInt(props.ioTPlatform) as 1 | 2,
|
|
||||||
ioTPlatformProductId: props.productId,
|
|
||||||
// 编辑时需要添加ID
|
|
||||||
...(isEdit && { id: editRow.value.id }),
|
...(isEdit && { id: editRow.value.id }),
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await api({ query: { input: fetchParams } });
|
const resp = await api({ body: fetchParams });
|
||||||
if (resp.data) {
|
if (resp.data) {
|
||||||
Message.success(
|
Message.success(
|
||||||
editRow.value.id ? $t('common.editSuccess') : $t('common.addSuccess'),
|
isEdit ? $t('common.editSuccess') : $t('common.addSuccess'),
|
||||||
);
|
);
|
||||||
thingModelModalApi.close();
|
thingModelModalApi.close();
|
||||||
editRow.value = {};
|
editRow.value = {};
|
||||||
gridApi.reload();
|
gridApi.reload();
|
||||||
} else {
|
} else {
|
||||||
Message.error(
|
Message.error(
|
||||||
editRow.value.id ? $t('common.editFail') : $t('common.addFail'),
|
isEdit ? $t('common.editFail') : $t('common.addFail'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('提交失败:', error);
|
console.error('提交设备端物模型失败:', error);
|
||||||
Message.error(
|
Message.error(
|
||||||
editRow.value.id ? $t('common.editFail') : $t('common.addFail'),
|
isEdit ? $t('common.editFail') : $t('common.addFail'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,63 +247,11 @@ const openAddModal = async () => {
|
|||||||
thingModelModalApi.open();
|
thingModelModalApi.open();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开复制已有模型模态框
|
// 删除
|
||||||
const openCopyAnotherThingModelModal = async () => {
|
|
||||||
console.log('打开复制模态框,当前props:', {
|
|
||||||
productId: props.productId,
|
|
||||||
productName: props.productName,
|
|
||||||
ioTPlatform: props.ioTPlatform,
|
|
||||||
});
|
|
||||||
copyModalApi.open();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 复制提交逻辑
|
|
||||||
async function submitCopy() {
|
|
||||||
const { valid } = await copyFormApi.validate();
|
|
||||||
if (!valid) return;
|
|
||||||
|
|
||||||
const formValues = await copyFormApi.getValues();
|
|
||||||
|
|
||||||
console.log('复制提交参数:', {
|
|
||||||
formValues,
|
|
||||||
props: {
|
|
||||||
productId: props.productId,
|
|
||||||
productName: props.productName,
|
|
||||||
ioTPlatform: props.ioTPlatform,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
const resp = await postIoTplatformThingModelInfoCopyAnotherThingModelAsync({
|
|
||||||
query: {
|
|
||||||
input: {
|
|
||||||
ioTPlatform: Number.parseInt(props.ioTPlatform) as 1 | 2,
|
|
||||||
ioTPlatformProductId: props.productId,
|
|
||||||
sourceProductId: formValues.ioTPlatformProductId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (resp.data) {
|
|
||||||
Message.success('复制模型成功');
|
|
||||||
copyModalApi.close();
|
|
||||||
gridApi.reload();
|
|
||||||
} else {
|
|
||||||
Message.error('复制模型失败');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('复制模型失败:', error);
|
|
||||||
Message.error('复制模型失败');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除函数
|
|
||||||
async function onDel(record: any) {
|
async function onDel(record: any) {
|
||||||
try {
|
try {
|
||||||
const resp = await postIoTplatformThingModelInfoDeleteAsync({
|
const resp = await postDeviceThingModelManagementDeleteAsync({
|
||||||
query: {
|
body: { id: record.id },
|
||||||
input: { id: record.id },
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
if (resp.data) {
|
if (resp.data) {
|
||||||
Message.success($t('common.deleteSuccess'));
|
Message.success($t('common.deleteSuccess'));
|
||||||
@ -333,49 +260,18 @@ async function onDel(record: any) {
|
|||||||
Message.error($t('common.deleteFail'));
|
Message.error($t('common.deleteFail'));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('删除失败:', error);
|
console.error('删除设备端物模型失败:', error);
|
||||||
Message.error($t('common.deleteFail'));
|
Message.error($t('common.deleteFail'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 复制标准模型函数
|
|
||||||
async function copyStandardThingModel() {
|
|
||||||
try {
|
|
||||||
const resp = await postIoTplatformThingModelInfoCopyStandardThingModel({
|
|
||||||
query: {
|
|
||||||
input: {
|
|
||||||
ioTPlatform: Number.parseInt(props.ioTPlatform) as 1 | 2,
|
|
||||||
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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal :open="visible" :title="`${props.ioTPlatform === 1 ? 'CTWing' : 'OneNET'}物模型管理 - ${productName || '产品'}`"
|
<Page auto-content-height>
|
||||||
width="90%" :footer="null" @cancel="closeModal" @ok="closeModal"
|
<Grid>
|
||||||
:body-style="{ height: '70vh', overflow: 'hidden' }">
|
|
||||||
<div style="display: flex; flex-direction: column; height: 100%">
|
|
||||||
<Grid style="flex: 1; overflow: hidden">
|
|
||||||
<template #toolbar-actions>
|
<template #toolbar-actions>
|
||||||
<TableAction :actions="[
|
<TableAction
|
||||||
|
:actions="[
|
||||||
{
|
{
|
||||||
label: $t('common.add'),
|
label: $t('common.add'),
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
@ -383,35 +279,26 @@ function closeModal() {
|
|||||||
onClick: openAddModal.bind(null),
|
onClick: openAddModal.bind(null),
|
||||||
auth: ['AbpIdentity.Users.Create'],
|
auth: ['AbpIdentity.Users.Create'],
|
||||||
},
|
},
|
||||||
{
|
]"
|
||||||
label: $t('abp.thingModelInfos.copyStandardThingModel'),
|
/>
|
||||||
type: 'default',
|
|
||||||
icon: 'ant-design:copy-outlined',
|
|
||||||
onClick: copyStandardThingModel,
|
|
||||||
auth: ['AbpIdentity.Users.Create'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: $t('abp.thingModelInfos.copyAnotherThingModelModal'),
|
|
||||||
type: 'default',
|
|
||||||
icon: 'ant-design:copy-outlined',
|
|
||||||
onClick: openCopyAnotherThingModelModal,
|
|
||||||
auth: ['AbpIdentity.Users.Create'],
|
|
||||||
ifShow: !hasData,
|
|
||||||
},
|
|
||||||
]" />
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #isValueNeedConvert="{ row }">
|
<!-- 解析启用列 -->
|
||||||
<component :is="h(
|
<template #functionAnalysisFlag="{ row }">
|
||||||
|
<component
|
||||||
|
:is="
|
||||||
|
h(
|
||||||
Tag,
|
Tag,
|
||||||
{ color: row.isValueNeedConvert ? 'blue' : 'default' },
|
{ color: row.functionAnalysisFlag ? 'green' : 'red' },
|
||||||
() => (row.isValueNeedConvert ? '是' : '否'),
|
() => (row.functionAnalysisFlag ? '是' : '否'),
|
||||||
)
|
)
|
||||||
" />
|
"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #action="{ row }">
|
<template #action="{ row }">
|
||||||
<TableAction :actions="[
|
<TableAction
|
||||||
|
:actions="[
|
||||||
{
|
{
|
||||||
label: $t('common.edit'),
|
label: $t('common.edit'),
|
||||||
type: 'link',
|
type: 'link',
|
||||||
@ -430,17 +317,18 @@ function closeModal() {
|
|||||||
confirm: onDel.bind(null, row),
|
confirm: onDel.bind(null, row),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]" />
|
]"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</Grid>
|
</Grid>
|
||||||
</div>
|
|
||||||
<ThingModelModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
|
<ThingModelModal
|
||||||
|
:title="editRow.id ? $t('common.edit') : $t('common.add')"
|
||||||
|
class="w-[800px]"
|
||||||
|
>
|
||||||
<component :is="editRow.id ? EditForm : AddForm" />
|
<component :is="editRow.id ? EditForm : AddForm" />
|
||||||
</ThingModelModal>
|
</ThingModelModal>
|
||||||
|
</Page>
|
||||||
<!-- 复制已有模型模态框 -->
|
|
||||||
<CopyModal title="复制已有模型" class="w-[600px]">
|
|
||||||
<CopyForm />
|
|
||||||
</CopyModal>
|
|
||||||
</Modal>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,11 +6,95 @@ import dayjs from 'dayjs';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
getCommonGetSelectList,
|
getCommonGetSelectList,
|
||||||
postOneNetProductListAsync,
|
postAggregationIoTplatformGetIoTplatformProductInfoAsync,
|
||||||
} from '#/api-client';
|
} from '#/api-client';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
|
// 查询表单配置
|
||||||
export const querySchema = computed(() => [
|
export const querySchema = computed(() => [
|
||||||
|
{
|
||||||
|
component: 'ApiSelect',
|
||||||
|
fieldName: 'ioTPlatform',
|
||||||
|
label: $t('abp.deviceInfos.ioTPlatform'),
|
||||||
|
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'),
|
||||||
|
dependencies: {
|
||||||
|
show(values: any) {
|
||||||
|
return !!values.ioTPlatform;
|
||||||
|
},
|
||||||
|
triggerFields: ['ioTPlatform'],
|
||||||
|
},
|
||||||
|
componentProps: (formValues: any) => {
|
||||||
|
const platform = formValues?.ioTPlatform;
|
||||||
|
|
||||||
|
return {
|
||||||
|
api: platform
|
||||||
|
? postAggregationIoTplatformGetIoTplatformProductInfoAsync
|
||||||
|
: null,
|
||||||
|
// 聚合服务要求 JSON Body 传参
|
||||||
|
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 [];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
fieldName: 'SearchKeyWords',
|
fieldName: 'SearchKeyWords',
|
||||||
@ -18,64 +102,55 @@ export const querySchema = computed(() => [
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// 列表列配置
|
||||||
export const tableSchema = computed(() => [
|
export const tableSchema = computed(() => [
|
||||||
{
|
{
|
||||||
field: 'filedType',
|
field: 'deviceModelName',
|
||||||
title: $t('abp.thingModelInfos.FiledType'),
|
title: '设备端物模型名称',
|
||||||
|
minWidth: 180,
|
||||||
|
showOverflow: 'tooltip',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'ioTPlatform',
|
||||||
|
title: $t('abp.deviceInfos.ioTPlatform'),
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
showOverflow: 'tooltip',
|
showOverflow: 'tooltip',
|
||||||
formatter: ({ cellValue }: { cellValue: any }) => {
|
formatter: ({ cellValue }: { cellValue: any }) => {
|
||||||
const typeMap: Record<string, string> = {
|
const map: Record<string | number, string> = {
|
||||||
Property: '属性',
|
1: 'CTWing',
|
||||||
Service: '服务',
|
2: 'OneNET',
|
||||||
Event: '事件',
|
|
||||||
};
|
};
|
||||||
return typeMap[cellValue] || cellValue;
|
return map[cellValue] || cellValue || '-';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'ioTPlatformRawFieldName',
|
field: 'ioTPlatformProductId',
|
||||||
title: $t('abp.thingModelInfos.IoTPlatformRawFieldName'),
|
title: '平台产品ID',
|
||||||
minWidth: 150,
|
minWidth: 160,
|
||||||
showOverflow: 'tooltip',
|
showOverflow: 'tooltip',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'standardFieldName',
|
field: 'scriptName',
|
||||||
title: $t('abp.thingModelInfos.StandardFieldName'),
|
title: '脚本函数名称',
|
||||||
minWidth: 150,
|
minWidth: 160,
|
||||||
showOverflow: 'tooltip',
|
showOverflow: 'tooltip',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'standardFieldDisplayName',
|
field: 'parsingSequence',
|
||||||
title: $t('abp.thingModelInfos.StandardFieldDisplayName'),
|
title: '解析顺序',
|
||||||
minWidth: 150,
|
|
||||||
showOverflow: 'tooltip',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'standardFieldValueType',
|
|
||||||
title: $t('abp.thingModelInfos.StandardFieldValueType'),
|
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
showOverflow: 'tooltip',
|
showOverflow: 'tooltip',
|
||||||
formatter: ({ cellValue }: { cellValue: any }) => {
|
formatter: ({ cellValue }: { cellValue: any }) => {
|
||||||
const typeMap: Record<string, string> = {
|
if (cellValue === 1) return '正序';
|
||||||
String: '字符串',
|
if (cellValue === 2) return '高低位反转';
|
||||||
Int32: '整数',
|
return cellValue ?? '-';
|
||||||
Int64: '长整数',
|
|
||||||
Float: '浮点数',
|
|
||||||
Double: '双精度',
|
|
||||||
Boolean: '布尔值',
|
|
||||||
DateTime: '日期时间',
|
|
||||||
Object: 'JSON对象',
|
|
||||||
Array: '数组',
|
|
||||||
};
|
|
||||||
return typeMap[cellValue] || cellValue;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'isValueNeedConvert',
|
field: 'functionAnalysisFlag',
|
||||||
title: $t('abp.thingModelInfos.IsValueNeedConvert'),
|
title: '解析启用',
|
||||||
minWidth: 120,
|
minWidth: 100,
|
||||||
slots: { default: 'isValueNeedConvert' },
|
slots: { default: 'functionAnalysisFlag' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'creationTime',
|
field: 'creationTime',
|
||||||
@ -94,21 +169,29 @@ export const tableSchema = computed(() => [
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 添加物模型表单schema
|
// 新增设备端物模型表单
|
||||||
export const addThingModelFormSchema = computed(() => [
|
export const addDeviceThingModelFormSchema = computed(() => [
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'deviceModelName',
|
||||||
|
label: '设备端物模型名称',
|
||||||
|
rules: z
|
||||||
|
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: $t('common.pleaseInput') + '设备端物模型名称',
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
component: 'ApiSelect',
|
component: 'ApiSelect',
|
||||||
fieldName: 'filedType',
|
fieldName: 'ioTPlatform',
|
||||||
label: $t('abp.thingModelInfos.FiledType'),
|
label: $t('abp.deviceInfos.ioTPlatform'),
|
||||||
rules: z.preprocess(
|
rules: z
|
||||||
(v) => (v == null ? '' : v),
|
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
||||||
z.string().min(1, $t('common.required')),
|
|
||||||
),
|
|
||||||
componentProps: {
|
componentProps: {
|
||||||
api: getCommonGetSelectList,
|
api: getCommonGetSelectList,
|
||||||
params: {
|
params: {
|
||||||
query: {
|
query: {
|
||||||
typeName: 'DataDictionaryTypeConst',
|
typeName: 'IoTPlatformTypeEnum',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
labelField: 'value',
|
labelField: 'value',
|
||||||
@ -117,9 +200,8 @@ export const addThingModelFormSchema = computed(() => [
|
|||||||
immediate: true,
|
immediate: true,
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
placeholder:
|
placeholder:
|
||||||
$t('common.pleaseSelect') + $t('abp.thingModelInfos.FiledType'),
|
$t('common.pleaseSelect') + $t('abp.deviceInfos.ioTPlatform'),
|
||||||
afterFetch: (res: any) => {
|
afterFetch: (res: any) => {
|
||||||
// 确保返回的是数组格式
|
|
||||||
if (Array.isArray(res)) {
|
if (Array.isArray(res)) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -133,270 +215,35 @@ export const addThingModelFormSchema = computed(() => [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
component: 'Input',
|
|
||||||
fieldName: 'ioTPlatformRawFieldName',
|
|
||||||
label: $t('abp.thingModelInfos.IoTPlatformRawFieldName'),
|
|
||||||
rules: z.preprocess(
|
|
||||||
(v) => (v == null ? '' : v),
|
|
||||||
z.string().min(1, $t('common.required')),
|
|
||||||
),
|
|
||||||
componentProps: {
|
|
||||||
placeholder:
|
|
||||||
$t('common.pleaseInput') +
|
|
||||||
$t('abp.thingModelInfos.IoTPlatformRawFieldName'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'StandardThingModelCodeSelect',
|
|
||||||
fieldName: 'standardFieldDisplayName',
|
|
||||||
label: $t('abp.thingModelInfos.StandardFieldDisplayName'),
|
|
||||||
rules: z.preprocess(
|
|
||||||
(v) => (v == null ? '' : v),
|
|
||||||
z.string().min(1, $t('common.required')),
|
|
||||||
),
|
|
||||||
componentProps: (formValues: any) => ({
|
|
||||||
// 传入联动的类型编码(运行时具体值)
|
|
||||||
typeCode: formValues?.filedType ?? null,
|
|
||||||
onResolve: (item: any | null) => {
|
|
||||||
// 选择后自动回填:名称=displayText,值类型=extendedAttribute(转大写)
|
|
||||||
formValues.standardFieldDisplayName = item?.displayText ?? '';
|
|
||||||
formValues.standardFieldName = item?.code ?? '';
|
|
||||||
formValues.standardFieldValueType = (item?.extendedAttribute ?? '')
|
|
||||||
.toString()
|
|
||||||
.toUpperCase();
|
|
||||||
},
|
|
||||||
placeholder:
|
|
||||||
$t('common.pleaseSelect') + $t('abp.thingModelInfos.StandardFieldName'),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'Input',
|
|
||||||
fieldName: 'standardFieldName',
|
|
||||||
label: $t('abp.thingModelInfos.StandardFieldName'),
|
|
||||||
rules: z.preprocess(
|
|
||||||
(v) => (v == null ? '' : v),
|
|
||||||
z.string().min(1, $t('common.required')),
|
|
||||||
),
|
|
||||||
componentProps: {
|
|
||||||
placeholder:
|
|
||||||
$t('common.pleaseInput') +
|
|
||||||
$t('abp.thingModelInfos.StandardFieldDisplayName'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'ApiSelect',
|
|
||||||
fieldName: 'standardFieldValueType',
|
|
||||||
label: $t('abp.thingModelInfos.StandardFieldValueType'),
|
|
||||||
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') +
|
|
||||||
$t('abp.thingModelInfos.StandardFieldValueType'),
|
|
||||||
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: 'Switch',
|
|
||||||
fieldName: 'isValueNeedConvert',
|
|
||||||
label: $t('abp.thingModelInfos.IsValueNeedConvert'),
|
|
||||||
defaultValue: false,
|
|
||||||
componentProps: {
|
|
||||||
style: { width: 'auto' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 编辑物模型表单schema
|
|
||||||
export const editThingModelFormSchema = computed(() => [
|
|
||||||
{
|
|
||||||
component: 'ApiSelect',
|
|
||||||
fieldName: 'filedType',
|
|
||||||
label: $t('abp.thingModelInfos.FiledType'),
|
|
||||||
rules: z.preprocess(
|
|
||||||
(v) => (v == null ? '' : v),
|
|
||||||
z.string().min(1, $t('common.required')),
|
|
||||||
),
|
|
||||||
componentProps: {
|
|
||||||
api: getCommonGetSelectList,
|
|
||||||
params: {
|
|
||||||
query: {
|
|
||||||
typeName: 'DataDictionaryTypeConst',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
labelField: 'value',
|
|
||||||
valueField: 'key',
|
|
||||||
optionsPropName: 'options',
|
|
||||||
immediate: true,
|
|
||||||
disabled: true, // 编辑时禁用
|
|
||||||
placeholder:
|
|
||||||
$t('common.pleaseSelect') + $t('abp.thingModelInfos.FiledType'),
|
|
||||||
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: $t('abp.thingModelInfos.IoTPlatformRawFieldName'),
|
|
||||||
rules: z.preprocess(
|
|
||||||
(v) => (v == null ? '' : v),
|
|
||||||
z.string().min(1, $t('common.required')),
|
|
||||||
),
|
|
||||||
componentProps: {
|
|
||||||
// disabled: true, // 编辑时禁用
|
|
||||||
placeholder:
|
|
||||||
$t('common.pleaseInput') +
|
|
||||||
$t('abp.thingModelInfos.IoTPlatformRawFieldName'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'StandardThingModelCodeSelect',
|
|
||||||
fieldName: 'standardFieldDisplayName',
|
|
||||||
label: $t('abp.thingModelInfos.StandardFieldDisplayName'),
|
|
||||||
rules: z.preprocess(
|
|
||||||
(v) => (v == null ? '' : v),
|
|
||||||
z.string().min(1, $t('common.required')),
|
|
||||||
),
|
|
||||||
componentProps: (formValues: any) => ({
|
|
||||||
typeCode: formValues?.filedType ?? null,
|
|
||||||
disabled: true, // 编辑时禁用
|
|
||||||
onResolve: (item: any | null) => {
|
|
||||||
formValues.standardFieldDisplayName = item?.displayText ?? '';
|
|
||||||
formValues.standardFieldValueType = (item?.extendedAttribute ?? '')
|
|
||||||
.toString()
|
|
||||||
.toUpperCase();
|
|
||||||
},
|
|
||||||
placeholder:
|
|
||||||
$t('common.pleaseInput') +
|
|
||||||
$t('abp.thingModelInfos.StandardFieldDisplayName'),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'Input',
|
|
||||||
fieldName: 'standardFieldName',
|
|
||||||
label: $t('abp.thingModelInfos.StandardFieldName'),
|
|
||||||
rules: z.string().min(1, $t('common.required')),
|
|
||||||
componentProps: {
|
|
||||||
disabled: true, // 编辑时禁用
|
|
||||||
placeholder:
|
|
||||||
$t('common.pleaseSelect') + $t('abp.thingModelInfos.StandardFieldName'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'ApiSelect',
|
|
||||||
fieldName: 'standardFieldValueType',
|
|
||||||
label: $t('abp.thingModelInfos.StandardFieldValueType'),
|
|
||||||
rules: z.preprocess(
|
|
||||||
(v) => (v == null ? '' : v),
|
|
||||||
z.string().min(1, $t('common.required')),
|
|
||||||
),
|
|
||||||
componentProps: {
|
|
||||||
api: getCommonGetSelectList,
|
|
||||||
params: {
|
|
||||||
query: {
|
|
||||||
typeName: 'StandardThingModelDataTypeEnum',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
optionsPropName: 'options',
|
|
||||||
immediate: true,
|
|
||||||
allowClear: true,
|
|
||||||
disabled: true, // 编辑时禁用
|
|
||||||
placeholder:
|
|
||||||
$t('common.pleaseSelect') +
|
|
||||||
$t('abp.thingModelInfos.StandardFieldValueType'),
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
// 转换选项值以匹配列表中的小写值
|
|
||||||
return items.map((item: any) => ({
|
|
||||||
...item,
|
|
||||||
// 使用secondValue的小写版本作为value,保持label为原始value
|
|
||||||
value: item.secondValue || item.value,
|
|
||||||
label: item.value, // 显示文本
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'Switch',
|
|
||||||
fieldName: 'isValueNeedConvert',
|
|
||||||
label: $t('abp.thingModelInfos.IsValueNeedConvert'),
|
|
||||||
componentProps: {
|
|
||||||
style: { width: 'auto' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 复制已有模型表单schema
|
|
||||||
export const copyThingModelFormSchema = computed(() => [
|
|
||||||
{
|
{
|
||||||
component: 'ApiSelect',
|
component: 'ApiSelect',
|
||||||
fieldName: 'ioTPlatformProductId',
|
fieldName: 'ioTPlatformProductId',
|
||||||
label: '选择要复制的产品',
|
label: $t('common.BelongingProductName'),
|
||||||
rules: z.preprocess(
|
rules: z
|
||||||
(v) => (v == null ? '' : v),
|
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
||||||
z.string().min(1, '请选择要复制的产品'),
|
componentProps: (formValues: any) => {
|
||||||
),
|
const platform = formValues?.ioTPlatform;
|
||||||
componentProps: {
|
|
||||||
api: postOneNetProductListAsync,
|
return {
|
||||||
|
api: platform
|
||||||
|
? postAggregationIoTplatformGetIoTplatformProductInfoAsync
|
||||||
|
: null,
|
||||||
params: {
|
params: {
|
||||||
query: {
|
body: {
|
||||||
pageIndex: 1,
|
ioTPlatformType:
|
||||||
pageSize: 1000,
|
typeof platform === 'string'
|
||||||
|
? Number.parseInt(platform)
|
||||||
|
: platform,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
labelField: 'productName',
|
labelField: 'productName',
|
||||||
valueField: 'ioTPlatformProductId',
|
valueField: 'ioTPlatformProductId',
|
||||||
optionsPropName: 'options',
|
optionsPropName: 'options',
|
||||||
immediate: true,
|
immediate: false,
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
placeholder: '请选择产品',
|
placeholder:
|
||||||
|
$t('common.pleaseSelect') + $t('common.BelongingProductName'),
|
||||||
afterFetch: (res: any) => {
|
afterFetch: (res: any) => {
|
||||||
// 确保返回的是数组格式
|
|
||||||
if (Array.isArray(res)) {
|
if (Array.isArray(res)) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -406,11 +253,148 @@ export const copyThingModelFormSchema = computed(() => [
|
|||||||
if (res && Array.isArray(res.data)) {
|
if (res && Array.isArray(res.data)) {
|
||||||
return res.data;
|
return res.data;
|
||||||
}
|
}
|
||||||
if (res && Array.isArray(res.data.items)) {
|
if (res && res.data && Array.isArray(res.data.items)) {
|
||||||
return res.data.items;
|
return res.data.items;
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'scriptName',
|
||||||
|
label: '脚本函数名称',
|
||||||
|
rules: z
|
||||||
|
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: $t('common.pleaseInput') + '脚本函数名称',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Textarea',
|
||||||
|
fieldName: 'functionScript',
|
||||||
|
label: '脚本函数体',
|
||||||
|
componentProps: {
|
||||||
|
rows: 6,
|
||||||
|
placeholder: '请输入脚本函数体(用于解析MODBUS设备数据)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 编辑设备端物模型表单
|
||||||
|
export const editDeviceThingModelFormSchema = computed(() => [
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'deviceModelName',
|
||||||
|
label: '设备端物模型名称',
|
||||||
|
rules: z
|
||||||
|
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: $t('common.pleaseInput') + '设备端物模型名称',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
disabled: 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'))),
|
||||||
|
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,
|
||||||
|
disabled: 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 [];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'scriptName',
|
||||||
|
label: '脚本函数名称',
|
||||||
|
rules: z
|
||||||
|
.preprocess((v) => (v == null ? '' : v), z.string().min(1, $t('common.required'))),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: $t('common.pleaseInput') + '脚本函数名称',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Textarea',
|
||||||
|
fieldName: 'functionScript',
|
||||||
|
label: '脚本函数体',
|
||||||
|
componentProps: {
|
||||||
|
rows: 6,
|
||||||
|
placeholder: '请输入脚本函数体(用于解析MODBUS设备数据)',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user