3.7 KiB
3.7 KiB
MODIFIED Requirements
Requirement: 统一积分服务接入
系统 SHALL 在插件加载时声明对 danding_points 的依赖,并通过 points_api 完成所有积分相关操作。所有积分流水的 source 参数 MUST 固定为 horse_race。points_api 调用失败时系统 MUST 先区分失败类型:余额不足直接拒绝不重试,网络/服务异常则重试 1 次并间隔 1 秒;仍然失败则记录错误日志并向用户返回服务异常提示,不进行后续状态变更。
Scenario: 插件加载时声明积分依赖
- WHEN 群赛马插件初始化
- THEN 系统先执行
require("danding_points"),并从danding_bot.plugins.danding_points导入points_api
Scenario: 下注扣款写入统一来源
- WHEN 用户成功下注 100 积分
- THEN 系统调用
points_api.spend_points(user_id, 100, "horse_race", "赛马下注")
Scenario: 积分服务余额不足时直接拒绝
- WHEN 系统调用
points_api.spend_points首次返回(False, balance)且余额低于下注额 - THEN 系统直接向用户提示积分不足,不进行重试
Scenario: 积分服务网络异常时带延时重试
- WHEN 系统调用
points_api.spend_points首次抛出网络异常或服务异常 - THEN 系统等待 1 秒后重试同一调用 1 次;若仍失败,则向用户返回"积分服务异常,请稍后重试",不写入下注记录、不变更房间状态
Requirement: 赔率计算与展示
系统 SHALL 使用标准池赔率公式计算每匹马的赔率:odds = total_pool / horse_pool,其中 total_pool 为当前比赛所有马匹的下注总额,horse_pool 为目标马匹的下注总额。当 horse_pool = 0 时(无人下注的马匹),赔率 MUST 设为 None 且不对外展示。系统 SHALL 在展示和结算时应用 MIN_ODDS 最低赔率保护,但仅当应用后总赔付不超过总池子时生效;若应用 MIN_ODDS 会导致该马赔付总额超过 total_pool,则 MUST 使用真实赔率。赔率展示 MUST 对当前房间内所有已下注马匹可用,精度保留到小数点后两位。结算金额 MUST 向下取整为整数积分。结算时 MUST 使用锁内快照赔率而非重新计算,确保与用户下注时看到的赔率一致。
Scenario: 标准赔率计算
- WHEN 总下注池为 800,某马下注额为 500
- THEN 该马赔率计算为
800 / 500 = 1.6
Scenario: 无人下注的马匹
- WHEN 某匹马没有收到任何下注(
horse_pool = 0) - THEN 该马赔率为
None,不在赔率列表中展示
Scenario: 热门马赔率触发下限保护且池子可承担
- WHEN 某匹马计算赔率为
1.08,MIN_ODDS=1.2,该马下注总额为 500,总池为 800 - THEN 应用保底赔率 1.2 后该马赔付总额为 600(≤800),系统对外展示和结算均使用
1.2
Scenario: 热门马赔率触发下限但池子不可承担
- WHEN 某匹马计算赔率为
1.08,MIN_ODDS=1.2,该马下注总额为 750,总池为 800 - THEN 应用保底赔率 1.2 后该马赔付总额为 900(>800),系统不应用保底,使用真实赔率
1.08
Scenario: 赔率精度与取整
- WHEN 赔率计算结果为
1.5238... - THEN 展示为
1.52,结算时bet_amount × 1.52向下取整为整数积分
Scenario: 显示当前赔率
- WHEN 用户发送显示赔率命令
- THEN 系统返回当前房间所有已下注马匹的赔率明细,格式为"马匹名: 赔率值"
Scenario: 结算使用快照赔率
- WHEN 比赛结束进入结算流程
- THEN 系统在持锁状态下计算赔率快照并用于所有赔付计算,不依赖比赛开始前保存的可能已过时的赔率