# 金字塔活动 PRD 版本:V1.0 日期:2026-09-28 状态:活动规则已确认,前后端实现已落地到本地,尚未部署;验证范围及待补项见[开发说明](pyramid-development.md)。 配套文档:[金字塔后端设计](pyramid-backend-design.md) ## 1. 目标与范围 金字塔是全服统一时间开放的六层付费抽奖活动。玩家在前五层按层购买抽奖机会,抽中目标奖励后进入下一层,到达第六层后免费领取整个活动剩余奖励。 本文记录需求与验收契约。后续实现位于前端 `assets/pyramid` 和独立后端仓库 `laf-cloud/functions/pyramid`;没有线上配置变更。 ## 2. 已确认规则 | 项目 | 规则 | | --- | --- | | 活动层数 | 固定六层;第一至第五层付费抽奖,第六层免费领取 | | 活动时间 | 每一期全服统一开始、统一结束,以服务端时间为准 | | 初始进度 | 每期从第一层开始,一期只能完成一轮;下一期重新开始 | | 支付价格 | 按当前层配置,每次支付购买该层一次抽奖机会 | | 次数类型 | 非负整数;正常串行流程下为 0 或 1,不设计囤积次数玩法 | | 机会归属 | 绑定下单时的期次和层数,不能用于其他层或下一期 | | 购买限制 | 有可用机会时只能抽奖,不能再次购买 | | 未决支付 | 未获得确定的支付成功、明确失败或关闭结果前,禁止后续购买、抽奖和领取 | | 未决支付退出 | 可以退出活动继续游戏,重新进入时恢复原订单查询 | | 奖励格子 | 每层可配置多个格子;一个格子可包含多个道具及数量 | | 目标格子 | 前五层允许多个格子配置 `up=true`,抽中任意一个立即升级 | | 抽奖方式 | 不放回;同一格子只能获得一次,不同格子可以包含相同道具 | | 抽奖概率 | 按当前层剩余格子的权重计算,每次实际概率之和为 1 | | 普通中奖 | 留在本层;当前发货确认完成、次数为 0 后可以再次购买 | | 中奖发货 | 抽中奖励立即进入前端发货流程,不增加一个手动领取步骤 | | 发货期间 | 后端已确定中奖及升级结果;发货确认前不能继续购买、抽奖或终点领取 | | 终点领取 | 第六层手动一键领取,自动包含第一至第五层剩余奖励,以及第六层固定奖励(如果配置) | | 到期次数 | 尚未使用的已支付机会作废;活动结束后才确认的支付机会也作废 | | 到期补发 | 只补发已经获得领取资格、尚未确认到账的奖励 | | 离线补发 | 后端保留待发记录;客户端在线时及下次登录时自动查询并发货,不依赖旧活动入口 | | 发奖恢复 | 正常领取、断线重试和结束补发沿用同一发奖授权,不能重复生成同一份奖励 | 过期支付机会不转入下一期,本方案不设计因机会过期而自动退款。支付事实仍须保存,不能把“机会作废”展示成“支付失败”。 ## 3. 活动时间与配置 ### 3.1 时间边界 采用服务端半开时间区间:`startAt <= now < endAt`。到达 `endAt` 即停止新购买、新抽奖和主动终点领取,已有待发奖励仍支持查询、到账和确认。 玩家晚进入不延长本期时间。客户端倒计时用于展示,不决定资格。支付以服务端首次核验成功的时间判断是否仍可发放机会;平台显示的付款时间不能使活动结束后才确认的机会恢复有效。 支付结果在结束前已入账、响应在结束后才到达客户端的,仍属于“已入账但到期未使用”的机会,按规则作废。中奖已在结束前成功持久化而响应丢失的,奖励资格保留,不能按新抽奖拒绝恢复。 ### 3.2 运营配置 待配置的商业数值:每期起止时间、前五层价格与支付商品映射、各层格子数量、道具及数量、目标格子、权重、第六层固定奖励。 上述数值未在本次讨论中指定,不在文档中虚构。未新增等级门槛、报名条件、保底次数、任务赠送次数或循环重置玩法。 工程建议:开期后固定配置版本,价格和奖励改动在下一期生效,避免已付费订单、剩余奖池和补发内容随配置改变。 ## 4. 抽奖与升级 设当前层未获得的格子集合为 R,格子 i 的权重为 w[i]: ```text P(i) = w[i] / sum(w[j], j in R) ``` 权重不要求加总为 1;计算后的实际概率必须加总为 1。示例:剩余权重为 5、3、2 时,概率为 0.5、0.3、0.2;抽走权重 5 的格子后,剩余概率变为 0.6、0.4。 抽中普通格子后该格子退出奖池。抽中目标格子后同时获得该格子奖励并进入下一层;不继续抽取旧层,旧层剩余格子(包括未抽中的目标格子)保留到终点领取。 奖励结果由后端决定。前端动画、关闭页面或重复请求不会改变已确定的中奖结果。 ## 5. 玩家操作流程 ### 5.1 购买与支付确认 1. 查询活动状态并展示当前层及其价格。 2. 通过现有 `/wx/orderPaySig` 或 `/wx/iosorderPaySig` 发起购买。 3. 成功创建订单后进入“支付确认中”,锁定活动后续业务操作并轮询订单。 4. 确认支付成功且活动有效:当前层获得一次机会,开放抽奖。 5. 确认订单明确失败或关闭:解除支付限制,活动有效时允许重新购买。 6. 查询超时、断网或本地暂未收到支付通知:继续保持未决;可以退出活动,之后恢复查询。 同一期只允许一个未决订单,重复发起应恢复原订单。支付平台窗口取消、客户端报错等信息不能独立作为“以后不可能到账”的依据。 ### 5.2 抽奖与到账 1. 玩家有一次机会时点击抽奖。 2. 后端记录扣次数、中奖格子、奖励授权,以及需要时的升级结果。 3. 前端立即发放授权中的道具,保存到账及授权处理记录。 4. 前端向后端确认发货完成,然后开放下一步操作。 中奖后断线不丢奖励,重试不再次扣次数。抽中目标后,即使升级动画还没播放或客户端发货未完成,后端层数已经推进,但操作入口仍处于发货锁定状态。 ### 5.3 第六层 到达第六层即获得全部剩余奖励的领取资格。确认上一笔中奖发货后,显示“一键领取全部”。点击后将剩余奖励进入前端发货流程,不收费、不扣次数、不再抽奖。 全部奖励确认到账后标记本期完成,不允许重新开始。完成整轮后的奖励总量固定为本期所有格子及终点奖励之和,随机性影响到达终点的付费次数及提前获得奖励的顺序。 边界情况:如果第六层未配置固定奖励,且前五层格子在升级前已经全部抽中,则没有剩余奖励可领取;最后一笔中奖确认到账后即满足完成条件,不要求执行一次空领取。 ## 6. 活动结束与补发 | 结束时的情况 | 处理 | | --- | --- | | 停留第一至第五层,尚有一次机会 | 机会作废,不自动代抽 | | 第一至第五层已抽中、尚未确认到账 | 保留原授权并恢复发货 | | 第一至第五层未抽中的格子 | 未获得资格,不补发,包括已跳过的低层格子 | | 已到第六层但未点击领取 | 自动生成全部剩余奖励的待发记录 | | 第六层已经申请领取但未确认 | 恢复原授权,不额外生成相同奖励 | | 已确认到账 | 不重复补发 | | 活动结束后才确认支付成功 | 保存成功支付事实,机会作废,不转下一期 | “自动补发”指自动形成并保留待发记录。采用前端发货,因此玩家离线时不直接增加客户端库存;实际到账发生在客户端在线并成功处理时。 登录恢复查询覆盖全部历史期次。在线玩家也应触发待发记录查询。旧活动入口关闭、进入新一期、退出活动都不能删除尚未确认的奖励授权。 ## 7. 展示状态与交互 | 状态 | 主要展示及操作 | | --- | --- | | 未开始 | 倒计时,不能购买、抽奖或领取本期奖励 | | 可购买 | 当前层价格及奖励格子,开放购买 | | 支付确认中 | 查询状态及退出入口,不开放后续活动业务操作 | | 可抽奖 | 展示 1 次机会,购买不可用 | | 发货中 | 展示中奖结果或恢复进度,其他活动业务操作锁定 | | 第六层可领取 | 一键领取全部,无支付入口 | | 本期完成 | 展示完成状态 | | 已结束 | 不开放新活动操作;符合条件的奖励仍通过补发流程到账 | “退出活动”不等于取消订单,“支付成功”不等于道具已经到账。奖励格子同时区分已获得资格和实际发货状态,不能只凭一个布尔值判定是否需要补发。 ## 8. 产品验收清单 1. 普通中奖留在本层,发货确认后才能再次购买。 2. 同层多个目标格子均能触发升级,未抽中的目标格子保留到终点。 3. 已抽中格子不再进入奖池,剩余概率重新归一化。 4. 有次数、存在未决订单、存在当前待确认发奖时,前后端都阻止不允许的操作。 5. 支付响应丢失后恢复同一订单;重复通知不增加第二次机会。 6. 抽奖响应丢失后返回同一中奖结果和授权,不重抽、不重复扣次数。 7. 前端到账成功但确认请求失败后,不重复增加库存。 8. 第六层一次领取全部剩余奖励;重复点击不重复发奖。 9. 未到第六层的玩家到期后不会获得未抽中奖励。 10. 已到第六层但未领取的玩家,下次登录能自动恢复全部剩余奖励。 11. 活动结束后到账的支付机会作废;旧期机会不能用于新一期。 12. 活动结束后重试已经成功的抽奖或领取,仍可恢复原授权。 13. 同一期完成后不能重置;下一期独立开始,历史待发记录仍可恢复。 ## 9. 实现依赖与边界 - 支付渠道必须能区分未决状态与可信的关闭/明确失败。若暂不具备,不能靠轮询超时解除锁定,应保留未决并提供查单处理入口。 - 前端余额和已处理授权记录必须有一致的持久化及同步方案。仅新增一个 `grantId` 或发货确认接口,不足以保证断线、崩溃恢复后绝不重复到账。 - 具体开奖数值、排期、首期价格、权重和第六层固定奖励待运营配置;技术接口、幂等与恢复要求详见配套后端设计。