From 0b96ff4ff7b37c75a7659da7bf2c225eda058657 Mon Sep 17 00:00:00 2001 From: ChenYi <296215406@outlook.com> Date: Tue, 23 Dec 2025 09:45:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=B9=E9=87=8F=E7=BB=91=E5=AE=9A=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E7=AB=AF=E7=89=A9=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/api-client/schemas.gen.ts | 10 + apps/web-antd/src/api-client/types.gen.ts | 8 + .../web-antd/src/locales/langs/en-US/abp.json | 4 +- .../web-antd/src/locales/langs/zh-CN/abp.json | 4 +- .../devicemanagement/deviceinfo/index.vue | 196 +++++++++++++++++- .../devicemanagement/deviceinfo/schema.ts | 14 ++ 6 files changed, 229 insertions(+), 7 deletions(-) diff --git a/apps/web-antd/src/api-client/schemas.gen.ts b/apps/web-antd/src/api-client/schemas.gen.ts index 3be9120..e7a4fea 100644 --- a/apps/web-antd/src/api-client/schemas.gen.ts +++ b/apps/web-antd/src/api-client/schemas.gen.ts @@ -2144,6 +2144,11 @@ export const DeviceManagementInfoDtoSchema = { description: '设备物模型数据Id', format: 'uuid', nullable: true + }, + deviceThingModelName: { + type: 'string', + description: '设备物模型名称', + nullable: true } }, additionalProperties: false @@ -6885,6 +6890,11 @@ export const PageDeviceInputSchema = { description: '物联网平台中对应的设备Id或者名称', nullable: true }, + ioTPlatformProductId: { + type: 'string', + description: '物联网平台中对应的产品Id', + nullable: true + }, searchKeyword: { type: 'string', description: '搜索关键字', diff --git a/apps/web-antd/src/api-client/types.gen.ts b/apps/web-antd/src/api-client/types.gen.ts index 41614e8..892f6b7 100644 --- a/apps/web-antd/src/api-client/types.gen.ts +++ b/apps/web-antd/src/api-client/types.gen.ts @@ -1183,6 +1183,10 @@ export type DeviceManagementInfoDto = { * 设备物模型数据Id */ deviceThingModelDataId?: (string) | null; + /** + * 设备物模型名称 + */ + deviceThingModelName?: (string) | null; }; export type DeviceManagementInfoDtoPagedResultDto = { @@ -3648,6 +3652,10 @@ export type PageDeviceInput = { * 物联网平台中对应的设备Id或者名称 */ ioTPlatformDeviceOpenInfo?: (string) | null; + /** + * 物联网平台中对应的产品Id + */ + ioTPlatformProductId?: (string) | null; /** * 搜索关键字 */ diff --git a/apps/web-antd/src/locales/langs/en-US/abp.json b/apps/web-antd/src/locales/langs/en-US/abp.json index 2c82941..8523b9d 100644 --- a/apps/web-antd/src/locales/langs/en-US/abp.json +++ b/apps/web-antd/src/locales/langs/en-US/abp.json @@ -216,7 +216,9 @@ "LastOnlineTime": "LastOnlineTime", "LastOfflineTime": "LastOfflineTime", "deviceInfoManage": "DeviceInfoManage", - "thingModelInfoManage": "ThingModelInfoManage" + "thingModelInfoManage": "ThingModelInfoManage", + "isNeedConfigDevicMdoel": "IsNeedConfigDevicMdoel", + "deviceThingModelName": "ThingModelInfoManage" }, "thingModelInfos": { "FiledType": "FiledType", diff --git a/apps/web-antd/src/locales/langs/zh-CN/abp.json b/apps/web-antd/src/locales/langs/zh-CN/abp.json index ea1dd3e..c1f00dc 100644 --- a/apps/web-antd/src/locales/langs/zh-CN/abp.json +++ b/apps/web-antd/src/locales/langs/zh-CN/abp.json @@ -209,7 +209,9 @@ "LastOnlineTime": "最后在线时间", "LastOfflineTime": "最后离线时间", "deviceInfoManage": "设备管理", - "thingModelInfoManage": "物模型管理" + "thingModelInfoManage": "物模型管理", + "isNeedConfigDevicMdoel": "是否绑定设备模型", + "deviceThingModelName": "设备物模型名称" }, "thingModelInfos": { "FiledType": "物模型类型", diff --git a/apps/web-antd/src/views/devicemanagement/deviceinfo/index.vue b/apps/web-antd/src/views/devicemanagement/deviceinfo/index.vue index 34cf725..958e91d 100644 --- a/apps/web-antd/src/views/devicemanagement/deviceinfo/index.vue +++ b/apps/web-antd/src/views/devicemanagement/deviceinfo/index.vue @@ -82,6 +82,82 @@ const gridOptions: VxeGridProps = { }, }, }, + // 监听复选框选择事件 + 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 }); @@ -640,7 +716,26 @@ const openBindModal = async (rowOrRows?: Record | Array | Array 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; @@ -1043,15 +1157,87 @@ const handleCacheRefresh = async () => { const openBatchBindModal = async () => { // 从表格获取选中的设备 try { - const checkboxRecords = gridApi?.getCheckboxRecords?.() || []; - if (checkboxRecords.length === 0) { - Message.warning('请先在表格中选择要绑定的设备'); + 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); - Message.error('获取表格选中的设备失败'); + console.error('错误详情:', error); + Message.error('获取表格选中的设备失败,请确保已勾选设备'); } }; diff --git a/apps/web-antd/src/views/devicemanagement/deviceinfo/schema.ts b/apps/web-antd/src/views/devicemanagement/deviceinfo/schema.ts index 4a99d66..e8cd85e 100644 --- a/apps/web-antd/src/views/devicemanagement/deviceinfo/schema.ts +++ b/apps/web-antd/src/views/devicemanagement/deviceinfo/schema.ts @@ -173,6 +173,7 @@ export const querySchema = computed(() => [ export const tableSchema: any = computed((): VxeGridProps['columns'] => [ { title: $t('common.seq'), type: 'seq', width: 50 }, + { title: '', type: 'checkbox', width: 50 }, { field: 'ioTPlatformName', title: $t('common.BelongingIoTPlatform'), @@ -225,6 +226,19 @@ export const tableSchema: any = computed((): VxeGridProps['columns'] => [ return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : ''; }, }, + { + field: 'isNeedConfigDevicMdoel', + title: $t('abp.deviceInfos.isNeedConfigDevicMdoel'), + minWidth: '150', + formatter: ({ cellValue }) => { + return cellValue ? '是' : '否'; + }, + }, + { + field: 'deviceThingModelName', + title: $t('abp.deviceInfos.deviceThingModelName'), + minWidth: '150', + }, { field: 'platformPassword', title: $t('abp.deviceInfos.platformPassword'),