research.md 6.0 KB

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

Date: 2026-09-11 | Spec: spec.md

本文记录实现前核对的代码现状(含行号锚点)与既定决策,纠正旧记忆中过时的事实。

一、代码现状(2026-09-11 核对)

1.1 payType 值域与三个下单入口

含义 备注
1 到付 商家建单固定用它(PosOrderController.java:266/1226 setPayType("1")
2 信用卡(OMG) OrderLifecycleService.isCardWalletPayTypePosOrderController.java:668
3 LINE Pay LinePayService.PAY_TYPE_LINEPosOrderController.java:676
4 现金 仅商家建单场景;闪送也已用作"现金"
5 Apple Pay(OMG) 与 2 同为 OMG 渠道
6 线下转账 027 引入
  • 漏洞确认UserOrderController.java:261 posOrder.setPayType(input.getPaymentMethod()) —— 用户下单传什么存什么,零校验
  • 商家建单(/addorder)固定到付 1,无支付方式选择。

1.2 闪送现状(⚠️ 纠正旧记忆"闪送零支付代码")

闪送已有支付字段与逻辑(近期提交"闪送订单增加支付方式字段"+"修改normalizePayType"):

  • FlashDeliveryOrder.payType 已存在(FlashDeliveryOrder.java,注释:4=现金、6=线下转账)
  • FlashDeliveryApplicationService.normalizePayType(...) 当前为透传(白名单校验被注释掉),缺省默认现金
  • FlashDeliveryOrderView.payType、骑手列表 FlashDeliveryRiderOrderListView.payType 均已返回
  • 闪送没有:payment_status(收款状态)、下单闸门校验、骑手收款方式设置

1.3 027 线下转账(迁移基准)

  • 接口:GET /chanting/store/bankInfo?id={storeId}(匿名)——pos_store.id → user_id → info_user,返回 bankAccountName / bankName / bankAccountNo 三字段;客户端 data != null 才显示线下支付(详见 specs/027-offline-transfer-payment/contracts/api.md
  • 商家确认收款:/system/orderShOprate/confirmTransferPayment商家确认,订单级;031 的骑手确认收款是闪送订单级,二者并存不冲突)
  • InfoUser 银行相关字段:bankAccount(185)、bankPhoto(193)、bankAccountName(197)、bankName(199)、bankAccountNo(205)。027 转账展示用的三字段 = bankName + bankAccountNo + bankAccountName

1.4 凭证与就绪度数据源

  • OMG(信用卡/Apple Pay):门店级 pos_store_omg/system/storeOmg 管理)
  • LINE Pay:门店级 pos_store_line_pay
  • admin-vue 已有门店支付凭证配置页:foodie-admin-vue/src/views/mendian/storePayment(OmgTab/LinePayTab)——031 的平台开关页是独立新页(方式×维度开关),不复用该页

1.5 可复用先例

  • 银行字典:taiwan_bank_list 已存在,且有读取先例(InfoUserController.java:815-821query.setDictType("taiwan_bank_list")
  • 商家 PC 设置页先例:foodie-store/src/views/SelfDeliverySettings.vue(029)
  • 平台开关先例:008 用 sys_config 单 key;本期改用结构化表(已决策),理由:方式×维度矩阵、带排序、可逐行改
  • 模块边界:校验服务需读 info_user/pos_store_omg/pos_store_line_pay/info_bank_card(全在 ruoyi-system)→ 闸门服务放 ruoyi-system,Controller 调用在 ruoyi-admin(符合 admin→system 单向依赖)

1.6 前端项目

  • 平台端:E:\QtwCode\foodie\foodie-admin-vue(新页"支付方式设置",四语言)
  • 商家端:E:\QtwCode\foodie\foodie-store(新页"支付设置"= 方式勾选 + 银行卡管理,vue-i18n 四语言 src/lang/
  • 两项目文件均为 CRLF,编辑用 Python 脚本(项目惯例)

二、既定决策(不再讨论,实现依据)

来源:2026-09-09 对话定稿 13 项 + 2026-09-11 补充 2 项,全文见 spec.md。

  1. 三层闸门:可用 = 平台开关(方式×维度) ∩ 收款方选择 ∩ 就绪度;维度 = MERCHANT(商家餐饮单) / RIDER_FLASH(骑手闪送),独立开关可交叉
  2. 闪送资金用户直达骑手,平台不经手;支付方式下单时选并随订单固定
  3. 骑手未设置 flash_pay_methods = 平台开放全部;商家 pay_methods NULL = 全部启用(存量零变化)
  4. 商家选择在主账号级(连锁共享,与 027 银行信息语义一致)
  5. 信用卡+Apple Pay 同组一个开关(OMG 渠道,023 同组先例)
  6. 到付(1) 纳入管控默认开;现金(4) 不纳入(仅商家建单)
  7. 不做平台逐店覆盖(YAGNI)
  8. 老 App:后端拒绝+国际化提示;bankInfo 接口保留、结构不变、改读启用卡、套闸门
  9. 商家 PC 做设置页;商家 App/骑手 App 只出接口(027 FR-010 模式)
  10. 银行卡列表化:info_bank_card 挂 info_user,商家/骑手通用,多卡同时仅一张 is_active,启用新卡停旧卡;付款方只见启用卡
  11. 027 迁移:info_user 三字段存量 INSERT...SELECT 迁成一张启用卡;就绪度判据从"三字段齐全"改"存在启用卡"
  12. 骑手确认收款:闪送订单 paymentStatus 0→1 + 操作日志;不阻塞送达/完成
  13. 下单闸门校验封装为单一独立方法(唯一校验入口),三下单路径(用户餐饮下单/商家建单/闪送下单)统一下单时调用,禁止各入口重复实现
  14. DDL 全部追加 updatesql/sql.md,开发者手动执行
  15. 平台开关缺行语义 = 开启(零数据依赖,新方式代码上线即默认可用,平台页保存时才落行,enabled=0 才是关)

三、实现要点结论

  • 闪送支付方式复用现有 pay_type扩展值域(不新增列);仅新增 payment_status
  • normalizePayType 透传行为改为调用闸门校验方法(补回被注释掉的白名单 + 三层闸门)
  • bankInfo 返回结构与字段名完全不变,仅数据源与可见性判断变化
  • 闸门服务命名建议 PaymentMethodGateService(ruoyi-system),提供 assertUsable(...)(校验,抛国际化异常)与 listAvailable(...)(结算页可选项)两个核心方法