289 lines
8.0 KiB
Markdown
289 lines
8.0 KiB
Markdown
# 空间批量操作问题修复规格说明书
|
||
|
||
**文档版本**: 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
|
||
<a-form-item label="生成类型" name="generateType" v-show="false">
|
||
```
|
||
|
||
**结论**: ✅ 已正确隐藏,无需修改
|
||
|
||
---
|
||
|
||
### 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<SpaceNodeResponse> 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
|
||
<a-table
|
||
:pagination="{
|
||
pageSize: 20,
|
||
showSizeChanger: false,
|
||
showTotal: (total: number) => `共 ${total} 条`
|
||
}"
|
||
>
|
||
```
|
||
|
||
**结论**: ✅ 已支持分页,每页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 | 项目详情统计数据 | 显示正确的户数和面积 |
|
||
|
||
---
|
||
|
||
## 五、风险评估
|
||
|
||
| 风险项 | 影响 | 缓解措施 |
|
||
|--------|------|---------|
|
||
| 修改后端地址生成逻辑 | 可能影响现有数据 | 仅影响新生成的楼栋 |
|
||
| 移除批量操作限制 | 用户可能误操作 | 在弹窗中提示用户选择正确的父节点 |
|
||
| 统计数据修复 | 可能需要数据迁移 | 提供统计刷新接口 |
|
||
|
||
---
|
||
|
||
**下一步**: 创建任务清单并开始修复
|