Compare commits
4 Commits
e860a539fa
...
0ffc2a3098
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ffc2a3098 | ||
|
|
eb12d8f38a | ||
|
|
0b96ff4ff7 | ||
|
|
33dd206da0 |
@ -467,11 +467,15 @@ export const BatchCreateDeviceAggregationInputSchema = {
|
||||
export const BindingDeviceThingModelInputSchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
devieDataId: {
|
||||
devieDataIdList: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
description: '设备数据Id',
|
||||
format: 'uuid'
|
||||
},
|
||||
description: '设备数据Id集合',
|
||||
nullable: true
|
||||
},
|
||||
isNeedConfigDevicMdoel: {
|
||||
type: 'boolean',
|
||||
description: '是否需要配置设备模型,默认false'
|
||||
@ -2140,6 +2144,11 @@ export const DeviceManagementInfoDtoSchema = {
|
||||
description: '设备物模型数据Id',
|
||||
format: 'uuid',
|
||||
nullable: true
|
||||
},
|
||||
deviceThingModelName: {
|
||||
type: 'string',
|
||||
description: '设备物模型名称',
|
||||
nullable: true
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
@ -5213,12 +5222,50 @@ export const IoTDBDynamicObjectPagedResultDtoSchema = {
|
||||
additionalProperties: false
|
||||
} as const;
|
||||
|
||||
export const IoTPlatformAccountInfoInputSchema = {
|
||||
required: ['ioTPlatformType'],
|
||||
type: 'object',
|
||||
properties: {
|
||||
ioTPlatformType: {
|
||||
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
|
||||
}
|
||||
},
|
||||
additionalProperties: false,
|
||||
description: '平台账号信息输入'
|
||||
} as const;
|
||||
|
||||
export const IoTPlatformAccountInfoOutputSchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
ioTPlatformType: {
|
||||
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
|
||||
},
|
||||
ioTPlatformAccount: {
|
||||
type: 'string',
|
||||
description: '平台账号',
|
||||
nullable: true
|
||||
},
|
||||
ioTPlatformPhoneNumber: {
|
||||
type: 'string',
|
||||
description: '平台账号手机号',
|
||||
nullable: true
|
||||
}
|
||||
},
|
||||
additionalProperties: false,
|
||||
description: '平台账号信息'
|
||||
} as const;
|
||||
|
||||
export const IoTPlatformProductInfoInputSchema = {
|
||||
required: ['ioTPlatformType'],
|
||||
type: 'object',
|
||||
properties: {
|
||||
ioTPlatformType: {
|
||||
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
|
||||
},
|
||||
ioTPlatformAccount: {
|
||||
type: 'string',
|
||||
description: '平台账号',
|
||||
nullable: true
|
||||
}
|
||||
},
|
||||
additionalProperties: false,
|
||||
@ -6881,6 +6928,11 @@ export const PageDeviceInputSchema = {
|
||||
description: '物联网平台中对应的设备Id或者名称',
|
||||
nullable: true
|
||||
},
|
||||
ioTPlatformProductId: {
|
||||
type: 'string',
|
||||
description: '物联网平台中对应的产品Id',
|
||||
nullable: true
|
||||
},
|
||||
searchKeyword: {
|
||||
type: 'string',
|
||||
description: '搜索关键字',
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -177,9 +177,9 @@ export type BatchCreateDeviceAggregationInput = {
|
||||
*/
|
||||
export type BindingDeviceThingModelInput = {
|
||||
/**
|
||||
* 设备数据Id
|
||||
* 设备数据Id集合
|
||||
*/
|
||||
devieDataId?: string;
|
||||
devieDataIdList?: Array<(string)> | null;
|
||||
/**
|
||||
* 是否需要配置设备模型,默认false
|
||||
*/
|
||||
@ -1183,6 +1183,10 @@ export type DeviceManagementInfoDto = {
|
||||
* 设备物模型数据Id
|
||||
*/
|
||||
deviceThingModelDataId?: (string) | null;
|
||||
/**
|
||||
* 设备物模型名称
|
||||
*/
|
||||
deviceThingModelName?: (string) | null;
|
||||
};
|
||||
|
||||
export type DeviceManagementInfoDtoPagedResultDto = {
|
||||
@ -2596,11 +2600,37 @@ export type IoTDBDynamicObjectPagedResultDto = {
|
||||
totalCount?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* 平台账号信息输入
|
||||
*/
|
||||
export type IoTPlatformAccountInfoInput = {
|
||||
ioTPlatformType: IoTPlatformTypeEnum;
|
||||
};
|
||||
|
||||
/**
|
||||
* 平台账号信息
|
||||
*/
|
||||
export type IoTPlatformAccountInfoOutput = {
|
||||
ioTPlatformType?: IoTPlatformTypeEnum;
|
||||
/**
|
||||
* 平台账号
|
||||
*/
|
||||
ioTPlatformAccount?: (string) | null;
|
||||
/**
|
||||
* 平台账号手机号
|
||||
*/
|
||||
ioTPlatformPhoneNumber?: (string) | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* 产品信息输入
|
||||
*/
|
||||
export type IoTPlatformProductInfoInput = {
|
||||
ioTPlatformType: IoTPlatformTypeEnum;
|
||||
/**
|
||||
* 平台账号
|
||||
*/
|
||||
ioTPlatformAccount?: (string) | null;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -3648,6 +3678,10 @@ export type PageDeviceInput = {
|
||||
* 物联网平台中对应的设备Id或者名称
|
||||
*/
|
||||
ioTPlatformDeviceOpenInfo?: (string) | null;
|
||||
/**
|
||||
* 物联网平台中对应的产品Id
|
||||
*/
|
||||
ioTPlatformProductId?: (string) | null;
|
||||
/**
|
||||
* 搜索关键字
|
||||
*/
|
||||
@ -6301,6 +6335,16 @@ export type PostAggregationIoTplatformGetIoTplatformProductInfoAsyncResponse = (
|
||||
|
||||
export type PostAggregationIoTplatformGetIoTplatformProductInfoAsyncError = unknown;
|
||||
|
||||
export type PostAggregationIoTplatformGetIoTplatformAccountInfoAsyncData = {
|
||||
query?: {
|
||||
input?: IoTPlatformAccountInfoInput;
|
||||
};
|
||||
};
|
||||
|
||||
export type PostAggregationIoTplatformGetIoTplatformAccountInfoAsyncResponse = (Array<IoTPlatformAccountInfoOutput>);
|
||||
|
||||
export type PostAggregationIoTplatformGetIoTplatformAccountInfoAsyncError = unknown;
|
||||
|
||||
export type PostAggregationIoTplatformGetIoTplatformProductPropertyInfoAsyncData = {
|
||||
query?: {
|
||||
input?: IoTPlatformProductPropertyInfoInput;
|
||||
|
||||
@ -216,7 +216,9 @@
|
||||
"LastOnlineTime": "LastOnlineTime",
|
||||
"LastOfflineTime": "LastOfflineTime",
|
||||
"deviceInfoManage": "DeviceInfoManage",
|
||||
"thingModelInfoManage": "ThingModelInfoManage"
|
||||
"thingModelInfoManage": "ThingModelInfoManage",
|
||||
"isNeedConfigDevicMdoel": "IsNeedConfigDevicMdoel",
|
||||
"deviceThingModelName": "ThingModelInfoManage"
|
||||
},
|
||||
"thingModelInfos": {
|
||||
"FiledType": "FiledType",
|
||||
|
||||
@ -209,7 +209,9 @@
|
||||
"LastOnlineTime": "最后在线时间",
|
||||
"LastOfflineTime": "最后离线时间",
|
||||
"deviceInfoManage": "设备管理",
|
||||
"thingModelInfoManage": "物模型管理"
|
||||
"thingModelInfoManage": "物模型管理",
|
||||
"isNeedConfigDevicMdoel": "是否绑定设备模型",
|
||||
"deviceThingModelName": "设备物模型名称"
|
||||
},
|
||||
"thingModelInfos": {
|
||||
"FiledType": "物模型类型",
|
||||
|
||||
@ -52,6 +52,23 @@ const router = useRouter();
|
||||
const route = useRoute();
|
||||
const formOptions: VbenFormProps = {
|
||||
schema: querySchema.value,
|
||||
submitOnChange: false,
|
||||
handleValuesChange: async (values, changedFields) => {
|
||||
// 当产品切换时,触发搜索
|
||||
if (changedFields.includes('ioTPlatformProductId')) {
|
||||
// 延迟一下,确保表单值已更新
|
||||
await nextTick();
|
||||
if (gridApi?.reload && gridApi?.formApi) {
|
||||
try {
|
||||
// 获取最新的表单值并传递给 reload
|
||||
const latestValues = await gridApi.formApi.getValues();
|
||||
await gridApi.reload(latestValues);
|
||||
} catch (error) {
|
||||
console.error('重新加载数据时出错:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
const gridOptions: VxeGridProps<any> = {
|
||||
checkboxConfig: {
|
||||
@ -71,17 +88,101 @@ const gridOptions: VxeGridProps<any> = {
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({ page }, formValues) => {
|
||||
// 总是从表单API获取最新的表单值,确保参数完整(分页、刷新时formValues可能不完整)
|
||||
const currentFormValues = gridApi?.formApi
|
||||
? await gridApi.formApi.getValues()
|
||||
: formValues || {};
|
||||
|
||||
// 优先使用从表单API获取的值(最新的),如果没有则使用传入的formValues
|
||||
const finalFormValues = { ...(formValues || {}), ...currentFormValues };
|
||||
|
||||
const { data } = await postDeviceInfoPage({
|
||||
body: {
|
||||
pageIndex: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
...formValues,
|
||||
...finalFormValues,
|
||||
},
|
||||
});
|
||||
return data;
|
||||
},
|
||||
},
|
||||
},
|
||||
// 监听复选框选择事件
|
||||
onCheckboxChange: ({ row, checked }: any) => {
|
||||
if (!checked) {
|
||||
// 取消选择时不需要验证
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取当前所有已选中的设备
|
||||
let currentSelected: any[] = [];
|
||||
if (gridApi?.grid) {
|
||||
const gridInstance = gridApi.grid as any;
|
||||
if (typeof gridInstance.getCheckboxRecords === 'function') {
|
||||
currentSelected = gridInstance.getCheckboxRecords();
|
||||
} else if (gridInstance.checkboxRecords) {
|
||||
currentSelected = gridInstance.checkboxRecords;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果已经有选中的设备,检查产品ID是否一致
|
||||
if (currentSelected.length > 0) {
|
||||
const firstProductId = currentSelected[0]?.ioTPlatformProductId;
|
||||
const currentProductId = row?.ioTPlatformProductId;
|
||||
|
||||
// 检查产品ID是否一致
|
||||
if (firstProductId && currentProductId && firstProductId !== currentProductId) {
|
||||
// 产品ID不一致,阻止选择并提示
|
||||
Message.warning('只能选择同一种产品的设备进行批量绑定,当前设备的产品与已选设备的产品不一致');
|
||||
|
||||
// 延迟取消选择,确保提示显示
|
||||
setTimeout(() => {
|
||||
if (gridApi?.grid) {
|
||||
const gridInstance = gridApi.grid as any;
|
||||
if (typeof gridInstance.setCheckboxRow === 'function') {
|
||||
gridInstance.setCheckboxRow(row, false);
|
||||
} else if (typeof gridInstance.clearCheckboxRow === 'function') {
|
||||
gridInstance.clearCheckboxRow(row);
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
// 监听全选事件
|
||||
onCheckboxAll: ({ checked, records }: any) => {
|
||||
if (!checked || records.length <= 1) {
|
||||
// 取消全选或只有一条记录时不需要验证
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查所有记录的产品ID是否一致
|
||||
const productIds = records
|
||||
.map((r: any) => r.ioTPlatformProductId)
|
||||
.filter((id: any) => id);
|
||||
|
||||
if (productIds.length > 0) {
|
||||
const uniqueProductIds = [...new Set(productIds)];
|
||||
if (uniqueProductIds.length > 1) {
|
||||
// 产品ID不一致,阻止全选并提示
|
||||
Message.warning('只能选择同一种产品的设备进行批量绑定,当前页面包含多种产品');
|
||||
|
||||
// 延迟取消全选
|
||||
setTimeout(() => {
|
||||
if (gridApi?.grid) {
|
||||
const gridInstance = gridApi.grid as any;
|
||||
if (typeof gridInstance.clearCheckboxAll === 'function') {
|
||||
gridInstance.clearCheckboxAll();
|
||||
} else if (typeof gridInstance.setAllCheckboxRow === 'function') {
|
||||
gridInstance.setAllCheckboxRow(false);
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });
|
||||
@ -104,12 +205,8 @@ watch(
|
||||
}
|
||||
|
||||
if (newQuery.ioTPlatformDeviceOpenInfo) {
|
||||
// 根据平台类型设置对应的产品ID字段
|
||||
if (newQuery.ioTPlatform === '2' || newQuery.ioTPlatform === 2) {
|
||||
filterValues.oneNETProductId = newQuery.ioTPlatformDeviceOpenInfo;
|
||||
} else if (newQuery.ioTPlatform === '1' || newQuery.ioTPlatform === 1) {
|
||||
filterValues.ctWingProductId = newQuery.ioTPlatformDeviceOpenInfo;
|
||||
}
|
||||
// 设置产品ID字段
|
||||
filterValues.ioTPlatformProductId = newQuery.ioTPlatformDeviceOpenInfo;
|
||||
// 同时设置通用字段用于查询
|
||||
filterValues.ioTPlatformDeviceOpenInfo = newQuery.ioTPlatformDeviceOpenInfo;
|
||||
}
|
||||
@ -135,22 +232,14 @@ watch(
|
||||
() => gridApi?.formApi?.getValues,
|
||||
(formValues) => {
|
||||
if (formValues) {
|
||||
const { oneNETProductId, ctWingProductId } = formValues;
|
||||
const { ioTPlatformProductId } = formValues;
|
||||
|
||||
// 如果选择了OneNET产品,设置ioTPlatformDeviceOpenInfo
|
||||
if (oneNETProductId) {
|
||||
console.log('检测到OneNET产品选择变化:', oneNETProductId);
|
||||
gridApi?.formApi?.setFieldValue('ioTPlatformDeviceOpenInfo', oneNETProductId);
|
||||
console.log('已设置ioTPlatformDeviceOpenInfo为:', oneNETProductId);
|
||||
}
|
||||
// 如果选择了CTWing产品,设置ioTPlatformDeviceOpenInfo
|
||||
else if (ctWingProductId) {
|
||||
console.log('检测到CTWing产品选择变化:', ctWingProductId);
|
||||
gridApi?.formApi?.setFieldValue('ioTPlatformDeviceOpenInfo', ctWingProductId);
|
||||
console.log('已设置ioTPlatformDeviceOpenInfo为:', ctWingProductId);
|
||||
}
|
||||
// 如果都没有选择,清空ioTPlatformDeviceOpenInfo
|
||||
else if (!oneNETProductId && !ctWingProductId) {
|
||||
// 如果选择了产品,设置ioTPlatformDeviceOpenInfo
|
||||
if (ioTPlatformProductId) {
|
||||
console.log('检测到产品选择变化:', ioTPlatformProductId);
|
||||
gridApi?.formApi?.setFieldValue('ioTPlatformDeviceOpenInfo', ioTPlatformProductId);
|
||||
console.log('已设置ioTPlatformDeviceOpenInfo为:', ioTPlatformProductId);
|
||||
} else {
|
||||
console.log('清空产品选择');
|
||||
gridApi?.formApi?.setFieldValue('ioTPlatformDeviceOpenInfo', '');
|
||||
}
|
||||
@ -165,7 +254,7 @@ const loadingTip = ref('缓存刷新中...');
|
||||
const commandRow: Record<string, any> = ref({});
|
||||
|
||||
// 绑定设备端物模型相关
|
||||
const bindRow: Record<string, any> = ref({});
|
||||
const bindRows: Array<Record<string, any>> = ref([]);
|
||||
|
||||
// 指令属性-值对列表
|
||||
interface CommandProperty {
|
||||
@ -274,9 +363,18 @@ const [BindModal, bindModalApi] = useVbenModal({
|
||||
draggable: true,
|
||||
onConfirm: submitBindDeviceThingModel,
|
||||
onBeforeClose: () => {
|
||||
bindRow.value = {};
|
||||
bindRows.value = [];
|
||||
return true;
|
||||
},
|
||||
onOpenChange: async (isOpen: boolean) => {
|
||||
if (isOpen) {
|
||||
console.log('绑定弹窗打开,选中的设备:', bindRows.value);
|
||||
await nextTick();
|
||||
// 确保表单值已设置
|
||||
const formValues = await bindFormApi.getValues();
|
||||
console.log('弹窗打开时的表单值:', formValues);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const [AddForm, addFormApi] = useVbenForm({
|
||||
@ -294,6 +392,12 @@ const [AddForm, addFormApi] = useVbenForm({
|
||||
showCollapseButton: false,
|
||||
showDefaultActions: false,
|
||||
wrapperClass: 'grid-cols-2',
|
||||
handleValuesChange: async (values, changedFields) => {
|
||||
// 当账号切换时,清空产品名称字段
|
||||
if (changedFields.includes('ioTPlatformAccountId')) {
|
||||
await addFormApi.setFieldValue('ioTPlatformProductId', undefined);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const [EditForm, editFormApi] = useVbenForm({
|
||||
@ -312,6 +416,12 @@ const [EditForm, editFormApi] = useVbenForm({
|
||||
showCollapseButton: false,
|
||||
showDefaultActions: false,
|
||||
wrapperClass: 'grid-cols-2',
|
||||
handleValuesChange: async (values, changedFields) => {
|
||||
// 当账号切换时,清空产品名称字段
|
||||
if (changedFields.includes('ioTPlatformAccountId')) {
|
||||
await editFormApi.setFieldValue('ioTPlatformProductId', undefined);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const [CommandForm, commandFormApi] = useVbenForm({
|
||||
@ -343,6 +453,36 @@ const [BindForm, bindFormApi] = useVbenForm({
|
||||
showCollapseButton: false,
|
||||
showDefaultActions: false,
|
||||
wrapperClass: 'grid-cols-1',
|
||||
handleValuesChange: async (values, changedFields) => {
|
||||
// 当开关打开时,手动触发设备物模型下拉框的重新加载
|
||||
if (changedFields.includes('isNeedConfigDevicMdoel') && values.isNeedConfigDevicMdoel) {
|
||||
console.log('开关打开,准备触发设备物模型下拉框重新加载');
|
||||
await nextTick();
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
const productId = values._ioTPlatformProductId || values.ioTPlatformProductId;
|
||||
console.log('手动触发下拉框重新加载,产品ID:', productId);
|
||||
if (productId) {
|
||||
const fieldRef = bindFormApi.getFieldComponentRef('deviceThingModelDataId');
|
||||
if (fieldRef && typeof fieldRef.updateParam === 'function') {
|
||||
fieldRef.updateParam({
|
||||
query: {
|
||||
input: {
|
||||
id: String(productId),
|
||||
},
|
||||
},
|
||||
});
|
||||
console.log('已手动触发下拉框重新加载');
|
||||
} else {
|
||||
console.warn('无法获取设备物模型下拉框的引用');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('手动触发下拉框重新加载失败:', error);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const [BatchAddForm, batchAddFormApi] = useVbenForm({
|
||||
@ -362,6 +502,12 @@ const [BatchAddForm, batchAddFormApi] = useVbenForm({
|
||||
wrapperClass: 'grid-cols-2',
|
||||
// 添加响应式监听
|
||||
autoSubmitOnEnter: false,
|
||||
handleValuesChange: async (values, changedFields) => {
|
||||
// 当账号切换时,清空产品名称字段
|
||||
if (changedFields.includes('ioTPlatformAccountId')) {
|
||||
await batchAddFormApi.setFieldValue('ioTPlatformProductId', undefined);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const [BatchAddModal, batchAddModalApi] = useVbenModal({
|
||||
@ -398,36 +544,13 @@ async function submit() {
|
||||
|
||||
const formValues = await formApi.getValues();
|
||||
|
||||
// 根据平台类型处理数据
|
||||
const processedFormValues = { ...formValues };
|
||||
|
||||
if (formValues.ioTPlatform === 2 || formValues.ioTPlatform === '2') {
|
||||
// OneNET平台
|
||||
processedFormValues.ioTPlatformAccountId = formValues.oneNETAccountId;
|
||||
processedFormValues.ioTPlatformProductId = formValues.oneNETProductId;
|
||||
// 清理不需要的字段
|
||||
delete processedFormValues.oneNETAccountId;
|
||||
delete processedFormValues.oneNETProductId;
|
||||
delete processedFormValues.ctWingAccountId;
|
||||
delete processedFormValues.ctWingProductId;
|
||||
} else if (formValues.ioTPlatform === 1 || formValues.ioTPlatform === '1') {
|
||||
// CTWing平台
|
||||
processedFormValues.ioTPlatformAccountId = formValues.ctWingAccountId;
|
||||
processedFormValues.ioTPlatformProductId = formValues.ctWingProductId;
|
||||
// 清理不需要的字段
|
||||
delete processedFormValues.ctWingAccountId;
|
||||
delete processedFormValues.ctWingProductId;
|
||||
delete processedFormValues.oneNETAccountId;
|
||||
delete processedFormValues.oneNETProductId;
|
||||
}
|
||||
|
||||
const fetchParams: any = isEdit
|
||||
? {
|
||||
id: editRow.value.id,
|
||||
...processedFormValues,
|
||||
...formValues,
|
||||
}
|
||||
: {
|
||||
...processedFormValues,
|
||||
...formValues,
|
||||
};
|
||||
|
||||
try {
|
||||
@ -459,7 +582,7 @@ async function onEdit(record: any) {
|
||||
editRow.value = record;
|
||||
userModalApi.open();
|
||||
|
||||
// 根据平台类型设置表单值
|
||||
// 设置表单值
|
||||
const formValues = { ...record };
|
||||
|
||||
// 确保ioTPlatform是字符串格式,因为ApiSelect组件的valueField是'key'
|
||||
@ -467,16 +590,6 @@ async function onEdit(record: any) {
|
||||
formValues.ioTPlatform = String(formValues.ioTPlatform);
|
||||
}
|
||||
|
||||
if (record.ioTPlatform === 2 || record.ioTPlatform === '2') {
|
||||
// OneNET平台
|
||||
formValues.oneNETAccountId = record.ioTPlatformAccountId;
|
||||
formValues.oneNETProductId = record.ioTPlatformProductId;
|
||||
} else if (record.ioTPlatform === 1 || record.ioTPlatform === '1') {
|
||||
// CTWing平台
|
||||
formValues.ctWingAccountId = record.ioTPlatformAccountId;
|
||||
formValues.ctWingProductId = record.ioTPlatformProductId;
|
||||
}
|
||||
|
||||
editFormApi.setValues(formValues);
|
||||
}
|
||||
|
||||
@ -585,17 +698,96 @@ const openCommandModal = (row: Record<string, any>) => {
|
||||
commandModalApi.open();
|
||||
};
|
||||
|
||||
// 打开绑定设备端物模型弹窗
|
||||
const openBindModal = async (row: Record<string, any>) => {
|
||||
bindRow.value = row;
|
||||
// 打开绑定设备端物模型弹窗(支持单个设备或多个设备)
|
||||
const openBindModal = async (rowOrRows?: Record<string, any> | Array<Record<string, any>>) => {
|
||||
// 如果没有传入参数,尝试从表格获取选中的设备
|
||||
let selectedRows: Array<Record<string, any>> = [];
|
||||
|
||||
if (rowOrRows) {
|
||||
// 如果传入的是数组,直接使用
|
||||
if (Array.isArray(rowOrRows)) {
|
||||
selectedRows = rowOrRows;
|
||||
} else {
|
||||
// 如果传入的是单个设备,转为数组
|
||||
selectedRows = [rowOrRows];
|
||||
}
|
||||
} else {
|
||||
// 从表格获取选中的设备
|
||||
try {
|
||||
let checkboxRecords: any[] = [];
|
||||
|
||||
// 尝试通过 grid 获取
|
||||
if (gridApi?.grid) {
|
||||
const gridInstance = gridApi.grid as any;
|
||||
if (typeof gridInstance.getCheckboxRecords === 'function') {
|
||||
checkboxRecords = gridInstance.getCheckboxRecords();
|
||||
} else if (gridInstance.checkboxRecords) {
|
||||
checkboxRecords = gridInstance.checkboxRecords;
|
||||
}
|
||||
}
|
||||
|
||||
// 尝试通过 store 获取
|
||||
if (checkboxRecords.length === 0 && gridApi?.store) {
|
||||
const store = gridApi.store as any;
|
||||
if (store.checkboxRecords) {
|
||||
checkboxRecords = store.checkboxRecords;
|
||||
}
|
||||
}
|
||||
|
||||
selectedRows = checkboxRecords;
|
||||
} catch (error) {
|
||||
console.warn('无法获取表格选中的设备:', error);
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedRows.length === 0) {
|
||||
Message.warning('请先选择要绑定的设备');
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证所有选中的设备必须是同一种产品(批量选择时)
|
||||
if (selectedRows.length > 1) {
|
||||
const productIds = selectedRows
|
||||
.map((row) => row.ioTPlatformProductId)
|
||||
.filter((id) => id); // 过滤掉空值
|
||||
|
||||
if (productIds.length === 0) {
|
||||
Message.error('选中的设备中没有有效的产品ID,无法进行绑定');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查产品ID是否一致
|
||||
const uniqueProductIds = [...new Set(productIds)];
|
||||
if (uniqueProductIds.length > 1) {
|
||||
Message.error(`选中的设备包含 ${uniqueProductIds.length} 种不同的产品,请只选择同一种产品的设备进行批量绑定`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('打开绑定弹窗,选中的设备:', selectedRows);
|
||||
bindRows.value = selectedRows;
|
||||
|
||||
// 获取第一个设备的产品ID(用于下拉框)
|
||||
const firstDevice = selectedRows[0];
|
||||
const productId = firstDevice.ioTPlatformProductId;
|
||||
console.log('设置表单值,产品ID:', productId, '类型:', typeof productId);
|
||||
|
||||
if (!productId) {
|
||||
console.warn('警告:设备行数据中没有 ioTPlatformProductId 字段,请检查表格数据是否包含该字段');
|
||||
}
|
||||
|
||||
bindModalApi.open();
|
||||
// 设置表单初始值(包括供下拉使用的平台产品ID)
|
||||
await nextTick();
|
||||
|
||||
await bindFormApi.setValues({
|
||||
isNeedConfigDevicMdoel: false,
|
||||
deviceThingModelDataId: undefined,
|
||||
_ioTPlatformProductId: row.ioTPlatformProductId,
|
||||
_ioTPlatformProductId: productId ? String(productId) : undefined,
|
||||
});
|
||||
|
||||
const formValues = await bindFormApi.getValues();
|
||||
console.log('表单值设置完成,当前表单值:', formValues);
|
||||
console.log('表单值中的 _ioTPlatformProductId:', formValues._ioTPlatformProductId);
|
||||
};
|
||||
|
||||
// 指令提交逻辑
|
||||
@ -687,27 +879,35 @@ async function submitBindDeviceThingModel() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bindRow.value?.id) {
|
||||
Message.error('设备信息缺失,无法绑定设备端物模型');
|
||||
if (!bindRows.value || bindRows.value.length === 0) {
|
||||
Message.error('请选择要绑定的设备');
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取所有选中设备的ID
|
||||
const deviceIds = bindRows.value
|
||||
.map((row) => row.id)
|
||||
.filter((id) => id); // 过滤掉空值
|
||||
|
||||
if (deviceIds.length === 0) {
|
||||
Message.error('选中的设备中没有有效的设备ID');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
bindModalApi.setState({ loading: true, confirmLoading: true });
|
||||
const result = await postDeviceInfoBindingDeviceThingModel({
|
||||
query: {
|
||||
input: {
|
||||
devieDataId: bindRow.value.id,
|
||||
body: {
|
||||
devieDataIdList: deviceIds,
|
||||
isNeedConfigDevicMdoel: isNeedConfig,
|
||||
deviceThingModelDataId: isNeedConfig ? deviceThingModelDataId : null,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (result) {
|
||||
Message.success('绑定设备端物模型成功');
|
||||
if (result.data) {
|
||||
Message.success(`成功绑定 ${deviceIds.length} 个设备的设备端物模型`);
|
||||
bindModalApi.close();
|
||||
bindRow.value = {};
|
||||
bindRows.value = [];
|
||||
gridApi.reload();
|
||||
} else {
|
||||
Message.error('绑定设备端物模型失败');
|
||||
@ -753,15 +953,11 @@ async function submitBatchAdd() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 根据平台类型处理数据
|
||||
let ioTPlatformProductId = '';
|
||||
if (formValues.ioTPlatform === 2 || formValues.ioTPlatform === '2') {
|
||||
// OneNET平台
|
||||
ioTPlatformProductId = formValues.oneNETProductId;
|
||||
} else if (formValues.ioTPlatform === 1 || formValues.ioTPlatform === '1') {
|
||||
// CTWing平台
|
||||
ioTPlatformProductId = formValues.ctWingProductId;
|
||||
}
|
||||
// 获取产品ID(兼容新旧字段名)
|
||||
const ioTPlatformProductId =
|
||||
formValues.ioTPlatformProductId ||
|
||||
formValues.oneNETProductId ||
|
||||
formValues.ctWingProductId;
|
||||
|
||||
if (!ioTPlatformProductId) {
|
||||
Message.error('请选择产品');
|
||||
@ -951,6 +1147,94 @@ const handleCacheRefresh = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 批量绑定设备端物模型
|
||||
const openBatchBindModal = async () => {
|
||||
// 从表格获取选中的设备
|
||||
try {
|
||||
console.log('gridApi:', gridApi);
|
||||
console.log('gridApi.grid:', gridApi?.grid);
|
||||
|
||||
// 尝试多种方式获取选中的行
|
||||
let checkboxRecords: any[] = [];
|
||||
|
||||
// 方式1:通过 grid 获取
|
||||
if (gridApi?.grid) {
|
||||
console.log('grid 可用,尝试获取选中行');
|
||||
const gridInstance = gridApi.grid as any;
|
||||
|
||||
// 尝试不同的方法名
|
||||
if (typeof gridInstance.getCheckboxRecords === 'function') {
|
||||
checkboxRecords = gridInstance.getCheckboxRecords();
|
||||
console.log('通过 grid.getCheckboxRecords 获取:', checkboxRecords);
|
||||
} else if (typeof gridInstance.getCheckboxReserveRecords === 'function') {
|
||||
checkboxRecords = gridInstance.getCheckboxReserveRecords();
|
||||
console.log('通过 grid.getCheckboxReserveRecords 获取:', checkboxRecords);
|
||||
}
|
||||
|
||||
// 尝试直接访问内部属性
|
||||
if (checkboxRecords.length === 0 && gridInstance.checkboxRecords) {
|
||||
checkboxRecords = gridInstance.checkboxRecords;
|
||||
console.log('通过 grid.checkboxRecords 属性获取:', checkboxRecords);
|
||||
}
|
||||
|
||||
// 尝试通过 store 获取
|
||||
if (checkboxRecords.length === 0 && gridInstance.$store) {
|
||||
const store = gridInstance.$store;
|
||||
if (store.checkboxRecords) {
|
||||
checkboxRecords = store.checkboxRecords;
|
||||
console.log('通过 grid.$store.checkboxRecords 获取:', checkboxRecords);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 方式2:通过 gridApi.store 获取
|
||||
if (checkboxRecords.length === 0 && gridApi?.store) {
|
||||
const store = gridApi.store as any;
|
||||
if (store.checkboxRecords) {
|
||||
checkboxRecords = store.checkboxRecords;
|
||||
console.log('通过 gridApi.store.checkboxRecords 获取:', checkboxRecords);
|
||||
}
|
||||
}
|
||||
|
||||
// 方式3:直接调用 gridApi 的方法
|
||||
if (checkboxRecords.length === 0 && typeof (gridApi as any).getCheckboxRecords === 'function') {
|
||||
checkboxRecords = (gridApi as any).getCheckboxRecords();
|
||||
console.log('通过 gridApi.getCheckboxRecords 获取:', checkboxRecords);
|
||||
}
|
||||
|
||||
console.log('最终获取到的选中设备:', checkboxRecords);
|
||||
console.log('选中设备数量:', checkboxRecords.length);
|
||||
|
||||
if (!checkboxRecords || checkboxRecords.length === 0) {
|
||||
Message.warning('请先在表格中勾选要绑定的设备(点击每行前面的复选框)');
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证所有选中的设备必须是同一种产品
|
||||
const productIds = checkboxRecords
|
||||
.map((row) => row.ioTPlatformProductId)
|
||||
.filter((id) => id); // 过滤掉空值
|
||||
|
||||
if (productIds.length === 0) {
|
||||
Message.error('选中的设备中没有有效的产品ID,无法进行绑定');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查产品ID是否一致
|
||||
const uniqueProductIds = [...new Set(productIds)];
|
||||
if (uniqueProductIds.length > 1) {
|
||||
Message.error(`选中的设备包含 ${uniqueProductIds.length} 种不同的产品,请只选择同一种产品的设备进行批量绑定`);
|
||||
return;
|
||||
}
|
||||
|
||||
await openBindModal(checkboxRecords);
|
||||
} catch (error) {
|
||||
console.error('获取表格选中的设备失败:', error);
|
||||
console.error('错误详情:', error);
|
||||
Message.error('获取表格选中的设备失败,请确保已勾选设备');
|
||||
}
|
||||
};
|
||||
|
||||
// 工具栏按钮配置
|
||||
const toolbarActions = computed(() => [
|
||||
{
|
||||
@ -967,6 +1251,13 @@ const toolbarActions = computed(() => [
|
||||
onClick: openBatchAddModal.bind(null),
|
||||
auth: ['AbpIdentity.Users.Create'],
|
||||
},
|
||||
{
|
||||
label: '批量绑定设备端物模型',
|
||||
type: 'default',
|
||||
icon: 'ant-design:link-outlined',
|
||||
onClick: openBatchBindModal,
|
||||
auth: ['AbpIdentity.Users.Create'],
|
||||
},
|
||||
{
|
||||
label: cacheRefreshLoading.value
|
||||
? $t('common.loading')
|
||||
@ -1161,7 +1452,21 @@ const toolbarActions = computed(() => [
|
||||
</div>
|
||||
</div>
|
||||
</CommandModal>
|
||||
<BindModal title="绑定设备端物模型" class="w-[600px]">
|
||||
<BindModal :title="`绑定设备端物模型${bindRows.length > 0 ? ` (已选择 ${bindRows.length} 个设备)` : ''}`" class="w-[600px]">
|
||||
<div v-if="bindRows.length > 0" class="mb-4 p-3 bg-blue-50 rounded border border-blue-200">
|
||||
<div class="text-sm font-medium text-blue-800 mb-2">
|
||||
已选择 {{ bindRows.length }} 个设备:
|
||||
</div>
|
||||
<div class="text-xs text-blue-600 max-h-32 overflow-y-auto">
|
||||
<div
|
||||
v-for="(row, index) in bindRows"
|
||||
:key="row.id || index"
|
||||
class="mb-1"
|
||||
>
|
||||
{{ index + 1 }}. {{ row.deviceName || row.deviceAddress || row.id }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<BindForm />
|
||||
</BindModal>
|
||||
<BatchAddModal title="批量添加设备" class="w-[800px]">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user