From 342fd0cf5dc6689f2fc5c9c0f2a74a687b52fb3d Mon Sep 17 00:00:00 2001 From: zzhyyyyy <2685922758@qq.com> Date: Fri, 26 Jun 2026 23:17:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(ad):=20=E5=90=8E=E5=8F=B0=E5=B9=BF?= =?UTF-8?q?=E5=91=8A=E9=85=8D=E7=BD=AE=E4=B8=8E=E6=94=B6=E7=9B=8A=E6=8A=A5?= =?UTF-8?q?=E8=A1=A8=E6=94=AF=E6=8C=81=20Draw=20=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E6=B5=81=E5=B9=B6=E5=8C=BA=E5=88=86=E6=AF=94=E4=BB=B7/?= =?UTF-8?q?=E9=A2=86=E5=88=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 运营后台:广告配置页信息流代码位改为 Draw 代码位(比价Draw信息流/领券Draw信息流,字段 compare_draw_code_id/coupon_draw_code_id);收益报表新增"场景"列与筛选,按比价/领券拆分 Draw 收益并显示各自金币小计。 Co-Authored-By: Claude Opus 4.8 --- src/app/(main)/ad-revenue-report/page.tsx | 75 ++++++++++++++++++++++- src/app/(main)/ad-revenue/page.tsx | 12 ++-- src/lib/types.ts | 1 + 3 files changed, 79 insertions(+), 9 deletions(-) diff --git a/src/app/(main)/ad-revenue-report/page.tsx b/src/app/(main)/ad-revenue-report/page.tsx index 553dc8d..0a67d60 100644 --- a/src/app/(main)/ad-revenue-report/page.tsx +++ b/src/app/(main)/ad-revenue-report/page.tsx @@ -47,6 +47,13 @@ const TYPE_TAG: Record = { withdrawal_video: { color: 'gold', label: '提现激励视频' }, }; +// Draw 信息流投放场景标签(后端 AdRevenueRow.feed_scene:comparison/coupon/welfare) +const SCENE_TAG: Record = { + comparison: { text: '比价', color: 'blue' }, + coupon: { text: '领券', color: 'gold' }, + welfare: { text: '福利', color: 'green' }, +}; + // 我们的应用环境标签 const APP_TAG: Record = { prod: { color: 'green', label: '傻瓜比价(正式)' }, @@ -256,6 +263,8 @@ export default function AdRevenueReportPage() { const [range, setRange] = useState<[Dayjs, Dayjs]>([dayjs(), dayjs()]); const [userId, setUserId] = useState(null); const [adType, setAdType] = useState(); + // 「场景」为纯前端过滤(后端 query 暂不支持 feed_scene),只作用于下方明细表,不重新请求、不影响趋势/日汇总。 + const [scene, setScene] = useState(); const [granularity, setGranularity] = useState<'day' | 'hour'>('day'); const [limit, setLimit] = useState(500); const [queriedGranularity, setQueriedGranularity] = useState<'day' | 'hour'>('day'); // 本次结果对应的粒度,决定是否显示「小时」列 @@ -332,6 +341,16 @@ export default function AdRevenueReportPage() { return {t.label}; }, }, + { + title: '场景', + dataIndex: 'feed_scene', + width: 80, + render: (v: string | null | undefined) => { + if (!v) return -; + const t = SCENE_TAG[v]; + return t ? {t.text} : {v}; + }, + }, { title: '来源应用', dataIndex: 'app_env', @@ -428,6 +447,16 @@ export default function AdRevenueReportPage() { } : null; + // 「场景」纯前端过滤:只对已加载的明细 items 生效(后端 query 暂不支持 feed_scene);趋势图/日汇总仍用全量 daily/total_*。 + const allItems = data?.items ?? []; + const filteredItems = scene ? allItems.filter((r) => r.feed_scene === scene) : allItems; + + // 选中比价/领券且类型=draw 时,给出该场景在已加载明细内的实发金币小计(仅明细口径,可能受 limit 截断)。 + const sceneCoinSubtotal = + adType === 'draw' && (scene === 'comparison' || scene === 'coupon') + ? filteredItems.reduce((s, r) => s + (r.has_reward ? r.actual_coin : 0), 0) + : null; + return (
@@ -497,6 +526,22 @@ export default function AdRevenueReportPage() { ]} /> + + 场景 + )} + {sceneCoinSubtotal != null && ( + + 当前已加载明细中, + + {SCENE_TAG[scene!].text} + + Draw 信息流 实发金币小计 {sceneCoinSubtotal}(共 {filteredItems.length} 条; + 仅明细口径,若已截断可能偏少;上方汇总/趋势仍为全量)。 + + } + /> + )} )} @@ -640,7 +701,7 @@ export default function AdRevenueReportPage() { } > - {/* 按小时图由 items 聚合,会被 limit 截断;按天图用 daily(全量)不受影响,故只在按小时时警告 */} + {/* 趋势图与日汇总恒为全量:按天图用 daily(全量),按小时图用全量 items;「场景」前端过滤只作用于下方明细表,不影响此图。 */} {!queriedMultiDay && data.truncated && ( )} + {scene && ( + + )} {queriedMultiDay ? ( ) : ( @@ -660,11 +729,11 @@ export default function AdRevenueReportPage() { (r.has_reward && !r.matched ? 'row-mismatch' : '')} expandable={{ // 只有发了奖的事件可展开,看「这条广告金币怎么算的」;纯展示行无复算、不可展开。 diff --git a/src/app/(main)/ad-revenue/page.tsx b/src/app/(main)/ad-revenue/page.tsx index 1bc8e27..8e9e609 100644 --- a/src/app/(main)/ad-revenue/page.tsx +++ b/src/app/(main)/ad-revenue/page.tsx @@ -10,8 +10,8 @@ import { api, errMsg } from '@/lib/api'; interface AdCfg { app_id: string; reward_code_id: string; - compare_feed_code_id: string; - coupon_feed_code_id: string; + compare_draw_code_id: string; + coupon_draw_code_id: string; reward_mkey: string; reward_enabled: boolean; compare_ad_enabled: boolean; @@ -74,11 +74,11 @@ export default function AdConfigPage() { > - - + + - - + + diff --git a/src/lib/types.ts b/src/lib/types.ts index cacc526..3514c37 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -348,6 +348,7 @@ export interface AdRevenueRow { user_id: number; user_phone: string | null; // 用户手机号(admin 展示;查不到为空) ad_type: string; // reward_video / feed / draw + feed_scene?: string | null; // Draw 信息流投放场景 comparison(比价) / coupon(领券) / welfare(福利);非信息流或旧数据为 null app_env: string | null; // prod(傻瓜比价) / test(测试);旧数据为空 our_code_id: string | null; // 我们配置的代码位 104xxx;旧数据为空 hour: number | null; // 北京时间小时 0–23(按小时粒度时有值;按天为 null)