PRD-020 商店与商城
文档编号:PRD-020
版本:v1.0
状态:已通过
适用端:服务端 / 客户端
关联模块:ScenesServer/NpcTrade.cpp、BillServer、tbl/Shop.xml
1. 背景与目标
商店分为 NPC 商店、绑定货币商店、元宝商城、活动商店。当前存在限购不跨天重置、折扣价与显示价不一致、扣款成功未发货等问题。本 PRD 统一商品、货币、限购、发货与退款。
2. 核心规则
2.1 商店类型
| 类型 | 货币 | 限购 | 典型商品 |
|---|---|---|---|
| NPC 商店 | 金币 | 无 | 消耗品、修理 |
| 绑定商店 | 绑定元宝/声望 | 每日/每周 | 材料、宝石 |
| 元宝商城 | 元宝 | 部分限购 | 时装、坐骑、礼包 |
| 活动商店 | 活动代币 | 活动周期 | 限定道具 |
2.2 购买规则
- 校验商品上架、等级/职业限制、限购次数、货币充足。
- 扣货币与发货在同一事务;发货失败则退款。
- 背包满时:可堆叠商品尝试叠加,否则拒绝购买。
- 折扣价以服务端配置为准,客户端只展示。
2.3 限购与重置
- 限购按角色 + 商品 + 周期记录。
- 每日 0 点、每周一 0 点重置;活动商店按活动结束重置。
- 限购次数为 0 时商品置灰,不允许购买。
3. 服务端设计
3.1 数据结构
struct ShopItem {
uint32_t shop_id;
uint32_t item_id;
uint32_t price;
uint8_t currency;
uint16_t limit_count;
uint8_t limit_type; // none/daily/weekly/activity
uint32_t discount;
};
struct PurchaseRecord {
uint64_t role_id;
uint32_t shop_id;
uint32_t item_id;
uint32_t count;
uint32_t cost;
uint64_t request_id;
};
3.2 协议
| 方向 | 协议 | 说明 |
|---|---|---|
| S→C | SC_ShopList | 商品列表与限购 |
| C→S | CS_ShopBuy | 购买 |
| S→C | SC_ShopBuyResult | 成功/失败/扣款 |
| S→C | SC_ShopLimitUpdate | 限购变化 |
3.3 购买流程
CS_ShopBuy(shop_id, item_id, count)
→ 校验商品/限购/等级/货币
→ 计算总价(折扣)
→ 扣货币(事务)
→ 发货到背包/邮件
→ 更新限购计数
→ 写 bill_log + item_log
→ 返回结果
3.4 计费与发货
- 元宝类商品走
BillServer,失败回滚。 - 发货优先背包,背包满转邮件。
- 购买日志保留 180 天,支持按
request_id查账。 - 重复请求幂等,不重复扣款/发货。
4. 客户端设计
- 商店分类页签、商品网格、价格/折扣/限购角标。
- 购买弹窗:数量选择、总价、余额、确认。
- 余额不足时高亮充值/获取途径。
- 购买成功播放获得动画,失败显示具体原因。
- 限购剩余次数实时刷新,跨天自动重置。
5. 配置
Shop.xml:shop_id、item_id、price、currency、limit_count、limit_type、discount、start_time、end_time、sort。
6. 边界与异常
| 场景 | 处理 |
|---|---|
| 货币不足 | 拒绝,不扣任何货币 |
| 背包满 | 转邮件或拒绝(按商品配置) |
| 限购已达上限 | 拒绝并刷新列表 |
| 折扣配置错误 | 以服务端最低价保护,记录告警 |
| 扣款成功发货失败 | 自动退款 + 补偿邮件 |
| 活动结束仍在购买 | 校验活动时间,拒绝 |
7. 验收标准
- 四类商店购买、限购、重置正确。
- 折扣价、总价、余额显示与服务端一致。
- 扣款与发货事务一致,无扣款不发货。
- 重复请求/连点不重复扣款。
- 背包满、活动结束、限购上限有明确提示。