WATER_PROMOTION.md 6.1 KB

企业邀请赠水(2026-10-19)

第一版为企业邀请企业:新企业首购前绑定邀请企业,首购后完成对应规格的后续完整配送签收,后台核实后向邀请企业发放水权益。奖励与代理佣金分别记账,不产生现金余额或提现,不增加实物库存。本次不实现自动送水。

配置与使用

  1. 执行 php -d extension=mbstring scripts/migrate_water_promotion.php 只查看计划;加 --apply 新建三张 InnoDB 表,初始化关闭的规则。复跑不覆盖已有配置,不回填历史订单或奖励。
  2. 使用新后台构建并重载本项目 Webman,使新增路由及代码生效。入口:财务结算中心 → 推广赠水奖励。只读沿用 water:finance:read,配置及审核沿用 water:finance:write,接口仍实时核对账号、角色和权限状态。
  3. 配置赠水规格、每次赠送桶数及首笔收款金额门槛(整数分,0表示不设额外门槛),开启新邀请。活动默认关闭,桶数默认0,无虚构奖励金额。
  4. 邀请企业管理员在小程序“我的 → 奖励与推广”获取企业唯一邀请码;可复制邀请码,微信小程序可分享对应页面。H5提供复制,不承诺生成微信二维码或海报。
  5. 新企业仍由平台建立档案并授权小程序管理员。新企业管理员在首购前输入邀请码并明确确认绑定。分享参数仅保存公开邀请码供登录后填写,不自动创建企业或授予权限。
  6. 首笔正金额、非测试购水登记后生成待审核奖励。组合结算虽然生成多张供水收款记录,但首购门槛按整笔结算金额判断,只生成一条奖励。未支付意向、免费收款、测试凭据或测试套餐不触发奖励。
  7. 首购后完成对应规格的完整配送签收,财务人员核实真实收款、无退款、非重复客户,填写说明并发放。权益页及权益明细立即可查询对应规格的赠水权益;已发放总桶数不代表剩余可用桶数。

约束和状态

  • 企业邀请码为20位随机十六进制码,企业唯一、不可由客户端指定。邀请码不是登录凭据。
  • 每个新企业仅可绑定一次邀请人。拒绝自邀、同一管理员管理的企业互邀及循环邀请;已有任何购水记录的企业不能新绑定。未首购的企业可以邀请其他企业,但没有多层邀请分成。
  • 绑定保存规则版本、赠水规格、桶数和首购门槛。修改或关闭活动只影响后续邀请码生成及新绑定;已有邀请按原约定审核,不追溯改桶数。
  • 状态:bound 待首购 → pending 待签收及审核 → issued 已发放 / rejected 不予发放。首笔实际购水低于门槛直接不予发放,后续订单不能替代首购。审核驳回不可通过重复请求改成发放。
  • 唯一约束、行锁及 request_key 保证重复请求不重复绑定或发奖。规则和审核均检查 revision;审核终态的相同结果及说明可幂等重放。
  • 首购时保存已有配送任务的最大ID;发放仅接受之后新建的、对应企业和首购规格的完整签收,避免同一秒时间戳或旧签收误领奖。赠水规格可以与首购规格不同。
  • 权益仍按企业和SKU汇总,配送未逐桶分摊到购水订单,因此此条件表示“首购后的对应规格签收”,不证明整笔组合订单已全部履约,必须结合人工核实。
  • 奖励记录、权益增加和 promotion_reward 流水在同一事务;失败全部回滚。赠水后配送继续校验仓库库存并冻结权益,不预先创造库存。
  • 小程序只返回授权企业的邀请及奖励状态,不向邀请企业披露被邀请企业的付款凭据、金额、配送ID或后台核实说明。
  • 正式退款及已用奖励扣回尚未实现;第一版必须人工审核后发放,不能视为自动退款闭环。微信登录、域名、真机分享需要原有微信配置完成。
  • 旧的本机推广演示种子不再作为真实奖励返回,不删除历史演示流水。

数据与接口

新增 sa_water_promotion_setting(平台配置)、sa_water_promotion_code(企业邀请码)、sa_water_promotion_referral(关系、规则及首购快照、奖励状态)。没有 Redis、队列或外部付款调用。

小程序已有 GET /api/mini/v1/enterprises/{enterprise}/rewards?page=1 返回真实记录,每页20条。新增:

  • POST /api/mini/v1/enterprises/{enterprise}/promotion/code:{request_key},仅企业管理员。
  • POST /api/mini/v1/enterprises/{enterprise}/promotion/bind:{request_key, invite_code},仅企业管理员。

后台新增:

  • GET /core/water/finance/promotion?page=1&status=pending:配置及分页奖励记录。
  • POST /core/water/finance/promotion/policy:{enabled, sku_id, quantity, min_amount_cents, revision}。
  • POST /core/water/finance/promotion/review:{id, revision, decision, note, receipt_refund_checked};decision 为 issued/rejected,发放须显式核实标记为true。

收款入口:WaterPurchaseReceipt::issue → PromotionReferrals::purchased;小程序控制器 → PromotionService(权限/幂等)→ 领域服务 → Eloquent模型;后台控制器沿用财务权限,委托配置、查询及审核服务。没有通过控制器查询业务表。

OpenAPI维护源为 docs/openapi/water-mini-v1.json,通过 php scripts/build_mini_docs.php 同步公开文档、npm run api:types 生成小程序类型。

验证与回退

php -d extension=mbstring tests/water_promotion_test.php 使用真实数据库事务,覆盖活动开关、规则版本、自邀/重复/共用管理员/循环绑定、权限撤销、首购、旧签收拒绝、完整签收、规则快照、组合结算、重试、驳回、财务信息隔离及失败回滚。结束比较策略、邀请、权益、收款和流水快照,所有业务夹具回滚。

回退时先关闭新邀请,保留新增表、已发放权益及审计流水;不得删除已生效权益或账本。需要回退代码时先停用新增接口入口,再使用对应旧版本构建。关闭活动不撤销已发放权益,也不取消已有绑定的约定。