1213 lines
37 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { computed } from 'vue';
import { z } from '@vben/common-ui';
import dayjs from 'dayjs';
import {
getCommonGetSelectList,
postAggregationIoTplatformGetIoTplatformProductInfoAsync,
postAggregationIoTplatformGetIoTplatformProductThingModelInfoAsync,
postOneNetProductListAsync,
} from '#/api-client';
import { $t } from '#/locales';
/** 表格中扩展字段可能为对象或 JSON 字符串,统一展示为字符串 */
function formatFieldExtensionCell(cellValue: unknown): string {
if (cellValue == null || cellValue === '') {
return '';
}
if (typeof cellValue === 'string') {
return cellValue;
}
if (typeof cellValue === 'object') {
try {
return JSON.stringify(cellValue);
} catch {
return String(cellValue);
}
}
return String(cellValue);
}
/** 表单中的扩展字段统一转换为可编辑文本 */
function formatFieldExtensionFormValue(fieldValue: unknown): string {
if (fieldValue == null || fieldValue === '') {
return '';
}
if (typeof fieldValue === 'string') {
return fieldValue;
}
try {
return JSON.stringify(fieldValue, null, 2);
} catch {
return String(fieldValue);
}
}
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,
params: {
body: {
// 聚合服务要求 JSON 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: 'ApiSelect',
fieldName: 'accessMode',
label: $t('abp.thingModelInfos.AccessMode'),
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
typeName: 'DevicePropertyAccessMode',
},
},
labelField: 'value',
valueField: 'key',
optionsPropName: 'options',
immediate: true,
allowClear: true,
placeholder: `${$t('common.pleaseSelect')}${$t('abp.thingModelInfos.AccessMode')}`,
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: 'identifierType',
label: $t('abp.thingModelInfos.IdentifierType'),
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
typeName: 'ThingModelIdentifierTypeEnum',
},
},
labelField: 'value',
valueField: 'key',
optionsPropName: 'options',
immediate: true,
allowClear: true,
placeholder: `${$t('common.pleaseSelect')}${$t('abp.thingModelInfos.IdentifierType')}`,
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: 'SearchKeyWords',
label: $t('common.SearchKeyWords'),
},
]);
export const tableSchema = computed(() => [
{
field: 'ioTPlatformProductId',
title: $t('abp.thingModelInfos.ioTPlatformProduct'),
minWidth: 150,
showOverflow: 'tooltip',
fixed: 'left',
},
{
field: 'filedTypeName',
title: $t('abp.thingModelInfos.FiledType'),
minWidth: 120,
showOverflow: 'tooltip',
formatter: ({ cellValue }: { cellValue: any }) => {
const typeMap: Record<string, string> = {
Property: '属性',
Service: '服务',
Event: '事件',
};
return typeMap[cellValue] || cellValue;
},
},
{
field: 'ioTPlatformRawFieldName',
title: $t('abp.thingModelInfos.IoTPlatformRawFieldName'),
minWidth: 150,
showOverflow: 'tooltip',
},
{
field: 'standardFieldName',
title: $t('abp.thingModelInfos.StandardFieldName'),
minWidth: 150,
showOverflow: 'tooltip',
},
{
field: 'ioTPlatformRawFieldExtension',
title: $t('abp.thingModelInfos.IoTPlatformRawFieldExtension'),
minWidth: 120,
showOverflow: 'tooltip',
formatter: ({ cellValue }: { cellValue: unknown }) =>
formatFieldExtensionCell(cellValue),
},
{
field: 'standardFieldDisplayName',
title: $t('abp.thingModelInfos.StandardFieldDisplayName'),
minWidth: 150,
showOverflow: 'tooltip',
},
{
field: 'standardFieldValueType',
title: $t('abp.thingModelInfos.StandardFieldValueType'),
minWidth: 120,
showOverflow: 'tooltip',
formatter: ({ cellValue }: { cellValue: any }) => {
const typeMap: Record<string, string> = {
String: '字符串',
Int32: '整数',
Int64: '长整数',
Float: '浮点数',
Double: '双精度',
Boolean: '布尔值',
DateTime: '日期时间',
Object: 'JSON对象',
Array: '数组',
Struct: '结构体',
};
return typeMap[cellValue] || cellValue;
},
},
{
field: 'standardFieldFieldExtension',
title: $t('abp.thingModelInfos.StandardFieldFieldExtension'),
minWidth: 120,
showOverflow: 'tooltip',
formatter: ({ cellValue }: { cellValue: unknown }) =>
formatFieldExtensionCell(cellValue),
},
{
field: 'isValueNeedConvert',
title: $t('abp.thingModelInfos.IsValueNeedConvert'),
minWidth: 120,
slots: { default: 'isValueNeedConvert' },
},
{
field: 'accessMode',
title: $t('abp.thingModelInfos.AccessMode'),
minWidth: 120,
slots: { default: 'accessMode' },
},
{
field: 'identifierType',
title: $t('abp.thingModelInfos.IdentifierType'),
minWidth: 120,
showOverflow: 'tooltip',
slots: { default: 'identifierType' },
},
{
field: 'isOperableIdentifier',
title: $t('abp.thingModelInfos.IsOperableIdentifier'),
minWidth: 150,
formatter: ({ cellValue }: { cellValue: any }) => {
return cellValue === true ? '是' : '否';
},
},
{
field: 'creationTime',
title: $t('common.creationTime'),
minWidth: 180,
formatter: ({ cellValue }: { cellValue: any }) => {
return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : '-';
},
},
{
field: 'action',
title: $t('common.action'),
width: 200,
fixed: 'right',
slots: { default: 'action' },
},
]);
// 添加物模型表单schema
export const getAddThingModelFormSchema = (
getPlatform: () => number | string | undefined,
getProductId: () => string | undefined,
) =>
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,
allowClear: 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: '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: '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();
// 选择后自动回填标准物模型扩展参数extendedAttributeValue
formValues.standardFieldFieldExtension = formatFieldExtensionFormValue(
item?.extendedAttributeValue,
);
},
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: 'Textarea',
fieldName: 'standardFieldFieldExtension',
label: $t('abp.thingModelInfos.StandardFieldFieldExtension'),
componentProps: {
rows: 4,
placeholder: '请选择标准物模型后自动回填扩展参数JSON格式',
},
},
{
component: 'ApiSelect',
fieldName: 'ioTPlatformRawFieldName',
label: $t('abp.thingModelInfos.IoTPlatformRawFieldName'),
rules: z.preprocess(
(v) => (v == null ? '' : v),
z.string().min(1, $t('common.required')),
),
dependencies: {
triggerFields: ['_ioTPlatform', '_ioTPlatformProductId', 'filedType'],
trigger: async (_formValues: any, formApi: any) => {
// 当 filedType 变化时,清空字段值,强制组件重新加载
if (formApi && typeof formApi.setFieldValue === 'function') {
await formApi.setFieldValue('ioTPlatformRawFieldName', undefined);
}
},
componentProps: (formValues: any) => {
// 优先从表单值获取(这是最可靠的方式,因为值是在打开弹窗时设置的)
let platform = formValues?._ioTPlatform;
let productId = formValues?._ioTPlatformProductId;
const filedType = formValues?.filedType;
// 如果表单值中没有,尝试从其他字段获取
if (!platform && formValues?.ioTPlatform) {
platform =
typeof formValues.ioTPlatform === 'string'
? Number.parseInt(formValues.ioTPlatform)
: formValues.ioTPlatform;
}
if (!productId && formValues?.ioTPlatformProductId) {
productId = formValues.ioTPlatformProductId;
}
// 如果还是没有,尝试从外部函数获取(作为后备方案)
if (!platform) {
const externalPlatform = getPlatform();
if (externalPlatform) {
platform =
typeof externalPlatform === 'string'
? Number.parseInt(externalPlatform)
: externalPlatform;
}
}
if (!productId) {
const externalProductId = getProductId();
if (externalProductId) {
productId = String(externalProductId);
}
}
// 确保平台类型是数字
if (platform && typeof platform === 'string') {
platform = Number.parseInt(platform);
}
// 调试信息
console.log('平台物模型编码下拉框配置:', {
platform,
productId,
filedType,
hasApi: !!(platform && productId),
fromForm: {
_ioTPlatform: formValues?._ioTPlatform,
_ioTPlatformProductId: formValues?._ioTPlatformProductId,
ioTPlatform: formValues?.ioTPlatform,
ioTPlatformProductId: formValues?.ioTPlatformProductId,
filedType: formValues?.filedType,
},
});
return {
api:
platform && productId
? postAggregationIoTplatformGetIoTplatformProductThingModelInfoAsync
: null,
params:
platform && productId
? {
body: {
ioTPlatformType:
typeof platform === 'string'
? Number.parseInt(platform)
: platform,
ioTPlatformProductId: String(productId),
// 确保 FiledType 参数始终存在(即使为空),以便触发接口重新请求
FiledType: filedType ? String(filedType) : undefined,
},
}
: {},
// 添加 key 确保 filedType 变化时组件重新渲染
key: `platform-${platform}-product-${productId}-type-${filedType || 'none'}`,
labelField: 'value',
valueField: 'key',
optionsPropName: 'options',
immediate: !!(platform && productId), // 当有平台和产品ID时立即加载
allowClear: true,
showSearch: true,
placeholder:
$t('common.pleaseSelect') +
$t('abp.thingModelInfos.IoTPlatformRawFieldName'),
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;
}
// 存储原始数据映射,用于后续查找 secondValue
const optionMap = new Map();
items.forEach((item: any) => {
if (item.key) {
optionMap.set(item.key, item.secondValue);
}
});
(formValues as any)._platformPropertyMap = optionMap;
return items;
},
onChange: (value: string) => {
// 选择后自动设置平台物模型数值类型为选中项的 secondValue
const optionMap = (formValues as any)._platformPropertyMap;
if (optionMap && value) {
let secondValue = optionMap.get(value);
if (secondValue) {
// 兼容 BOOL / BOOLEAN 差异,统一转换为后端 / 枚举使用的 BOOLEAN
if (
typeof secondValue === 'string' &&
secondValue.toUpperCase() === 'BOOL'
) {
secondValue = 'BOOLEAN';
}
formValues.ioTPlatformRawFieldDataType = secondValue;
}
}
},
};
},
},
},
{
component: 'Switch',
fieldName: 'isValueNeedConvert',
label: $t('abp.thingModelInfos.IsValueNeedConvert'),
defaultValue: false,
componentProps: {
style: { width: 'auto' },
},
},
{
component: 'ApiSelect',
fieldName: 'accessMode',
label: $t('abp.thingModelInfos.AccessMode'),
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
typeName: 'DevicePropertyAccessMode',
},
},
labelField: 'value',
valueField: 'key',
optionsPropName: 'options',
immediate: true,
allowClear: true,
placeholder:
$t('common.pleaseSelect') + $t('abp.thingModelInfos.AccessMode'),
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: 'isOperableIdentifier',
label: $t('abp.thingModelInfos.IsOperableIdentifier'),
defaultValue: false,
componentProps: {
style: { width: 'auto' },
},
},
{
component: 'ApiSelect',
fieldName: 'identifierType',
label: $t('abp.thingModelInfos.IdentifierType'),
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
typeName: 'ThingModelIdentifierTypeEnum',
},
},
labelField: 'value',
valueField: 'key',
optionsPropName: 'options',
immediate: true,
allowClear: true,
placeholder:
$t('common.pleaseSelect') + $t('abp.thingModelInfos.IdentifierType'),
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: '平台物模型值类型',
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
typeName: 'StandardThingModelDataTypeEnum',
},
},
labelField: 'value',
valueField: 'secondValue',
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: 'Switch',
fieldName: 'isSpecialIdentifier',
label: '是否特殊物模型标识符',
defaultValue: false,
componentProps: {
style: { width: 'auto' },
},
},
{
component: 'Textarea',
fieldName: 'ioTPlatformRawFieldExtension',
label: '平台物模型值类型扩展',
componentProps: {
rows: 4,
placeholder:
'请输入平台原始字段扩展信息用于扩展结构体类型JSON格式',
},
},
]);
// 编辑物模型表单schema
export const getEditThingModelFormSchema = (
getPlatform: () => number | string | undefined,
getProductId: () => string | undefined,
) =>
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: '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: '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: 'ioTPlatformRawFieldName',
label: $t('abp.thingModelInfos.IoTPlatformRawFieldName'),
rules: z.preprocess(
(v) => (v == null ? '' : v),
z.string().min(1, $t('common.required')),
),
dependencies: {
triggerFields: ['_ioTPlatform', '_ioTPlatformProductId', 'filedType'],
trigger: async (_formValues: any, formApi: any) => {
// 当 filedType 变化时,清空字段值,强制组件重新加载
if (formApi && typeof formApi.setFieldValue === 'function') {
await formApi.setFieldValue('ioTPlatformRawFieldName', undefined);
}
},
componentProps: (formValues: any) => {
// 优先从表单值获取(这是最可靠的方式,因为值是在打开弹窗时设置的)
let platform = formValues?._ioTPlatform;
let productId = formValues?._ioTPlatformProductId;
const filedType = formValues?.filedType;
// 如果表单值中没有,尝试从其他字段获取
if (!platform && formValues?.ioTPlatform) {
platform =
typeof formValues.ioTPlatform === 'string'
? Number.parseInt(formValues.ioTPlatform)
: formValues.ioTPlatform;
}
if (!productId && formValues?.ioTPlatformProductId) {
productId = formValues.ioTPlatformProductId;
}
// 如果还是没有,尝试从外部函数获取(作为后备方案)
if (!platform) {
const externalPlatform = getPlatform();
if (externalPlatform) {
platform =
typeof externalPlatform === 'string'
? Number.parseInt(externalPlatform)
: externalPlatform;
}
}
if (!productId) {
const externalProductId = getProductId();
if (externalProductId) {
productId = String(externalProductId);
}
}
// 确保平台类型是数字
if (platform && typeof platform === 'string') {
platform = Number.parseInt(platform);
}
// 调试信息
console.log('平台物模型编码下拉框配置:', {
platform,
productId,
filedType,
hasApi: !!(platform && productId),
fromForm: {
_ioTPlatform: formValues?._ioTPlatform,
_ioTPlatformProductId: formValues?._ioTPlatformProductId,
ioTPlatform: formValues?.ioTPlatform,
ioTPlatformProductId: formValues?.ioTPlatformProductId,
filedType: formValues?.filedType,
},
});
return {
api:
platform && productId
? postAggregationIoTplatformGetIoTplatformProductThingModelInfoAsync
: null,
params:
platform && productId
? {
body: {
ioTPlatformType:
typeof platform === 'string'
? Number.parseInt(platform)
: platform,
ioTPlatformProductId: String(productId),
// 确保 FiledType 参数始终存在(即使为空),以便触发接口重新请求
FiledType: filedType ? String(filedType) : undefined,
},
}
: {},
// 添加 key 确保 filedType 变化时组件重新渲染
key: `platform-${platform}-product-${productId}-type-${filedType || 'none'}`,
labelField: 'value',
valueField: 'key',
optionsPropName: 'options',
immediate: !!(platform && productId), // 当有平台和产品ID时立即加载
allowClear: true,
showSearch: true,
placeholder:
$t('common.pleaseSelect') +
$t('abp.thingModelInfos.IoTPlatformRawFieldName'),
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;
}
// 存储原始数据映射,用于后续查找 secondValue
const optionMap = new Map();
items.forEach((item: any) => {
if (item.key) {
optionMap.set(item.key, item.secondValue);
}
});
(formValues as any)._platformPropertyMap = optionMap;
return items;
},
onChange: (value: string) => {
// 选择后自动设置平台物模型数值类型为选中项的 secondValue
const optionMap = (formValues as any)._platformPropertyMap;
if (optionMap && value) {
let secondValue = optionMap.get(value);
if (secondValue) {
// 兼容 BOOL / BOOLEAN 差异,统一转换为后端 / 枚举使用的 BOOLEAN
if (
typeof secondValue === 'string' &&
secondValue.toUpperCase() === 'BOOL'
) {
secondValue = 'BOOLEAN';
}
formValues.ioTPlatformRawFieldDataType = secondValue;
}
}
},
};
},
},
},
{
component: 'Switch',
fieldName: 'isValueNeedConvert',
label: $t('abp.thingModelInfos.IsValueNeedConvert'),
componentProps: {
style: { width: 'auto' },
},
},
{
component: 'ApiSelect',
fieldName: 'accessMode',
label: $t('abp.thingModelInfos.AccessMode'),
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
typeName: 'DevicePropertyAccessMode',
},
},
labelField: 'value',
valueField: 'key',
optionsPropName: 'options',
immediate: true,
allowClear: true,
placeholder:
$t('common.pleaseSelect') + $t('abp.thingModelInfos.AccessMode'),
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: 'isOperableIdentifier',
label: $t('abp.thingModelInfos.IsOperableIdentifier'),
componentProps: {
style: { width: 'auto' },
},
},
{
component: 'ApiSelect',
fieldName: 'identifierType',
label: $t('abp.thingModelInfos.IdentifierType'),
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
typeName: 'ThingModelIdentifierTypeEnum',
},
},
labelField: 'value',
valueField: 'key',
optionsPropName: 'options',
immediate: true,
allowClear: true,
placeholder:
$t('common.pleaseSelect') + $t('abp.thingModelInfos.IdentifierType'),
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: '平台物模型值类型',
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
typeName: 'StandardThingModelDataTypeEnum',
},
},
labelField: 'value',
valueField: 'secondValue',
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: 'Switch',
fieldName: 'isSpecialIdentifier',
label: '是否特殊物模型标识符',
componentProps: {
style: { width: 'auto' },
},
},
{
component: 'Textarea',
fieldName: 'ioTPlatformRawFieldExtension',
label: '平台物模型值类型扩展',
componentProps: {
rows: 4,
placeholder:
'请输入平台原始字段扩展信息用于扩展结构体类型JSON格式',
},
},
]);
// 复制已有模型表单schema
export const copyThingModelFormSchema = computed(() => [
{
component: 'ApiSelect',
fieldName: 'ioTPlatformProductId',
label: '选择要复制的产品',
rules: z.preprocess(
(v) => (v == null ? '' : v),
z.string().min(1, '请选择要复制的产品'),
),
componentProps: {
api: postOneNetProductListAsync,
params: {
query: {
pageIndex: 1,
pageSize: 1000,
},
},
labelField: 'productName',
valueField: 'ioTPlatformProductId',
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 && Array.isArray(res.data.items)) {
return res.data.items;
}
return [];
},
},
},
]);
// 复制标准模型(按物模型类型多选)表单 schema
export const copyStandardThingModelFormSchema = computed(() => [
{
component: 'ApiSelect',
fieldName: 'filedTypes',
label: '选择要复制的物模型类型',
rules: z.preprocess(
(v) => (v == null ? [] : v),
z.array(z.string()).min(1, '请至少选择一个物模型类型'),
),
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
// 与物模型字段类型相同的数据字典Property / Service / Event
typeName: 'DataDictionaryTypeConst',
},
},
labelField: 'value',
valueField: 'key',
optionsPropName: 'options',
immediate: true,
allowClear: true,
mode: 'multiple',
placeholder: '请选择要复制的物模型类型(可多选)',
maxTagCount: 'responsive',
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 [];
},
},
},
]);