# 实施计划:闪送配送服务 **分支**:`test` | **日期**:2026-08-31 | **规格**:[spec.md](./spec.md) ## 摘要 在既有独立闪送模块上补充包裹类别/重量档、立即或预约配送、可选 PIN 交付、寄件图片、费用明细、页面状态分组、骑手公开摘要和角色安全响应。服务端继续负责路线报价、骑手原子抢单、取件/送达图片、用户签收、24 小时自动完成和平台介入;支付、退款、结算、骑手收入与自动派单仍不在本期范围。 ## 技术上下文 - **语言/版本**:Java 21 - **主要依赖**:Spring Boot、Spring MVC、Spring Security、MyBatis/MyBatis-Plus、Apache HttpClient 4、fastjson2 - **存储**:MySQL;迁移仅记录在 `updatesql/sql.md` - **测试**:JUnit 5、Mockito、Spring MockMvc、MyBatis XML 解析测试 - **目标平台**:现有 RuoYi 多模块 REST API 服务端 - **性能目标**:列表分页;抢单和状态流转单条条件更新;地图超时后立即降级 - **约束**:保持 `ruoyi-admin -> ruoyi-system`;Controller 不接收 Map;App 身份只从 token 解析;业务错误全部 i18n;不执行数据库迁移 - **范围**:24 个闪送/地址端点、4 张新表、1 张地址表增量、五套语言资源、定向自动化测试 ## 规范检查 - [x] 独立 `flash_delivery_*` 模型,不复用 `pos_order`/`taxi_order` - [x] HTTP 集成只放在 `ruoyi-admin` - [x] Controller 使用显式 DTO 和参数注解 - [x] 用户与骑手接口通过 token 取身份,平台接口使用明确权限 - [x] 金额、距离和状态由服务端计算与校验 - [x] 地址、订单和凭证执行所有权/角色校验 - [x] SQL 只写 `updatesql/sql.md` - [x] 支付能力明确延期 ## 源码结构 ```text ruoyi-system/src/main/java/com/ruoyi/system/ ├── domain/flash/ # 订单、计价、图片、日志实体 └── mapper/flash/ # 持久化、原子抢单、条件状态流转 ruoyi-system/src/main/resources/mapper/flash/*.xml ruoyi-admin/src/main/java/com/ruoyi/app/flashdelivery/ ├── controller/ # 用户、骑手、平台 Controller ├── dto/ # 明确请求 DTO 与响应视图 ├── service/ # 报价、状态机、权限和脱敏 ├── route/ # Google Routes 与直线降级 └── task/ # 送达 24 小时自动完成 ruoyi-admin/src/test/java/com/ruoyi/app/flashdelivery/ ruoyi-system/src/test/java/com/ruoyi/system/mapper/flash/ ``` 地址簿沿用 `InfoAddress`、`IInfoAddressService` 和 `InfoAddressController`,增加请求 DTO、置顶字段、按用户条件查询/更新及所有权测试。 ## 核心实现决策 1. `FlashDeliveryApplicationService` 是事务边界;报价只读,创建和每个状态操作同时写订单与日志。 2. 抢单执行带 `status='WAITING_ACCEPTANCE' AND rider_id IS NULL` 的单条 UPDATE;受影响行数不是 1 即已被抢走。 3. 其余状态变更携带订单、操作者、预期状态和版本条件,阻止并发覆盖。 4. `(user_id, client_request_id)` 唯一键保证创建幂等;冲突时返回原订单。 5. Google Routes API 字段掩码仅取距离与时长;异常、非 2xx、空路线或无效距离降级为 Haversine。 6. 待抢单使用专用脱敏视图;抢单后只有订单骑手可见完整电话和详细地址。 7. 寄件图片在创建事务中写入;取件/送达图片在状态更新事务中写入。三类凭证均校验 1 至 9 个 HTTP(S) URL,取件和送达不得为空。 8. 预约订单沿用 `WAITING_ACCEPTANCE`,可抢查询和原子抢单 SQL 同时限制 `scheduled_pickup_start_at <= now`,不增加仅为调度使用的新状态。 9. PIN 默认启用并由服务端生成四位数字;用户详情可见,骑手响应始终剔除,送达事务先校验 PIN 再写凭证和状态。 10. 用户/骑手使用业务视图,平台详情保留完整审计实体;待抢视图只增加类别、重量档、配送时段、预计时长和市/区级路线信息。 11. 自动任务扫描送达满 24 小时订单并逐条条件完成,和用户/平台并发时只允许一次成功。 ## 补充原型增量实施批次 1. 更新规格、API、数据模型和 `updatesql/sql.md`,明确旧表增量字段及索引。 2. 先扩展计价器、Mapper XML、应用服务和 Controller 契约测试并确认红灯。 3. 增加请求/响应 DTO、实体字段、计价明细与角色安全映射。 4. 实现预约可抢条件、PIN 校验、寄件凭证和状态分组分页。 5. 使用 JDK 21 运行闪送定向测试、MyBatis XML 测试、模块构建与差异检查。 ## 验证策略 测试先行:先写测试并确认因实现缺失而失败,再添加最小生产代码。最终统一执行: ```powershell $env:JAVA_HOME='C:\Users\qmj\.jdks\graalvm-jdk-21.0.7' $env:PATH="$env:JAVA_HOME\bin;$env:PATH" mvn -pl ruoyi-system -am -Dtest=FlashDeliveryMapperXmlTest -Dsurefire.failIfNoSpecifiedTests=false test mvn -pl ruoyi-admin -am -Dtest='FlashDelivery*Test,InfoAddressControllerSecurityTest' -Dsurefire.failIfNoSpecifiedTests=false test mvn -pl ruoyi-admin -am -DskipTests package git diff --check ``` ## 复杂度跟踪 无规范违例。四张新表分别承担订单快照、可变计价、图片凭证和审计日志;应用层留在 admin 是外部 HTTP 依赖和模块边界共同决定的。