Преглед изворни кода

制定闪送时段运价实施计划

补充后端时段运价模型、外卖同规则整数计价、平台 CRUD、前端调整与数据库迁移任务。
qmj пре 3 дана
родитељ
комит
73d19f9857
2 измењених фајлова са 112 додато и 0 уклоњено
  1. 100 0
      specs/024-flash-delivery/plan.md
  2. 12 0
      specs/024-flash-delivery/tasks.md

+ 100 - 0
specs/024-flash-delivery/plan.md

@@ -172,3 +172,103 @@ git diff --check
 Set-Location E:\QtwCode\foodie\foodie_server
 git diff --check
 ```
+
+## 外卖同规则时段运价增量(2026-09-01)
+
+本节替代上方“平台管理前端增量”中的单行价格配置接口、七字段表单和两位小数计价描述;订单管理与平台介入设计继续有效。
+
+### 目标与架构
+
+**目标**:将闪送计价改为与现有外卖订单一致的“当前时段 + 起送距离/价格 + 计价距离/金额”规则,移除最低价、时长费、尖峰倍率和启停状态,并让平台在独立闪送入口维护三种服务的多个运价时段。
+
+**架构**:`flash_delivery_pricing` 继续作为闪送独立配置表,但从每服务单行改为每服务多时段。`FlashDeliveryPricingMapper` 在数据库当前时间下返回唯一匹配时段并提供重叠计数;`FlashDeliveryPricingCalculator` 只负责距离边界和整数 TWD 计算;应用服务负责 CRUD、版本、订单快照和业务错误。平台前端复用现有价格页与权限,改为时段新增、修改和删除。
+
+**技术栈**:JDK 21、Spring Boot、MyBatis-Plus/MyBatis、MySQL、JUnit 5/Mockito;Vue 2.6、Element UI 2.15、Vue i18n 8、Node `node:test`。
+
+### 全局约束
+
+- 不新建分支或 worktree,后端与平台前端都在当前 `test` 分支工作。
+- 不直接执行数据库迁移;删除测试阶段旧计价数据和字段的 SQL 只追加到 `updatesql/sql.md`。
+- 路线预计时长继续保存和展示,但不得参与计价。
+- 起送价格、计价金额、里程费用和最终金额均为整数 TWD;计算结果使用 `RoundingMode.HALF_UP` 取整到 1 元,不做千位特殊取整。
+- 同一服务类型的时段使用开始包含、结束不包含语义且不得重叠;保存即生效,删除即失效,不提供 `enabled`。
+- Controller 使用明确 DTO 和显式注解,平台配置接口继续使用 `flash:pricing:list/edit`。
+- 前端新增可见文本同步简中、繁中、英文和越南文,文件保留 CRLF,不增加 npm 依赖。
+- 只修改闪送功能所需文件,不触碰工作区原有脏文件。
+
+### 文件职责
+
+```text
+foodie_server/
+├── ruoyi-system/src/main/java/com/ruoyi/system/domain/flash/
+│   ├── FlashDeliveryPricing.java          # 时段运价实体
+│   └── FlashDeliveryOrder.java            # 整数金额与运价快照
+├── ruoyi-system/src/main/java/com/ruoyi/system/mapper/flash/
+│   └── FlashDeliveryPricingMapper.java    # 当前时段与重叠查询
+├── ruoyi-system/src/main/resources/mapper/flash/
+│   └── FlashDeliveryOrderMapper.xml       # 新订单快照字段映射
+├── ruoyi-admin/src/main/java/com/ruoyi/app/flashdelivery/
+│   ├── controller/FlashDeliveryAdminController.java
+│   ├── dto/FlashDeliveryPricingRequest.java
+│   ├── dto/FlashDeliveryPriceBreakdown.java
+│   ├── dto/FlashDeliveryQuoteView.java
+│   ├── dto/FlashDeliveryServiceView.java
+│   └── service/{FlashDeliveryApplicationService,FlashDeliveryPricingCalculator}.java
+├── ruoyi-admin/src/test/java/com/ruoyi/app/flashdelivery/
+│   ├── controller/FlashDeliveryControllerContractTest.java
+│   └── service/{FlashDeliveryApplicationServiceTest,FlashDeliveryPricingCalculatorTest}.java
+├── ruoyi-admin/src/main/resources/i18n/messages_{zh_CN,zh_TW,en_US,vi}.properties
+└── updatesql/sql.md
+
+foodie-admin-vue/
+├── src/api/flashDelivery/{contracts,index}.js
+├── src/views/flashDelivery/shared.js
+├── src/views/flashDelivery/pricing/index.vue
+├── src/views/flashDelivery/orders/OrderDetail.vue
+├── src/api/language/language.{zh_CN,zh_TW,en_US,vi}.js
+└── tests/flash-delivery.test.cjs
+```
+
+### 后端接口与数据流
+
+1. `FlashDeliveryPricing` 使用 `startTime,endTime,startingDistance,startingFare,distance,freight`;距离为正十进制公里,金额为正 `Long`。
+2. `selectCurrent(serviceType)` 使用数据库 `CURTIME()` 和 `start_time <= CURTIME() AND end_time > CURTIME()` 匹配唯一时段;找不到时返回国际化业务错误。
+3. `countOverlaps(serviceType,startTime,endTime,excludedId)` 使用 `start_time < endTime AND end_time > startTime` 检测重叠;新增和修改均在写入前校验。
+4. 计价器签名改为 `calculateBreakdown(FlashDeliveryPricing pricing, int distanceMeters)`。超出公里小于 `0.5` 时计费公里为 `0`,小于 `1` 时为 `1`,否则使用实际超出公里;`distanceFee` 四舍五入为 `Long`,`amount=startingFare+distanceFee`。
+5. `GET /admin/pricing` 返回全部时段;`POST /admin/pricing` 新增;`PUT /admin/pricing/{id}` 按版本更新;`DELETE /admin/pricing/{id}` 删除。新增、修改和删除都使用 `flash:pricing:edit`。
+6. `home` 对三种服务分别读取当前时段,只返回有配置的服务;`quote/create` 每次重新读取当前时段并计算。订单固化 `pricingId,pricingVersion,pricingStartTime,pricingEndTime,startingDistance,startingFare,distance,freight,distanceFee`。
+7. 报价与公开服务 DTO 移除旧计价字段,保留 `estimatedDurationSeconds`;金额 DTO 和订单实体改为整数 `Long`。
+
+### 平台前端交互
+
+- 价格页表格按服务类型、开始时间排序,列出起止时间、起送距离/价格、计价距离/金额、版本和更新时间。
+- “新增时段”打开空表单;“编辑”回填完整配置;“删除”二次确认后请求服务端并刷新列表。
+- 表单校验开始时间早于结束时间、距离为正数、金额为正整数,并用当前列表预检同服务时段重叠;服务端仍执行最终重叠校验。
+- 页面不显示启停、最低价、每分钟价格或尖峰倍率。配置保存后立即生效,无匹配时段时由后端阻止报价。
+- 订单详情展示匹配时段、起送距离/价格、计价距离/金额、里程费用和整数总额;预计时长仍显示在路线信息中。
+
+### TDD 批次
+
+1. 先改 `FlashDeliveryPricingCalculatorTest`,覆盖起送内、超出 `0.49/0.50/0.99/1.20` 公里、非 1 公里计价距离、`.5` 金额四舍五入及非法配置;确认旧实现编译或断言失败。
+2. 再改应用服务和 Controller 契约测试,覆盖当前时段读取、无时段、重叠新增/修改、版本冲突、删除、整数快照和新路由;确认旧接口失败。
+3. 实现实体、Mapper、DTO、计算器、应用服务、Controller 和四语言后端错误,使定向后端测试转绿。
+4. 先改 Node 测试,要求新增/修改/删除请求、六字段载荷、时段/整数校验、页面权限和四语言新 key,并确认旧前端失败。
+5. 实现前端请求、纯函数、价格页、订单详情与四语言,使 Node 测试转绿。
+6. 追加开发阶段清理 SQL,删除旧配置数据和两表旧字段,增加时段及新订单快照字段;不执行 SQL。
+
+### 验证命令
+
+```powershell
+Set-Location E:\QtwCode\foodie\foodie_server
+$env:JAVA_HOME='C:\Users\qmj\.jdks\graalvm-jdk-21.0.7'
+$env:PATH="$env:JAVA_HOME\bin;$env:PATH"
+mvn -pl ruoyi-admin -am -Dtest='FlashDeliveryPricingCalculatorTest,FlashDeliveryApplicationServiceTest,FlashDeliveryControllerContractTest,FlashDeliveryOrderViewTest,FlashDeliveryAvailableOrderViewTest,FlashDeliveryI18nContractTest' -Dsurefire.failIfNoSpecifiedTests=false test
+mvn -pl ruoyi-admin -am -DskipTests package
+git diff --check
+
+Set-Location E:\QtwCode\foodie\foodie-admin-vue
+npm run test:flash-delivery
+npx eslint --no-ignore src/api/flashDelivery/index.js src/api/flashDelivery/contracts.js src/views/flashDelivery/shared.js src/views/flashDelivery/pricing/index.vue src/views/flashDelivery/orders/index.vue src/views/flashDelivery/orders/OrderDetail.vue tests/flash-delivery.test.cjs
+npm run build:prod
+git diff --check
+```

+ 12 - 0
specs/024-flash-delivery/tasks.md

@@ -64,3 +64,15 @@
 - [x] T036 [US6] 在四个 `src/api/language/language.*.js` 文件增加一致的 `flashDelivery` 文案,并使语言与页面契约测试转绿
 - [x] T037 [US6] 在 `updatesql/sql.md` 追加幂等的“闪送管理/价格配置/闪送订单”动态菜单 SQL,将现有六项权限归入对应页面
 - [x] T038 [US6] 运行 `npm run test:flash-delivery`、新增文件 ESLint、`npm run build:prod` 和两个仓库 `git diff --check`,核对暂存范围后分别使用中文提交
+
+## Phase 10:外卖同规则时段运价
+
+- [ ] T039 [US1] 先重写 `FlashDeliveryPricingCalculatorTest`,覆盖起送内、0.49/0.50/0.99/1.20 公里边界、非 1 公里计价距离、整数 HALF_UP 和非法配置,并确认旧计价实现红灯
+- [ ] T040 [US1] 重写 `FlashDeliveryPricing`、`FlashDeliveryOrder`、费用 DTO、订单 XML 和计价器,删除最低价、分钟价、尖峰与启停字段,实现整数 TWD 的外卖同规则距离计价
+- [ ] T041 [US5] 先扩展 `FlashDeliveryApplicationServiceTest` 与 `FlashDeliveryControllerContractTest`,覆盖当前时段、无时段、重叠、新增、按 ID 修改、版本冲突、删除和新订单快照,并确认旧服务接口红灯
+- [ ] T042 [US5] 实现 `FlashDeliveryPricingMapper` 当前时段/重叠查询、时段 CRUD、home/quote/create 当前时段读取、完整快照及四语言业务错误,使后端定向测试转绿
+- [ ] T043 [US6] 先更新 `tests/flash-delivery.test.cjs`,覆盖价格 GET/POST/PUT/DELETE、六字段载荷、时段与整数校验、页面权限和四语言 key,并确认旧前端红灯
+- [ ] T044 [US6] 更新前端 API、`shared.js`、价格时段新增/编辑/删除页面、订单费用详情和四语言,删除启停、最低价、分钟价与尖峰展示,使定向测试转绿
+- [ ] T045 在 `updatesql/sql.md` 追加开发阶段迁移:清理旧闪送计价数据,删除两表旧计价字段,增加时段配置、新订单快照字段与索引;只记录不执行
+- [ ] T046 使用 JDK 21 运行后端定向测试和模块构建,运行前端定向测试、强制 ESLint、生产构建、CRLF 与两个仓库差异检查
+- [ ] T047 核对两个仓库暂存范围,分别使用中文提交并推送当前 `test` 分支,不包含后端仓库原有脏文件