diff --git a/src/app/(main)/ad-revenue-report/page.tsx b/src/app/(main)/ad-revenue-report/page.tsx index 1ed0091..b159d6d 100644 --- a/src/app/(main)/ad-revenue-report/page.tsx +++ b/src/app/(main)/ad-revenue-report/page.tsx @@ -81,11 +81,23 @@ const PLAYBACK_STATUS_TAG: Record = { unknown: { color: 'default', label: '未知' }, }; +const ZERO_REVENUE_REWARD_VIDEO_STATUSES = new Set(['closed_early', 'too_short']); + function rewardStatuses(row: AdRevenueRow): string[] { if (row.sub_rewards?.length) return row.sub_rewards.map((reward) => reward.status); return row.status ? [row.status] : []; } +function effectiveRevenueYuan(row: AdRevenueRow): number { + if ( + row.ad_type === 'reward_video' + && rewardStatuses(row).some((status) => ZERO_REVENUE_REWARD_VIDEO_STATUSES.has(status)) + ) { + return 0; + } + return row.row_revenue_yuan ?? row.revenue_yuan; +} + function rewardStatusTag(row: AdRevenueRow) { const statuses = rewardStatuses(row); if (!row.has_reward || statuses.length === 0) { @@ -546,10 +558,8 @@ export default function AdRevenueReportPage() { width: 110, align: 'right', // 一次比价/领券聚合行用 row_revenue_yuan(该次发奖广告 eCPM 折算之和),其它行用展示侧 revenue_yuan - render: (v: number, r: AdRevenueRow) => { - const rev = r.row_revenue_yuan ?? v; - return rev.toFixed(4); - }, + // 激励视频提前关闭/时长不足时防御性显示 0,与后端有效收益口径一致。 + render: (_v: number, r: AdRevenueRow) => effectiveRevenueYuan(r).toFixed(4), }, { title: '发奖状态', @@ -695,7 +705,7 @@ export default function AdRevenueReportPage() {

「预估收益」为客户端在广告展示(onAdShow)时上报 eCPM 折算的预估值(每千次展示 ÷1000 - 累加),只要广告展示就计入、不论是否看完发奖;穿山甲会过滤无效/过短曝光,故预估值可能偏高, + 累加);激励视频提前关闭或播放时长不足时按 0 计,其他有效展示按 eCPM 折算。穿山甲仍可能过滤无效曝光, 实际收益一律以穿山甲后台结算为准。测试应用多为 0。「广告位ID / 来源应用」为本期新增,历史记录留空。

diff --git a/src/lib/types.ts b/src/lib/types.ts index caec6d6..9274e27 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -488,7 +488,7 @@ export interface AdRevenueRow { has_impression: boolean; // 是否有广告展示(信息流逐条展示=true,纯发奖行=false) impressions: number; // 本行展示条数 1/0(供日汇总、趋势图复用) ecpm: string | null; // 分/千次;展示行取展示值,纯发奖行取发奖采用值 - revenue_yuan: number; // 本次展示预估收益(元);纯发奖行=0 + revenue_yuan: number; // 本次有效展示预估收益(元);纯发奖、激励视频提前关闭/时长不足=0 row_revenue_yuan?: number | null; // 主表逐行显示用:一次比价/领券聚合行=该次发奖广告 eCPM 折算之和;其它行空(回退 revenue_yuan) adn: string | null; // 实际填充 ADN;纯发奖行为空 slot_id: string | null; // 底层 mediation rit;纯发奖行为空