From ec9b7efcd6a6341e03ade1cbf94bedc42eae0f5f Mon Sep 17 00:00:00 2001
From: jacy <18049821889@163.com>
Date: Thu, 3 Sep 2026 13:25:22 +0800
Subject: [PATCH] =?UTF-8?q?=E6=8E=A8=E5=B9=BF=E7=A0=81=E6=A8=A1=E5=9D=97?=
=?UTF-8?q?=EF=BC=8C=E5=9C=A8=E5=90=8E=E7=AB=AF=E5=A2=9E=E5=8A=A0=E6=96=87?=
=?UTF-8?q?=E6=A1=88=E8=A1=A8=E8=BE=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/admin-web/src/pages/PromoCodesPage.tsx | 4 +-
.../src/pages/promo/PromoCodeDetailPage.tsx | 54 ++++++++++++-------
.../src/pages/promo/PromoCodeMetricsPanel.tsx | 2 +-
.../src/pages/promo/PromoCodeUsersPage.tsx | 11 +++-
4 files changed, 46 insertions(+), 25 deletions(-)
diff --git a/apps/admin-web/src/pages/PromoCodesPage.tsx b/apps/admin-web/src/pages/PromoCodesPage.tsx
index 43a354a..16d042a 100644
--- a/apps/admin-web/src/pages/PromoCodesPage.tsx
+++ b/apps/admin-web/src/pages/PromoCodesPage.tsx
@@ -90,7 +90,7 @@ export default function PromoCodesPage() {
),
},
{
- title: '扫码',
+ title: 扫码,
dataIndex: 'scanCount',
width: 70,
render: (v: number, row) => (
@@ -110,7 +110,7 @@ export default function PromoCodesPage() {
),
},
{
- title: '转化率',
+ title: 转化率,
width: 90,
render: (_, row) => promoConversion(row.scanCount, row.orderCount),
},
diff --git a/apps/admin-web/src/pages/promo/PromoCodeDetailPage.tsx b/apps/admin-web/src/pages/promo/PromoCodeDetailPage.tsx
index a7971b2..14939e3 100644
--- a/apps/admin-web/src/pages/promo/PromoCodeDetailPage.tsx
+++ b/apps/admin-web/src/pages/promo/PromoCodeDetailPage.tsx
@@ -37,8 +37,33 @@ const descContentStyle: CSSProperties = {
wordBreak: 'break-all',
};
+const SCAN_HINT =
+ '按人次累计:每次扫码或带参进入记一次,未登录也计入;同一用户多次进入记多次。同一次打开内的重复上报、以及登录后补归因不重复计。不是按人去重。';
+
const ATTRIBUTION_HINT =
- '首次触达本推广码的用户。每人只归因一次、只归一个码:已登录用户扫码或带参进入时,若还没有归因记录,则记到本码;之后再扫其他码不会改。与「扫码注册」不同:注册只统计来源仍是自然量并被标记为本码的用户;已有其他来源(如分享)的用户仍可计入归因,但不计入扫码注册。';
+ '首次触达本推广码的用户,按人计:每人只归因一次、只归一个码。已登录扫码时,若还没有归因记录则记到本码;未登录先扫码、登录后再补记。之后再扫其他码不会改。未登录连续扫多个码时,登录后归到最后一次缓存的码。与「扫码注册」不同:已有分享等其他来源的用户仍可计入归因,但不计入扫码注册。';
+
+const REGISTER_HINT =
+ '用户来源仍是自然量时,才标记为本推广码。已有分享等其他来源的用户不计入,因此通常小于或等于归因用户数。';
+
+const ORDER_HINT = '下单时绑定当时的归因推广码,仅统计已完成订单。';
+
+const CONVERSION_HINT =
+ '已完成订单数 ÷ 扫码进入次数(人次)。同一人多次扫码会放大分母,未登录扫码也计入。';
+
+function StatHint({ label, hint }: { label: string; hint: string }) {
+ return (
+
+ {label}
+
+ e.stopPropagation()}
+ />
+
+
+ );
+}
async function downloadQrcode(url: string, filename: string) {
try {
@@ -221,20 +246,16 @@ export default function PromoCodeDetailPage() {
style={{ cursor: 'pointer' }}
onClick={() => navigate(`/promo-codes/${detail.id}?eventType=SCAN`)}
>
-
+ }
+ value={stats?.scanCount ?? detail.scanCount}
+ />
- 归因用户数
-
-
-
-
- }
+ title={}
value={stats?.attributionCount ?? 0}
/>
@@ -242,7 +263,7 @@ export default function PromoCodeDetailPage() {
}
value={stats?.registerCount ?? stats?.sourceMarkedCount ?? 0}
/>
@@ -255,14 +276,7 @@ export default function PromoCodeDetailPage() {
onClick={() => navigate(`/orders?promoCodeId=${detail.id}&status=COMPLETED`)}
>
- 订单数
-
-
-
-
- }
+ title={}
value={stats?.orderCount ?? detail.orderCount}
/>
@@ -270,7 +284,7 @@ export default function PromoCodeDetailPage() {
}
value={promoConversion(stats?.scanCount ?? detail.scanCount, stats?.orderCount ?? detail.orderCount)}
/>
diff --git a/apps/admin-web/src/pages/promo/PromoCodeMetricsPanel.tsx b/apps/admin-web/src/pages/promo/PromoCodeMetricsPanel.tsx
index 213de9a..f62f1c7 100644
--- a/apps/admin-web/src/pages/promo/PromoCodeMetricsPanel.tsx
+++ b/apps/admin-web/src/pages/promo/PromoCodeMetricsPanel.tsx
@@ -234,7 +234,7 @@ export default function PromoCodeMetricsPanel({ promoId }: Props) {
style={{ marginTop: 16 }}
extra={
- 仅统计功能上线后的新事件
+ 仅统计功能上线后的新事件。扫码进入按人次(多次进入记多次);归因 / 注册按人(每人一次)。
}
>
diff --git a/apps/admin-web/src/pages/promo/PromoCodeUsersPage.tsx b/apps/admin-web/src/pages/promo/PromoCodeUsersPage.tsx
index 481964f..10acc8c 100644
--- a/apps/admin-web/src/pages/promo/PromoCodeUsersPage.tsx
+++ b/apps/admin-web/src/pages/promo/PromoCodeUsersPage.tsx
@@ -61,7 +61,11 @@ export default function PromoCodeUsersPage() {
render: (v) => (v === detail.id ? 本码 : v || '—'),
},
{
- title: '首次触达',
+ title: (
+
+ 首次触达
+
+ ),
dataIndex: 'firstTouchAt',
width: 160,
render: (v) => (v ? fmtTime(v) : '—'),
@@ -87,7 +91,10 @@ export default function PromoCodeUsersPage() {
return (
<>
{settingsModal}
-
+