spec.md 5.0 KB

小程序端积分相关 Controller 代码质量与规范治理 Spec

Why

fs-user-app/.../controller/store 目录下涉及积分的 Controller 存在多处代码规范与质量问题:防重复提交缺失、支付回调无分布式锁、IDOR 越权漏洞、NPE 风险、死代码、自赋值 Bug、代码重复等。这些问题直接影响积分扣减/发放的资金安全与数据一致性,违反项目内存中"代码严谨规范、高可用、计算准确"的工程约定。

What Changes

  • 为下单接口 StoreOrderScrmController.create/createMultiStore 增加 @RepeatSubmit 防重复提交注解
  • 为单门店支付回调 PayScrmController.hfPayNotify/ybPayNotify 增加分布式锁,避免重复回调导致积分重复发放
  • 修复 IntegralScrmController.getIntegralOrderById 的 IDOR 越权漏洞,校验订单归属
  • 修复 UserSignScrmController.getIntegral 行 71 的自赋值 Bug(param.setUserId(param.getUserId()) 改为从登录态取值)
  • 清理 HuifuPayScrmController 被注释的死代码及未使用的依赖注入
  • 修复 user.getIntegral().intValue() 的 NPE 风险,增加 null 校验
  • 删除 IntegralScrmController 中与 UserSignScrmController 重复的 getUserSignsign 方法
  • 为支付回调 switch 语句补充 default 分支并记录日志
  • 抽取硬编码的配置 key(store.sign)与魔法值(支付来源 1)为常量
  • 统一 @Login 注解使用策略
  • BREAKING:删除 IntegralScrmController.getUserSignIntegralScrmController.sign 两个重复端点(/store/app/integral/getUserSign/store/app/integral/sign),前端需改用 /store/app/sign/* 路径

Impact

  • Affected specs: 积分发放规则(points.grantRule)、多门店积分按比例分配、签到积分、积分商品兑换
  • Affected code:
    • fs-user-app/.../store/StoreOrderScrmController.java(下单防重)
    • fs-user-app/.../store/PayScrmController.java(回调加锁、switch default)
    • fs-user-app/.../store/IntegralScrmController.java(IDOR 修复、删除重复方法、NPE 修复)
    • fs-user-app/.../store/UserSignScrmController.java(自赋值 Bug 修复、NPE 修复、常量化)
    • fs-user-app/.../store/HuifuPayScrmController.java(死代码清理)
    • fs-user-app/.../store/CourseScrmController.java(方法命名、参数校验)

ADDED Requirements

Requirement: 下单接口防重复提交

系统 SHALL 为所有涉及积分扣减的下单接口提供防重复提交保护。

Scenario: 用户快速双击提交订单

  • WHEN 用户在 3 秒内重复调用 /store/app/order/create/store/app/order/createMultiStore
  • THEN 第二次及后续请求被拦截,返回"请勿重复提交"提示,积分不被重复扣减

Requirement: 支付回调分布式锁保护

系统 SHALL 为所有支付回调接口提供分布式锁保护,防止第三方支付平台重复回调导致积分重复发放。

Scenario: 第三方支付平台重复回调

  • WHEN 汇付/易宝在短时间内对同一笔订单发送多次支付成功回调
  • THEN 仅第一次回调处理成功并发放积分,后续回调因获取锁失败直接返回 SUCCESS 且不重复发放积分

Requirement: 积分订单越权访问防护

系统 SHALL 校验积分订单查询接口的订单归属,防止用户查看他人订单。

Scenario: 用户枚举他人订单 ID 查询

  • WHEN 用户 A 调用 /store/app/integral/getIntegralOrderById?orderId=用户B的订单ID
  • THEN 系统返回"无权访问该订单",不返回订单数据

MODIFIED Requirements

Requirement: 签到积分发放

签到接口 UserSignScrmController.sign SHALL 正确从登录态获取 userId,并保证积分余额字段读取时无 NPE 风险。

Scenario: 用户查询积分记录

  • WHEN 用户调用 /store/app/sign/getIntegral
  • THEN 返回当前登录用户的积分记录(修复前因自赋值 Bug 返回错误数据)

Requirement: 积分相关配置 key 常量化

所有积分相关的配置 key(如 store.sign)与魔法值(如支付来源 1)SHALL 抽取为常量,禁止在方法体内硬编码。

Scenario: 配置 key 统一管理

  • WHEN 开发者需要修改签到配置 key
  • THEN 在常量类中修改一处即可,无需在多个方法体内查找替换

REMOVED Requirements

Requirement: IntegralScrmController 中的签到接口

Reason: getUserSignsign 方法在 IntegralScrmControllerUserSignScrmController 中完全重复,违反 DRY 原则,维护困难 Migration: 前端需将 /store/app/integral/getUserSign/store/app/integral/sign 的调用迁移到 /store/app/sign/getUserSign/store/app/sign/sign

Requirement: HuifuPayScrmController 被注释的支付回调逻辑

Reason: 整个 switch 语句被注释,方法体仅剩 return "ok",注入的 7 个 Service 全部未使用,属于死代码 Migration: 真正生效的支付回调在 PayScrmController 中,无需迁移;直接清理被注释代码与未使用依赖