# 运单导入校验功能 - 前后端对接完成总结 ## 完成时间 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` 转换为 `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