ether-docs/02-DESIGN/domains/batch-operations/spec.md

289 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 空间批量操作问题修复规格说明书
**文档版本**: 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 | 项目详情统计数据 | 显示正确的户数和面积 |
---
## 五、风险评估
| 风险项 | 影响 | 缓解措施 |
|--------|------|---------|
| 修改后端地址生成逻辑 | 可能影响现有数据 | 仅影响新生成的楼栋 |
| 移除批量操作限制 | 用户可能误操作 | 在弹窗中提示用户选择正确的父节点 |
| 统计数据修复 | 可能需要数据迁移 | 提供统计刷新接口 |
---
**下一步**: 创建任务清单并开始修复