bindbox-game/.trae/documents/统一积分设计与支付联动.md
邹方成 45815bfb7d chore: 清理无用文件与优化代码结构
refactor(utils): 修复密码哈希比较逻辑错误
feat(user): 新增按状态筛选优惠券接口
docs: 添加虚拟发货与任务中心相关文档
fix(wechat): 修正Code2Session上下文传递问题
test: 补充订单折扣与积分转换测试用例
build: 更新配置文件与构建脚本
style: 清理多余的空行与注释
2025-12-18 17:35:55 +08:00

5.3 KiB
Raw Blame History

现状与审计结论

  • 积分存储:user_points 余额、user_points_ledger 流水;订单字段 orders.points_amount(分)存在但未在支付链路写入。
  • 转换比率存在两套并存:
    • 1元=10积分internal/api/user/points_redeem_product_app.go:55-60internal/api/user/points_redeem_coupon_app.go:55-61、展示与调度退款部分。
    • 1元=100积分退款按比例恢复internal/api/admin/pay_refund_admin.go:133-167;以及金额退款流水:internal/api/admin/pay_refund_admin.go:158-167internal/api/admin/lottery_admin.go:131
  • 统一配置已存在但未全面使用:points_exchange_per_cent(每分对应的积分),在资产兑换中生效:internal/service/user/address_share.go:137-147,175-183,198-199
  • 支付回调未联动积分:internal/api/pay/wechat_notify.go:133-141 仅更新订单与券,不处理 points_amount/points_ledger_id
  • 管理端订单详情积分展示按 /10internal/api/admin/pay_orders_admin.go:366-372
  • 调度器退款按 /10 恢复:internal/service/activity/scheduler.go:80-83

目标与边界

  • 统一换算严格执行“1元=100积分”即“分→积分除以100”或统一通过 points_exchange_per_cent默认1控制所有入口使用同一来源。
  • 钱支付为主,积分是权益之一:支持订单使用积分抵扣(记录为 orders.points_amount),并在退款按比例恢复所扣积分;支持支付成功后按配置返积分(可选)。
  • 保持幂等与数据一致性,避免对历史数据造成破坏。

变更设计

  • 转换率收敛

    • 将积分兑换商品/优惠券的“分/10”改为统一转换
      • 商品:internal/api/user/points_redeem_product_app.go 使用 needPoints := price_in_cents / 100price_in_cents * points_exchange_per_cent
      • 优惠券:internal/api/user/points_redeem_coupon_app.go 使用同一逻辑。
    • 管理端展示:PointsUsed := points_amount / 100,修改 internal/api/admin/pay_orders_admin.go
    • 调度器退款恢复:refundPts := points_amount / 100,修改 internal/service/activity/scheduler.go
    • 提供共用转换函数(服务层):centsToPoints(cents, rate),所有入口统一调用,来源于 system_configs.points_exchange_per_cent
  • 订单积分抵扣接入

    • 下单/支付前:新增“使用积分抵扣”选项,调用 user.ConsumePointsFor 扣减;将抵扣金额写入 orders.points_amount(单位分),并写入 user_points_ledgerref_table=orders、ref_id=order_no
    • 幂等:重复请求不重复扣减;取消/超时需恢复。
  • 支付成功联动

    • 微信回调:internal/api/pay/wechat_notify.go 在订单转“已支付”后:
      • 若订单已有 points_amount>0,确保对应扣积分流水存在(幂等校验)。
      • 可选:读取 system_configs.points_reward_per_cent默认0按“每分奖励多少积分”为用户发放支付返积分流水 action=pay_reward)。
  • 退款联动一致性

    • 管理端退款与调度器统一按 points_amount/100 计算需恢复积分,流水 action=refund_restore;金额退款流水 refund_amount := amount_refund/100 保持不变。
    • 退款比例恢复公式保持:restorePointsTarget = (points_amount * refunded_cents / total_paid_cents) / 100
  • 文档与配置

    • Swagger注释与说明文本改为“1元=100积分”。
    • 系统配置:确保存在并默认 points_exchange_per_cent=1;新增可选 points_reward_per_cent=0

实现清单(按模块)

  1. 统一转换入口
  • 修改 internal/api/user/points_redeem_product_app.go:55-60internal/api/user/points_redeem_coupon_app.go:55-61
  • 增加服务层转换工具并替换硬编码。
  1. 展示与调度一致
  • 修改 internal/api/admin/pay_orders_admin.go:366-372
  • 修改 internal/service/activity/scheduler.go:80-83
  1. 订单积分抵扣
  • 下单接口/订单生成逻辑:写入 orders.points_amount(分)与积分扣减流水。
  • 回调幂等校验:wechat_notify.go 保证一致。
  1. 退款一致性
  • 保持 admin/pay_refund_admin.go 公式不变;
  • 修正调度器恢复逻辑为 /100,并保证只在 points_amount>0 场景生效。
  1. 支付返积分(可选)
  • 新增读取 points_reward_per_cent,在 wechat_notify.go 进行奖励入账与流水。
  1. 测试与验收
  • 单元测试:
    • 转换函数:分↔积分在不同 points_exchange_per_cent 下正确。
    • 订单使用积分:扣减、写入订单、退款部分恢复。
    • 回调奖励:开启/关闭奖励配置的行为。
  • 集成测试:
    • 正常支付→即时开奖→虚拟发货链路无回归。
    • 调度不足参与→全额退款→金额与积分恢复一致。
  • 管理端与APP展示points_used=points_amount/100 一致。

风险与数据兼容

  • 历史数据可能基于/10提供一次性校验脚本仅统计差异不强制修复新数据全走统一入口避免继续漂移。
  • 幂等与重复扣减:以 user_points_ledger + ref_table/ref_id 作为幂等键。

交付物

  • 代码改动API、服务、调度
  • 配置项说明与默认值。
  • Swagger与README更新。
  • 测试报告(单元+集成)。

请确认按此方案执行。我将按上述顺序推进并提交具体改动与测试结果。