diff --git a/apps/web-antd/src/api-client/schemas.gen.ts b/apps/web-antd/src/api-client/schemas.gen.ts index 9366c7b..3be9120 100644 --- a/apps/web-antd/src/api-client/schemas.gen.ts +++ b/apps/web-antd/src/api-client/schemas.gen.ts @@ -467,10 +467,14 @@ export const BatchCreateDeviceAggregationInputSchema = { export const BindingDeviceThingModelInputSchema = { type: 'object', properties: { - devieDataId: { - type: 'string', - description: '设备数据Id', - format: 'uuid' + devieDataIdList: { + type: 'array', + items: { + type: 'string', + format: 'uuid' + }, + description: '设备数据Id集合', + nullable: true }, isNeedConfigDevicMdoel: { type: 'boolean', diff --git a/apps/web-antd/src/api-client/types.gen.ts b/apps/web-antd/src/api-client/types.gen.ts index 0b8eed8..41614e8 100644 --- a/apps/web-antd/src/api-client/types.gen.ts +++ b/apps/web-antd/src/api-client/types.gen.ts @@ -177,9 +177,9 @@ export type BatchCreateDeviceAggregationInput = { */ export type BindingDeviceThingModelInput = { /** - * 设备数据Id + * 设备数据Id集合 */ - devieDataId?: string; + devieDataIdList?: Array<(string)> | null; /** * 是否需要配置设备模型,默认false */ diff --git a/apps/web-antd/src/views/devicemanagement/deviceinfo/index.vue b/apps/web-antd/src/views/devicemanagement/deviceinfo/index.vue index 0283641..34cf725 100644 --- a/apps/web-antd/src/views/devicemanagement/deviceinfo/index.vue +++ b/apps/web-antd/src/views/devicemanagement/deviceinfo/index.vue @@ -165,7 +165,7 @@ const loadingTip = ref('缓存刷新中...'); const commandRow: Record = ref({}); // 绑定设备端物模型相关 -const bindRow: Record = ref({}); +const bindRows: Array> = ref([]); // 指令属性-值对列表 interface CommandProperty { @@ -274,9 +274,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({ @@ -343,6 +352,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({ @@ -585,17 +624,58 @@ const openCommandModal = (row: Record) => { commandModalApi.open(); }; -// 打开绑定设备端物模型弹窗 -const openBindModal = async (row: Record) => { - bindRow.value = row; +// 打开绑定设备端物模型弹窗(支持单个设备或多个设备) +const openBindModal = async (rowOrRows?: Record | Array>) => { + // 如果没有传入参数,尝试从表格获取选中的设备 + let selectedRows: Array> = []; + + if (rowOrRows) { + // 如果传入的是数组,直接使用 + if (Array.isArray(rowOrRows)) { + selectedRows = rowOrRows; + } else { + // 如果传入的是单个设备,转为数组 + selectedRows = [rowOrRows]; + } + } else { + // 从表格获取选中的设备 + try { + const checkboxRecords = gridApi?.getCheckboxRecords?.() || []; + selectedRows = checkboxRecords; + } catch (error) { + console.warn('无法获取表格选中的设备:', error); + } + } + + if (selectedRows.length === 0) { + Message.warning('请先选择要绑定的设备'); + 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 +767,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, - isNeedConfigDevicMdoel: isNeedConfig, - deviceThingModelDataId: isNeedConfig ? deviceThingModelDataId : null, - }, + 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('绑定设备端物模型失败'); @@ -951,6 +1039,22 @@ const handleCacheRefresh = async () => { } }; +// 批量绑定设备端物模型 +const openBatchBindModal = async () => { + // 从表格获取选中的设备 + try { + const checkboxRecords = gridApi?.getCheckboxRecords?.() || []; + if (checkboxRecords.length === 0) { + Message.warning('请先在表格中选择要绑定的设备'); + return; + } + await openBindModal(checkboxRecords); + } catch (error) { + console.error('获取表格选中的设备失败:', error); + Message.error('获取表格选中的设备失败'); + } +}; + // 工具栏按钮配置 const toolbarActions = computed(() => [ { @@ -967,6 +1071,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 +1272,21 @@ const toolbarActions = computed(() => [ - + +
+
+ 已选择 {{ bindRows.length }} 个设备: +
+
+
+ {{ index + 1 }}. {{ row.deviceName || row.deviceAddress || row.id }} +
+
+
diff --git a/apps/web-antd/src/views/devicemanagement/deviceinfo/schema.ts b/apps/web-antd/src/views/devicemanagement/deviceinfo/schema.ts index eea7d43..4a99d66 100644 --- a/apps/web-antd/src/views/devicemanagement/deviceinfo/schema.ts +++ b/apps/web-antd/src/views/devicemanagement/deviceinfo/schema.ts @@ -10,7 +10,7 @@ import { getCommonGetSelectList, postCtWingAccountListAsync, postCtWingProductListAsync, - postIoTplatformThingModelInfoFindByPlatformProductIdAsync, + postDeviceThingModelManagementFindByPlatformProductIdAsync, postOneNetAccountListAsync, postOneNetProductListAsync, } from '#/api-client'; @@ -529,6 +529,14 @@ export const addDeviceFormSchema: any = computed(() => [ // 设备绑定设备端物模型表单 export const bindDeviceThingModelFormSchema: any = computed(() => [ + { + component: 'Input', + fieldName: '_ioTPlatformProductId', + label: '', + componentProps: { + type: 'hidden', + }, + }, { component: 'Switch', fieldName: 'isNeedConfigDevicMdoel', @@ -545,7 +553,13 @@ export const bindDeviceThingModelFormSchema: any = computed(() => [ // 仅在需要配置设备模型时显示 dependencies: { show(values: any) { - return !!values.isNeedConfigDevicMdoel; + const shouldShow = !!values.isNeedConfigDevicMdoel; + console.log('设备物模型下拉框显示检查:', { + isNeedConfigDevicMdoel: values.isNeedConfigDevicMdoel, + shouldShow, + _ioTPlatformProductId: values._ioTPlatformProductId, + }); + return shouldShow; }, triggerFields: ['isNeedConfigDevicMdoel', '_ioTPlatformProductId'], }, @@ -554,27 +568,32 @@ export const bindDeviceThingModelFormSchema: any = computed(() => [ const productId = formValues?._ioTPlatformProductId || formValues?.ioTPlatformProductId; - return { + console.log('设备物模型下拉框 componentProps 被调用:', { + formValues, + productId, + isNeedConfigDevicMdoel: formValues?.isNeedConfigDevicMdoel, + }); + + const config = { api: productId - ? postIoTplatformThingModelInfoFindByPlatformProductIdAsync + ? postDeviceThingModelManagementFindByPlatformProductIdAsync : null, params: productId ? { query: { - input: { - id: String(productId), - }, + id: String(productId), }, } : {}, - // 平台物模型信息里的显示字段(优先显示标准字段显示名) - labelField: 'standardFieldDisplayName', + // 设备端物模型信息里的显示字段 + labelField: 'deviceModelName', valueField: 'id', optionsPropName: 'options', immediate: !!productId, allowClear: true, - placeholder: '请选择设备物模型', + placeholder: '请选择设备端物模型', afterFetch: (res: any) => { + console.log('设备物模型下拉框 afterFetch 被调用,响应:', res); // 确保返回数组 if (Array.isArray(res)) { return res; @@ -591,6 +610,9 @@ export const bindDeviceThingModelFormSchema: any = computed(() => [ return []; }, }; + + console.log('设备物模型下拉框配置:', config); + return config; }, // 规则在提交中按开关手动校验,这里设为可选 rules: z.string().optional(),