# 小程序端积分相关 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` 重复的 `getUserSign`、`sign` 方法 - 为支付回调 switch 语句补充 default 分支并记录日志 - 抽取硬编码的配置 key(`store.sign`)与魔法值(支付来源 `1`)为常量 - 统一 `@Login` 注解使用策略 - **BREAKING**:删除 `IntegralScrmController.getUserSign` 和 `IntegralScrmController.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**: `getUserSign` 和 `sign` 方法在 `IntegralScrmController` 和 `UserSignScrmController` 中完全重复,违反 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` 中,无需迁移;直接清理被注释代码与未使用依赖