cce3a01de1
Co-authored-by: OuYingJun1024 <1034284404@qq.com> Reviewed-on: #49 Co-authored-by: ouzhou <ouzhou@wonderable.ai> Co-committed-by: ouzhou <ouzhou@wonderable.ai>
4.7 KiB
4.7 KiB
Admin 看广告金币审计
所属:Admin 组(前缀
/admin/api/ad-coin-audit) | 鉴权:Admin Bearer(任意已登录 admin,只读) | ← 返回 API 索引
把「看视频赚金币」(ad_reward_record)和「比价信息流广告」(ad_feed_reward_record)两类发奖记录,用与正式发奖完全相同的公式 app/core/rewards.py calculate_ad_reward_coin 复算一遍 expected_coin,与实际入账的 actual_coin 对比,核对金币公式是否生效。纯只读对账,不发币、不改任何数据。
相关表:ad_reward_record、ad_feed_reward_record。
金币公式(展示参照)
eCPM元 = getEcpm分 ÷ 100
单份金币 = round( eCPM元 ÷ 1000 × 因子1 × 因子2 × coin_per_yuan ) # coin_per_yuan=10000
- eCPM 口径:
getEcpm()原值单位是分/千次展示;先 ÷100 转元,因子判档与收益换算都用元。 - 因子1(eCPM 档,阈值单位=元/千次):≤100→0.1,101–200→0.3,201–400→0.4,>400→0.6(即 ¥100/¥200/¥400 CPM 分界。真实 eCPM 多 <¥100 CPM,故常落最低档 0.1,高档基本不触发——产品有意取舍)。
- 因子2(LT,当日第 N 份):第1→2.0,第2→1.5,第3→1.3,第4–10→1.1,≥11→1.0。
- 第 N 份的计数:看视频每条 granted 记 1 份;信息流每满 10 秒记 1 份。两个点位各自独立计数(看视频的份数不影响信息流的份数,反之亦然)。
GET /admin/api/ad-coin-audit — 复算对比
-
入参(均 query,可选):
参数 类型 默认 说明 datestring 今天 北京时间 YYYY-MM-DD,审计某天user_idint 全部 只看某用户;不传=所有用户 scenestring 两类 reward_video/feed;不传=两类都返回limitint(1~500) 100 展示明细条数(按时间倒序截断;份序号在截断前已按全天数据算好,不影响复算正确性) only_mismatchbool false 只展示不一致(✗)行;统计数仍按全量,不受影响 -
出参
200:AdCoinAuditOut字段 类型 说明 datestring 审计日期 formulaobject 当前公式参数快照(见下) totalint 该筛选下复算总条数(全量,不受 limit/only_mismatch影响)mismatch_countint 全量不一致条数(截断前统计,可信);=0 说明全部按公式发放 truncatedbool 展示集是否被 limit截断(true=还有未返回的明细,请缩小范围或调大limit)itemsAdCoinAuditRow[]展示明细(见下); only_mismatch=true时只含 ✗ 行
AdCoinFormulaOut(formula)
| 字段 | 类型 | 说明 |
|---|---|---|
description |
string | 公式文字说明 |
coin_per_yuan |
int | 金币:元 汇率(10000) |
ecpm_unit |
string | eCPM 口径(分/千次展示,SDK getEcpm 原值) |
feed_unit_seconds |
int | 信息流每多少秒折 1 份(10) |
ecpm_factor_tiers |
[因子, 下限, 上限|null][] |
因子1 档位表(直接读发奖常量,与发奖同源) |
lt_factor_tiers |
[因子, 下限, 上限|null][] |
因子2 LT 档位表 |
AdCoinAuditRow(items[])
| 字段 | 类型 | 说明 |
|---|---|---|
scene |
string | reward_video / feed |
record_id |
int | 对应记录表主键 |
user_id |
int | |
created_at |
datetime | |
status |
string | granted / capped(超每日上限未发) / ecpm_missing(缺 eCPM 未发) |
ecpm |
string | null | 本次采用的 eCPM 原始值 |
ecpm_factor |
float | null | 因子1;非 granted 为 null |
units |
int | 折算份数:看视频恒 1;信息流 = 满 10 秒份数 |
lt_index_start / lt_index_end |
int | null | 本条占用「当日第几份」的起止(看视频起=止;信息流一条可跨多份) |
lt_factor_start / lt_factor_end |
float | null | 因子2 的起止值(信息流跨份时会衰减,故给区间) |
expected_coin |
int | 按公式复算应发金币(非 granted 恒 0) |
actual_coin |
int | 实际入账金币 |
matched |
bool | 复算与实发是否一致;非 granted 校验实发是否确为 0 |
说明
- 非 granted 行(capped/ecpm_missing)不占用份序号、应发恒 0,
matched用于校验「该不发的确实没发」。 - 用法建议:按
user_id+date定位某次具体核对最直观;不带user_id是全用户当天概览。 - 本地联调造数:debug 包看完激励视频会调
/api/v1/ad/test-grant,它会用客户端按ad_session_id上报的真实 eCPM 发奖(取不到兜底 200),所以本审计能看到真实 eCPM 对应的金币。