plan.md 5.2 KB

Implementation Plan: 可配置支付方式(031-pay-method-config)

Branch: test-202609v2(直接开发,不建 feature 分支) | Date: 2026-09-11 | Spec: spec.md

Input: Feature specification from /specs/031-pay-method-config/spec.md

Summary

支付方式可用性从代码固定行为改为三层闸门:平台开关(方式×维度,新表 payment_method_config,缺行=开)∩ 收款方选择(info_user.pay_methods / flash_pay_methods,NULL=全部)∩ 就绪度(凭证/启用卡)。核心是 ruoyi-system 的 PaymentMethodGateService 单一校验入口,用户餐饮下单、商家建单、闪送下单、027 bankInfo 四处统一调用,顺带堵掉 createOrder 不校验 payType 的漏洞。银行卡从 027 三字段列表化为 info_bank_card(多卡单启用,存量 INSERT...SELECT 迁移),闪送订单复用 pay_type 列并新增 payment_status(骑手确认收款,不阻塞流程)。前端两页:admin-vue 平台开关矩阵页、foodie-store 商家支付设置页(勾选+银行卡管理),均四语言。

Technical Context

Language/Version: Java 21(后端);Vue2 + Element UI(两前端)

Primary Dependencies: Spring Boot、MyBatis-Plus、vue-i18n(foodie-store);httpclient4+fastjson2(不涉及新外部调用)

Storage: MySQL(2 张新表 + 3 处加列,DDL 全部入 updatesql/sql.md 手动执行)

Testing: JUnit5 + Mockito(后端单测);SQL 只读冒烟用 pymysql 直连测试库

Target Platform: Linux 服务端(Spring Boot)+ 两个管理前端(Windows 开发)

Project Type: web-service(多模块 Maven + 两前端仓库)

Performance Goals: 开关读取走字典式缓存(同 DictUtils 模式),结算页/下单路径不新增可感知延迟;保存开关后下一次查询即生效

Constraints: 模块依赖 ruoyi-admin → ruoyi-system 单向;闸门服务放 ruoyi-system;Controller 规范(@RequestHeader/@RequestBody DTO/@RequestParam,DTO 无 Bean Validation);前端 CRLF 用 Python 编辑;Java 注释禁 */

Scale/Scope: 后端 2 新表 + 3 加列 + 1 新服务 + 6 组新接口 + 3 入口接入;前端 2 新页面;迁移 1 条 SQL;i18n 后端 6 文件 + 前端 4 文件

Constitution Check

.specify/memory/constitution.md 为未填充模板占位,无已批准的项目原则约束 → GATE: PASS(无适用条款)。项目实际约束以 CLAUDE.md(模块边界/Controller 规范/i18n/DDL 流程)为准,已并入 Technical Context Constraints。

Project Structure

Documentation (this feature)

specs/031-pay-method-config/
├── plan.md              # 本文件
├── research.md          # 代码现状核对(含行号锚点)与 15 项既定决策
├── data-model.md        # 表结构/迁移/就绪度判定
├── quickstart.md        # 验证场景(对照 SC-001~006)
├── contracts/api.md     # 接口契约(含闸门服务内部契约与三入口调用点)
├── checklists/requirements.md
└── tasks.md             # /speckit-tasks 生成(待)

Source Code (repository root)

ruoyi-system/src/main/java/com/ruoyi/system/
├── domain/PaymentMethodConfig.java            # 新:平台开关
├── domain/InfoBankCard.java                   # 新:银行卡
├── domain/InfoUser.java                       # 加 payMethods/flashPayMethods
├── domain/flash/FlashDeliveryOrder.java       # 加 paymentStatus
├── mapper/PaymentMethodConfigMapper.java      # 新
├── mapper/InfoBankCardMapper.java             # 新
└── service/PaymentMethodGateService.java      # 新:单一闸门入口(assertUsable/listAvailable)

ruoyi-admin/src/main/java/com/ruoyi/app/
├── pay/PayMethodConfigController.java         # 新:平台开关(list/put)
├── pay/BankCardController.java                # 新:银行卡 CRUD+启用
├── user/... MerchantPayMethodController.java  # 新:商家选择(get/put)
├── qs(RiderFlashPayMethodController).java     # 新:骑手闪送方式(get/put)
├── order/UserOrderController.java             # 改:createOrder 接闸门(:261)
├── order/PosOrderController.java              # 改:/addorder 接闸门(COD对称校验)
├── chanting/... bankInfo 数据源改 info_bank_card + 套闸门
└── flashdelivery/service/FlashDeliveryApplicationService.java  # 改:normalizePayType→闸门;抢单过滤;confirmPayment

E:\QtwCode\foodie\foodie-admin-vue\src\views\pay\methodConfig\   # 新:平台开关矩阵页
E:\QtwCode\foodie\foodie-store\src\views\PayMethodSettings.vue   # 新:商家支付设置页(参照SelfDeliverySettings.vue)
+ 两前端路由/菜单/i18n(四语言)

Structure Decision: 闸门与凭证/卡读取同层(ruoyi-system),Controller 全在 ruoyi-admin;前端独立仓库各一页。pay 包为新建(现有 chanting/store 等包无支付方式配置归属)。

Complexity Tracking

无 Constitution 违规需要豁免。设计保持在"1 服务 + 2 表 + 2 页"最小面:平台开关用结构化表而非逐 key sys_config(矩阵+排序+唯一约束,已决策);不引入规则引擎、不做逐店覆盖、不做 App 端页面。