# 空间批量操作问题修复规格说明书 **文档版本**: v1.0 **创建日期**: 2026-02-23 **文档类型**: Bug修复规格说明书 --- ## 一、问题描述 用户报告了8个问题,需要逐一分析和修复: ### 问题列表 | 序号 | 问题描述 | 状态 | |------|---------|------| | 1 | 批量操作点进去的生成类型不用显示了,隐藏即可 | ✅ 已隐藏 | | 2 | 批量生成房间保存,提示失败 | ⚠️ 需排查 | | 3 | 批量生成车位后缀应为空 | ✅ 已设置 | | 4 | 批量生成车位设置的3位数序号,但生成的是1位数,且自动带上了后缀号车位 | ⚠️ 需排查 | | 5 | 批量操作不再限定必须选中楼栋或车位才能添加对应批量信息 | ⚠️ 需修改 | | 6 | 停车区域的子项里显示的车位列表设置成支持分页,每页20个 | ✅ 已支持 | | 7 | 新增的批量楼栋依然没有生成地址 | ⚠️ 需修改 | | 8 | 项目查看详情,统计数据里,显示总户数8户,但是我增加了12户。面积为空 | ⚠️ 需排查 | --- ## 二、问题分析 ### 2.1 问题1:生成类型隐藏 **文件**: `ether-ui-admin/src/views/mdm/project/components/BatchGenerateModal.vue` **当前状态**: 第21行已使用 `v-show="false"` 隐藏 ```vue ``` **结论**: ✅ 已正确隐藏,无需修改 --- ### 2.2 问题2:批量生成房间保存失败 **相关文件**: - 前端: `BatchGenerateModal.vue` 第451-477行 - 后端: `SpaceNodeServiceImpl.java` 第932-994行 **前端代码分析**: ```typescript const generateRooms = async () => { if (!formState.value.buildingIds || formState.value.buildingIds.length === 0) { throw new Error("请选择所属楼栋"); } // ... 调用 API }; ``` **后端代码分析**: ```java public List batchGenerateRooms(BatchGenerateRoomsRequest request) { // 检查楼栋是否存在 SpaceNode building = spaceNodeRepository.findById(buildingId) .orElseThrow(() -> new BusinessException("楼栋不存在: " + buildingId)); // ... } ``` **可能原因**: 1. 前端传递的 `buildingIds` 可能是空数组 2. 后端 `findById` 可能找不到楼栋(项目隔离问题) 3. 编码冲突导致失败 **需要检查**: - API 路径是否正确 - 项目上下文是否正确传递 - 后端日志输出 --- ### 2.3 问题3:车位后缀应为空 **前端代码**: `BatchGenerateModal.vue` 第490行 ```typescript await spaceNodeApi.batchGenerateParkingSpaces({ // ... suffix: "", // ✅ 已设置为空字符串 }); ``` **结论**: ✅ 已正确设置,无需修改 --- ### 2.4 问题4:车位序号位数和名称问题 **后端代码**: `SpaceNodeServiceImpl.java` 第1057-1070行 ```java int digitCount = request.getDigitCount() != null ? request.getDigitCount() : 3; for (int i = 0; i < request.getCount(); i++) { int number = request.getStartNumber() + i; String code = (request.getPrefix() != null ? request.getPrefix() : "") + String.format("%0" + digitCount + "d", number); // ✅ 正确使用位数 // ... parkingSpace.setName(code); // ✅ 名称只使用编码,没有添加"车位"后缀 } ``` **前端代码**: `BatchGenerateModal.vue` 第369-385行 ```typescript const generateParkingCodePreview = () => { const { codePrefix, digitCount, startNumber, parkingCount } = formState.value; // ... const code = `${codePrefix}${String(num).padStart(digitCount, '0')}`; // ✅ 正确使用位数 }; ``` **结论**: 后端代码逻辑正确。需要检查: 1. 前端是否正确传递 `digitCount` 参数 2. 后端是否正确接收 `digitCount` 参数 --- ### 2.5 问题5:批量操作限制 **前端代码**: `SpaceManagement.vue` 第613-621行 ```typescript // 计算是否可以批量生成房间(需要选中楼栋) const canBatchGenerateRoom = computed(() => { return selectedNode.value?.nodeType === SpaceNodeType.BUILDING; }); // 计算是否可以批量生成车位(需要选中停车区域) const canBatchGenerateParking = computed(() => { return selectedNode.value?.nodeType === SpaceNodeType.GARAGE || selectedNode.value?.nodeType === SpaceNodeType.PARKING_AREA; }); ``` **问题**: 这些计算属性已定义但未使用来限制批量生成操作 **需要修改**: 移除限制,允许直接从菜单选择批量生成类型 --- ### 2.6 问题6:车位列表分页 **前端代码**: `SpaceManagement.vue` 第225-229行 ```vue ``` **结论**: ✅ 已支持分页,每页20条 --- ### 2.7 问题7:批量楼栋地址生成 **后端代码**: `SpaceNodeServiceImpl.java` 第902-911行 ```java if (parentNode != null) { building.setTreePath(parentTreePath + "." + buildingId); building.setLevel(baseLevel); String parentAddress = parentNode.getAddress() != null ? parentNode.getAddress() : parentNode.getName(); building.setAddress(parentAddress + " " + name); } else { building.setTreePath(buildingId.toString()); building.setLevel(0); building.setAddress(name); // ⚠️ 没有父节点时,地址只设置为名称 } ``` **问题**: 当没有父节点时,地址只设置为 `name`(如 "B001号楼"),而不是完整地址 **需要修改**: 应该使用项目地址作为基础地址 --- ### 2.8 问题8:项目统计数据不正确 **相关文件**: - 前端: `project/detail.vue` 第458-471行 - 后端: `ProjectServiceImpl.java` **前端代码**: ```typescript try { statistics.value = await projectApi.getProjectStatistics(projectId); } catch { // 统计接口可能不存在,使用默认值 statistics.value = { totalBuildings: project.value?.totalBuildings ?? 0, totalUnits: project.value?.totalUnits ?? 0, // ... }; } ``` **问题**: 统计数据可能来自项目表的缓存字段,而不是实时计算 **需要检查**: 1. 后端统计接口是否实时计算 2. 项目表的 `totalBuildings`, `totalUnits` 等字段是否正确更新 --- ## 三、修复方案 ### 3.1 问题2修复:批量生成房间 **需要检查**: 1. 确保前端正确传递项目ID 2. 确保后端使用项目上下文查询楼栋 ### 3.2 问题4修复:车位序号位数 **需要验证**: 1. 前端传递的 `digitCount` 参数是否正确 2. 后端接收参数是否正确 ### 3.3 问题5修复:移除批量操作限制 **修改文件**: `SpaceManagement.vue` **修改内容**: 移除 `canBatchGenerateRoom` 和 `canBatchGenerateParking` 的限制检查 ### 3.4 问题7修复:楼栋地址生成 **修改文件**: `SpaceNodeServiceImpl.java` **修改内容**: 当没有父节点时,使用项目地址作为基础地址 ### 3.5 问题8修复:项目统计数据 **需要检查**: 1. 后端统计接口实现 2. 空间节点变更时是否更新项目统计字段 --- ## 四、测试验证 ### 4.1 测试环境 - 前端: http://localhost:5175 - 后端: http://localhost:8080 ### 4.2 测试用例 | 序号 | 测试项 | 预期结果 | |------|--------|---------| | 1 | 打开批量生成弹窗,确认生成类型已隐藏 | 不显示生成类型选择 | | 2 | 批量生成房间 | 保存成功 | | 3 | 批量生成车位,设置3位数序号 | 生成如 001, 002, 003 格式 | | 4 | 批量生成车位,名称不带"车位"后缀 | 名称与编码一致 | | 5 | 不选中任何节点,点击批量生成楼栋/房间/车位 | 弹窗正常打开 | | 6 | 停车区域子项列表 | 支持分页,每页20条 | | 7 | 批量生成楼栋,查看地址 | 地址包含项目地址 | | 8 | 项目详情统计数据 | 显示正确的户数和面积 | --- ## 五、风险评估 | 风险项 | 影响 | 缓解措施 | |--------|------|---------| | 修改后端地址生成逻辑 | 可能影响现有数据 | 仅影响新生成的楼栋 | | 移除批量操作限制 | 用户可能误操作 | 在弹窗中提示用户选择正确的父节点 | | 统计数据修复 | 可能需要数据迁移 | 提供统计刷新接口 | --- **下一步**: 创建任务清单并开始修复