From 6ece274af64dbb1330e776c87e21d66bf31144ca Mon Sep 17 00:00:00 2001 From: zhuzihao Date: Fri, 26 Jun 2026 23:56:25 +0800 Subject: [PATCH] =?UTF-8?q?feat(analytics):=20=E6=96=B0=E5=A2=9E=E3=80=8C?= =?UTF-8?q?=E5=9F=8B=E7=82=B9=E6=97=A5=E5=BF=97=E3=80=8D=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=A1=B5=20(#22)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zzhyyyyy <2685922758@qq.com> Reviewed-on: https://gitea.shaguabijia.com/WonderableAI/shaguabijia-admin-web/pulls/22 Co-authored-by: zhuzihao Co-committed-by: zhuzihao --- 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 1ac18af..127a7de 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -381,6 +381,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)