From 101102e60cac3a06f612590d656688677012d398 Mon Sep 17 00:00:00 2001 From: linkeyu <798648091@qq.com> Date: Sat, 1 Aug 2026 13:52:22 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=E5=AF=B9=E9=BD=90=E9=A2=86=E5=88=B8?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E7=8E=87=E5=88=86=E6=AF=8D=E5=8F=A3=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(main)/dashboard/page.tsx | 9 ++++++--- src/lib/types.ts | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/app/(main)/dashboard/page.tsx b/src/app/(main)/dashboard/page.tsx index d84b9d4..edee557 100644 --- a/src/app/(main)/dashboard/page.tsx +++ b/src/app/(main)/dashboard/page.tsx @@ -550,6 +550,7 @@ export default function DashboardPage() { const couponPeriod = periodData?.coupon ?? null; const previousCouponPeriod = previousPeriodData?.coupon ?? null; const couponStartedDelta = percentDelta(couponPeriod?.started, previousCouponPeriod?.started); + const couponSuccessDenominator = couponPeriod?.success_denominator ?? null; const couponSuccessRateValue = couponPeriod?.success_rate == null ? '--' : (couponPeriod.success_rate * 100).toFixed(1); const couponSuccessRateDelta = pointDelta(couponPeriod?.success_rate, previousCouponPeriod?.success_rate); @@ -875,9 +876,11 @@ export default function DashboardPage() { unit="%" delta={couponSuccessRateDelta.value} deltaTone={couponSuccessRateDelta.tone} - hint={`全部点位领成功的次数 / 领券发起数;本期 ${fmtInt(couponPeriod?.all_success)} / ${fmtInt( - couponPeriod?.started, - )} 次。点位成功口径含「今日已领过」。`} + hint={`全部点位领成功的次数 ÷(领券发起数-中途退出数);本期 ${fmtInt( + couponPeriod?.all_success, + )} ÷(${fmtInt(couponPeriod?.started)}-${fmtInt(couponPeriod?.abandoned)}),分母为 ${fmtInt( + couponSuccessDenominator, + )}。中途退出不计入分母,点位成功口径含「今日已领过」。`} /> Date: Sat, 1 Aug 2026 14:06:46 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=E5=B1=95=E7=A4=BA=E4=B8=AD=E9=80=94?= =?UTF-8?q?=E9=80=80=E5=87=BA=E6=97=A0=E7=BB=93=E6=9E=9C=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(main)/coupon-data/page.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/app/(main)/coupon-data/page.tsx b/src/app/(main)/coupon-data/page.tsx index 8f4ed8f..37ca3a8 100644 --- a/src/app/(main)/coupon-data/page.tsx +++ b/src/app/(main)/coupon-data/page.tsx @@ -145,6 +145,15 @@ function PointScorePopover({ row }: { row: CouponDataRow }) { const [loading, setLoading] = useState(false); const [loadError, setLoadError] = useState(null); + const abandonedWithoutPointResult = + row.status === 'abandoned' && row.point_success_count === 0 && row.point_total_count === 0; + if (abandonedWithoutPointResult) { + return ( + + 0.0%(退出前无结果) + + ); + } if (row.point_success_count == null || row.point_total_count == null || row.point_total_count <= 0) { return -; } -- 2.52.0 From b8363b31aba76cff57d8ce1a390a894c28862e48 Mon Sep 17 00:00:00 2001 From: linkeyu <798648091@qq.com> Date: Sat, 1 Aug 2026 14:12:30 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=E4=BF=9D=E7=95=99=E8=B7=B3=E8=BF=87?= =?UTF-8?q?=E5=8D=95=E5=88=B8=E6=98=8E=E7=BB=86=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(main)/coupon-data/page.tsx | 33 +++++++++++++++++------------ 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/app/(main)/coupon-data/page.tsx b/src/app/(main)/coupon-data/page.tsx index 37ca3a8..1258b7c 100644 --- a/src/app/(main)/coupon-data/page.tsx +++ b/src/app/(main)/coupon-data/page.tsx @@ -76,6 +76,7 @@ interface CouponDataRow { claimed_count: number | null; point_success_count: number | null; point_total_count: number | null; + point_event_count?: number; // 兼容旧后端的内嵌明细;新后端不再返回,改为点击后按 trace 加载。 point_details?: CouponPointDetail[]; trace_url: string | null; @@ -145,24 +146,22 @@ function PointScorePopover({ row }: { row: CouponDataRow }) { const [loading, setLoading] = useState(false); const [loadError, setLoadError] = useState(null); - const abandonedWithoutPointResult = + const abandonedWithoutScoredResult = row.status === 'abandoned' && row.point_success_count === 0 && row.point_total_count === 0; - if (abandonedWithoutPointResult) { - return ( - - 0.0%(退出前无结果) - - ); - } - if (row.point_success_count == null || row.point_total_count == null || row.point_total_count <= 0) { + if ( + row.point_success_count == null || + row.point_total_count == null || + (row.point_total_count <= 0 && !abandonedWithoutScoredResult) + ) { return -; } const score = `${row.point_success_count}/${row.point_total_count}`; - const scoreWithRate = `${score}(${( - row.point_success_count / row.point_total_count * 100 - ).toFixed(1)}%)`; + const hasPointDetails = (row.point_event_count ?? 0) > 0; + const scoreWithRate = abandonedWithoutScoredResult + ? `0.0%(${hasPointDetails ? '无有效结果' : '退出前无结果'})` + : `${score}(${(row.point_success_count / row.point_total_count * 100).toFixed(1)}%)`; const scoreColor = - row.point_success_count === row.point_total_count + row.point_total_count > 0 && row.point_success_count === row.point_total_count ? STATUS_TAG.completed.color : STATUS_TAG.abandoned.color; const loadDetails = async () => { @@ -183,6 +182,14 @@ function PointScorePopover({ row }: { row: CouponDataRow }) { } }; + if (abandonedWithoutScoredResult && !hasPointDetails) { + return ( + + {scoreWithRate} + + ); + } + return (