1、调整凭证

2、调整运单
This commit is contained in:
2026-09-08 22:41:40 +08:00
parent f370f56a92
commit bdafb83583
16 changed files with 1816 additions and 51 deletions
@@ -0,0 +1,325 @@
# 运单导入校验功能 - 前后端对接完成总结
## 完成时间
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