bdafb83583
2、调整运单
326 lines
9.3 KiB
Markdown
326 lines
9.3 KiB
Markdown
# 运单导入校验功能 - 前后端对接完成总结
|
||
|
||
## 完成时间
|
||
2026-09-08
|
||
|
||
## 改造方式
|
||
从前端校验改为后端校验,参考港口码头导入模块(`/base/port-terminal`)的实现方式。
|
||
|
||
---
|
||
|
||
## 一、后端实现完成
|
||
|
||
### 1. 修改的文件
|
||
|
||
#### 1.1 控制器层
|
||
**文件**: `/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/WaybillController.java`
|
||
|
||
**修改内容**:
|
||
- 修改 `confirmImportBatch` 方法签名
|
||
- 添加 `HttpServletResponse response` 参数
|
||
- 返回类型从 `R` 改为 `void`(响应通过 response 直接写入)
|
||
|
||
```java
|
||
@PostMapping("/import-batch/confirm")
|
||
@ApiOperationSupport(order = 7)
|
||
@Operation(summary = "确认运单批量导入")
|
||
public void confirmImportBatch(@RequestBody WaybillImportBatchRequest request, HttpServletResponse response) {
|
||
waybillImportBatchService.confirm(request, response);
|
||
}
|
||
```
|
||
|
||
#### 1.2 服务接口层
|
||
**文件**: `/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IWaybillImportBatchService.java`
|
||
|
||
**修改内容**:
|
||
- 添加 `jakarta.servlet.http.HttpServletResponse` 导入
|
||
- 修改 `confirm` 方法签名,添加 `HttpServletResponse response` 参数
|
||
- 返回类型从 `WaybillImportBatch` 改为 `void`
|
||
|
||
#### 1.3 服务实现层
|
||
**文件**: `/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillImportBatchServiceImpl.java`
|
||
|
||
**修改内容**:
|
||
|
||
1. **添加导入**:
|
||
```java
|
||
import jakarta.servlet.http.HttpServletResponse;
|
||
import org.springblade.common.excel.ImportFailureExcelUtil;
|
||
import org.springblade.core.tool.api.R;
|
||
import org.springblade.core.tool.utils.DateUtil;
|
||
import org.springblade.core.tool.utils.WebUtil;
|
||
import org.springblade.transport.excel.WaybillImportBatchExcel;
|
||
```
|
||
|
||
2. **重写 `confirm` 方法**:
|
||
- 在导入前执行校验
|
||
- 校验失败时导出包含错误信息的 Excel 文件
|
||
- 校验通过时执行导入并返回 JSON 成功响应
|
||
|
||
3. **修改 `persist` 方法**:
|
||
- 移除了内部的校验逻辑(校验已提前在 `confirm` 中处理)
|
||
- 专注于数据持久化
|
||
|
||
4. **添加 `mapToExcel` 方法**:
|
||
- 将 `Map<String, Object>` 转换为 `WaybillImportBatchExcel` 对象
|
||
- 用于生成错误明细 Excel
|
||
|
||
#### 1.4 Excel 实体类
|
||
**文件**: `/blade-service/blade-transport/src/main/java/org/springblade/transport/excel/WaybillImportBatchExcel.java`
|
||
|
||
**修改内容**:
|
||
- 添加 `errorMessage` 字段(用于存储校验错误信息)
|
||
|
||
```java
|
||
/** 导入失败原因(不导出到模板,仅用于失败明细) */
|
||
private String errorMessage;
|
||
```
|
||
|
||
### 2. 校验规则实现
|
||
|
||
后端已经实现了完整的校验规则(在 `validateImportRows` 方法中):
|
||
|
||
#### 2.1 格式校验
|
||
- ✅ 车牌号格式(公路运输)
|
||
- ✅ 手机号格式(11位数字)
|
||
- ✅ 运输方式枚举值
|
||
- ✅ 计量单位枚举值
|
||
- ✅ 正数校验(数量、里程)
|
||
- ✅ 日期时间格式
|
||
|
||
#### 2.2 逻辑校验
|
||
- ✅ 运费合计 = 运费 + 其他费用合计
|
||
- ✅ 日期关系校验(发货时间不能晚于完成时间)
|
||
- ✅ 配载标识号一致性
|
||
- ✅ 同一运单标识号一致性
|
||
|
||
### 3. 错误明细 Excel 格式
|
||
|
||
- ✅ 在原始 Excel 最后一列追加"错误信息"列
|
||
- ✅ 错误信息以红色字体显示
|
||
- ✅ 校验通过的行显示空字符串
|
||
- ✅ 多个错误用 "; " 分隔
|
||
- ✅ 列宽自动调整
|
||
|
||
---
|
||
|
||
## 二、前端实现完成
|
||
|
||
### 1. 回滚的代码
|
||
|
||
#### 1.1 删除的文件
|
||
- ❌ `src/utils/waybill-import-validator.js`(前端校验工具)
|
||
- ❌ `src/utils/transport-plan-import-validator.js`(运输计划校验工具)
|
||
|
||
#### 1.2 修改的文件
|
||
**文件**: `src/views/business/components/waybill-import-dialog.vue`
|
||
|
||
**回滚内容**:
|
||
- 移除校验相关的导入
|
||
- 移除 `validationResult`、`validationDetails`、`uploadedFile` 等响应式变量
|
||
- 移除 `performValidation` 方法
|
||
- 移除 `exportErrorReport` 方法
|
||
- 简化 `fileChange`、`fileRemove`、`confirmImport`、`resetCreateForm` 方法
|
||
|
||
**保留内容**:
|
||
- 文件上传逻辑
|
||
- Excel 解析逻辑
|
||
- 表单提交逻辑
|
||
|
||
### 2. 前端处理流程
|
||
|
||
前端现在的处理逻辑非常简单:
|
||
|
||
1. 用户上传 Excel 文件
|
||
2. 前端解析文件并展示预览
|
||
3. 用户点击"确认导入"
|
||
4. 前端调用后端接口 `POST /blade-transport/waybill-manage/import-batch/confirm`
|
||
5. 后端响应:
|
||
- **JSON 响应** → 前端提示"导入成功"
|
||
- **Excel 文件流** → 浏览器自动下载错误明细表
|
||
|
||
**关键点**: 前端的 `axios` 会自动处理响应类型,当后端返回 Excel 文件流时,浏览器会自动触发下载。
|
||
|
||
---
|
||
|
||
## 三、接口对接说明
|
||
|
||
### 接口信息
|
||
- **路径**: `/blade-transport/waybill-manage/import-batch/confirm`
|
||
- **方法**: POST
|
||
- **Content-Type**: `application/json`
|
||
|
||
### 请求参数
|
||
```json
|
||
{
|
||
"id": null,
|
||
"batchNo": "YDB202609080001",
|
||
"projectId": 123,
|
||
"contractId": 456,
|
||
"carrierType": "承运商",
|
||
"carrierId": 789,
|
||
"carrierContractId": 101,
|
||
"status": "completed",
|
||
"importType": "waybill",
|
||
"planId": null,
|
||
"rows": [
|
||
{
|
||
"vehicleNo": "桂A12345",
|
||
"transportType": "公路整车",
|
||
"departureAddress": "广西南宁市...",
|
||
"arrivalAddress": "广东广州市...",
|
||
"cargoName": "钢材",
|
||
"cargoType": "建筑材料",
|
||
"quantity": "10",
|
||
"quantityUnit": "吨",
|
||
"actualStartDate": "2024-09-01",
|
||
"actualEndDate": "2024-09-02",
|
||
...
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 响应说明
|
||
|
||
#### 成功响应(JSON)
|
||
```
|
||
HTTP/1.1 200 OK
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"code": 200,
|
||
"success": true,
|
||
"data": null,
|
||
"msg": "操作成功"
|
||
}
|
||
```
|
||
|
||
#### 失败响应(Excel 文件流)
|
||
```
|
||
HTTP/1.1 200 OK
|
||
Content-Type: application/vnd.ms-excel
|
||
Content-Disposition: attachment; filename=运单导入失败明细20260908182530.xlsx
|
||
|
||
[Excel Binary Data]
|
||
```
|
||
|
||
错误明细 Excel 格式:
|
||
- 最后一列为"错误信息"列(红色字体)
|
||
- 每行显示该行的所有校验错误(用 "; " 分隔)
|
||
- 校验通过的行显示空字符串
|
||
|
||
---
|
||
|
||
## 四、测试验证
|
||
|
||
### 4.1 后端编译
|
||
✅ **成功** - `mvn clean compile -DskipTests` 通过
|
||
|
||
### 4.2 前端构建
|
||
✅ **成功** - `pnpm run build` 通过
|
||
|
||
### 4.3 待测试项
|
||
|
||
#### 后端测试
|
||
- [ ] 上传完全正确的数据,验证导入成功
|
||
- [ ] 上传车牌号格式错误的数据,验证下载错误明细
|
||
- [ ] 上传必填项缺失的数据,验证下载错误明细
|
||
- [ ] 上传手机号格式错误的数据,验证下载错误明细
|
||
- [ ] 上传运费合计不匹配的数据,验证下载错误明细
|
||
- [ ] 上传日期逻辑错误的数据,验证下载错误明细
|
||
- [ ] 上传配载标识号车牌不一致的数据,验证下载错误明细
|
||
- [ ] 上传混合数据(部分正确部分错误),验证错误明细格式
|
||
|
||
#### 前端测试
|
||
- [ ] 验证文件上传和预览功能
|
||
- [ ] 验证导入成功时的提示
|
||
- [ ] 验证校验失败时自动下载错误明细
|
||
- [ ] 验证错误明细 Excel 的格式和内容
|
||
|
||
#### 联调测试
|
||
- [ ] 启动后端服务
|
||
- [ ] 启动前端服务
|
||
- [ ] 完整流程测试
|
||
|
||
---
|
||
|
||
## 五、文档输出
|
||
|
||
### 已创建的文档
|
||
1. **导入校验规则-后端实现文档.md** - 详细的校验规则说明(供后端开发参考)
|
||
2. **导入校验改造总结.md** - 改造过程总结
|
||
3. **本文档** - 前后端对接完成总结
|
||
|
||
---
|
||
|
||
## 六、运输计划导入
|
||
|
||
运输计划导入(`/business/transport-plan/import`)当前已经支持错误明细下载(代码行 519-547),只需要后端按照类似的方式实现校验逻辑即可。
|
||
|
||
**待完成**:
|
||
- [ ] 参考运单导入的实现方式
|
||
- [ ] 在运输计划导入接口中实现校验逻辑
|
||
- [ ] 校验失败时返回 Excel 文件流
|
||
|
||
---
|
||
|
||
## 七、注意事项
|
||
|
||
### 7.1 响应类型判断
|
||
前端的 `axios` 或 `fetch` 会根据响应头 `Content-Type` 自动处理:
|
||
- `application/json` → 解析为 JSON 对象
|
||
- `application/vnd.ms-excel` → 作为文件下载
|
||
|
||
**重要**: 后端必须正确设置响应头,否则前端无法正确处理。
|
||
|
||
### 7.2 事务处理
|
||
- 校验失败导出 Excel 时,不会执行数据库操作
|
||
- 校验通过后才会开始事务并持久化数据
|
||
- 如果持久化失败,事务会回滚
|
||
|
||
### 7.3 性能考虑
|
||
- 大文件导入建议设置超时时间(当前默认 60 秒)
|
||
- 校验使用了 TreeMap 确保错误信息按行号排序
|
||
- 使用 Map 数据结构优化跨行校验性能
|
||
|
||
### 7.4 扩展性
|
||
- 校验规则集中在 `validateImportRows` 方法中,便于维护
|
||
- 枚举值从配置中加载,便于扩展
|
||
- Excel 导出使用工具类,便于复用
|
||
|
||
---
|
||
|
||
## 八、后续工作
|
||
|
||
### 短期
|
||
1. **测试验证** - 完成上述测试用例
|
||
2. **Bug 修复** - 根据测试结果修复问题
|
||
3. **运输计划导入** - 实现类似的校验逻辑
|
||
|
||
### 长期
|
||
1. **校验规则配置化** - 将部分规则抽取为配置
|
||
2. **地址库集成** - 实现真实的地址匹配校验
|
||
3. **性能优化** - 针对大文件导入进行优化
|
||
4. **国际化** - 支持多语言错误信息
|
||
|
||
---
|
||
|
||
## 九、参考资料
|
||
|
||
### 参考实现
|
||
- **港口码头导入**: `/blade-system/port-terminal/import-port-terminal`
|
||
- **导入失败工具类**: `org.springblade.common.excel.ImportFailureExcelUtil`
|
||
- **前端导入工具**: `/src/utils/import-excel.js`
|
||
|
||
### 相关文档
|
||
- 《导入校验规则-后端实现文档.md》
|
||
- 《导入校验改造总结.md》
|
||
|
||
---
|
||
|
||
**完成状态**: ✅ 前后端代码已完成,编译通过,等待测试验证
|
||
|
||
**编写人**: Claude Code
|
||
**版本**: 1.0
|