import { EMPTY_RECHARGE_OVERVIEW, EMPTY_RECHARGE_SUMMARY, formatAmount, formatUsdMinor } from "../format.js"; const KPI_CARDS = [ { filter: "", key: "total", label: "充值总和", tone: "total" }, { filter: "google_play_recharge", key: "googlePlay", label: "谷歌充值", tone: "google" }, { filter: "third_party", key: "thirdParty", label: "三方充值", tone: "thirdparty" }, { filter: "coin_seller", key: "coinSeller", label: "币商充值", tone: "coinseller" }, ]; const DAILY_FIELDS = { coinSeller: { coin: "coinSellerCoinAmount", usd: "coinSellerUsdMinor" }, googlePlay: { coin: "googleCoinAmount", usd: "googleUsdMinor" }, thirdParty: { coin: "thirdPartyCoinAmount", usd: "thirdPartyUsdMinor" }, }; export function FinanceOverview({ currency, filters, loading, onFiltersChange, onGoUnsynced, onOpenApp, onOpenWithdrawals, overview, perAppSummaries, prevSummary, regions, summary, }) { const data = summary || EMPTY_RECHARGE_SUMMARY; const trend = overview || EMPTY_RECHARGE_OVERVIEW; const showCoins = currency === "coin"; const totalUsd = Number(data.total?.usdMinorAmount) || 0; const unsynced = trend.googlePaid.unsyncedCount; const selectedApp = filters.appCode; return (
{unsynced > 0 ? (
⚠ {formatAmount(unsynced)} 笔谷歌订单实付未同步,手续费口径尚不完整
) : null}
{KPI_CARDS.map(({ filter, key, label, tone }) => { const bucket = data[key] || { billCount: 0, coinAmount: 0, usdMinorAmount: 0 }; const active = (filters.rechargeType || "") === filter; return ( ); })}
充值趋势按渠道堆叠 · 日 · {showCoins ? "金币" : "USD"}
谷歌 三方 币商
净入账拆解谷歌已同步口径
{selectedApp ? "区域分布 Top 5" : "区域分布"}
{selectedApp ? ( ) : (

选择单个 App 后查看区域分布

)}
App 对比点击行进入该 App 流水
{(perAppSummaries || []).map((app) => { const appTotal = Number(app.summary?.total?.usdMinorAmount) || 0; const maxTotal = Math.max( 1, ...(perAppSummaries || []).map( (item) => Number(item.summary?.total?.usdMinorAmount) || 0, ), ); return ( onOpenApp(app.appCode)} > ); })} {!perAppSummaries?.length ? ( ) : null}
App 充值流水 笔数 谷歌 三方 币商 占比
{app.appName || app.appCode} {formatUsdMinor(appTotal, "USD")} {formatAmount(app.summary?.total?.billCount || 0)} {formatUsdMinor(app.summary?.googlePlay?.usdMinorAmount || 0, "USD")} {formatUsdMinor(app.summary?.thirdParty?.usdMinorAmount || 0, "USD")} {formatUsdMinor(app.summary?.coinSeller?.usdMinorAmount || 0, "USD")}
暂无数据
); } // WithdrawalKpi 是两张独立口径的资金流出卡: // 「用户提现」只统计提现申请审核通过的 USDT(点击进入提现审核页); // 「工资兑换」只统计用户工资转币商的 USDT(likei 平台为银行卡余额兑换金币)。 // 两者都不是充值渠道,不参与来源筛选联动,占比按“金额 / 充值总和”表达资金回流强度。 function WithdrawalKpi({ loading, onOpenWithdrawals, totalUsd, withdrawal }) { const data = withdrawal || { approvedCount: 0, approvedUsdMinor: 0, totalUsdMinor: 0, transferCount: 0, transferUsdMinor: 0, }; return ( <>
工资兑换 {loading ? "…" : usdtText(data.transferUsdMinor)} {loading ? "统计中" : outflowMeta(data.transferUsdMinor, data.transferCount, totalUsd)} 用户工资转币商
); } function usdtText(usdMinor) { return `USDT ${(usdMinor / 100).toLocaleString("zh-CN", { maximumFractionDigits: 2, minimumFractionDigits: 2 })}`; } function outflowMeta(usdMinor, count, totalUsd) { const parts = []; if (totalUsd > 0) { const share = (usdMinor / totalUsd) * 100; parts.push(`占充值 ${share.toLocaleString("zh-CN", { maximumFractionDigits: 1 })}%`); } parts.push(`${formatAmount(count)} 笔`); return parts.join(" · "); } function kpiMeta(bucket, key, totalUsd, prevSummary) { const parts = [`${formatAmount(bucket.billCount)} 笔`]; if (key !== "total" && totalUsd > 0) { const share = ((Number(bucket.usdMinorAmount) || 0) / totalUsd) * 100; parts.push(`占比 ${share.toLocaleString("zh-CN", { maximumFractionDigits: 1 })}%`); } const prev = prevSummary?.[key]; if (prev && Number(prev.usdMinorAmount) > 0) { const delta = ((Number(bucket.usdMinorAmount) - Number(prev.usdMinorAmount)) / Number(prev.usdMinorAmount)) * 100; const arrow = delta >= 0 ? "▲" : "▼"; parts.push(`${arrow} ${Math.abs(delta).toLocaleString("zh-CN", { maximumFractionDigits: 1 })}% vs 上期`); } return parts.join(" · "); } function Sparkline({ daily, field, showCoins, tone }) { const values = (daily || []).map((bucket) => { if (field === "total") { return showCoins ? bucket.googleCoinAmount + bucket.thirdPartyCoinAmount + bucket.coinSellerCoinAmount : bucket.googleUsdMinor + bucket.thirdPartyUsdMinor + bucket.coinSellerUsdMinor; } const fields = DAILY_FIELDS[field]; return fields ? bucket[showCoins ? fields.coin : fields.usd] : 0; }); if (values.length < 2) { return ; } const width = 100; const height = 28; const max = Math.max(...values); const min = Math.min(...values); const points = values.map((value, index) => { const x = (index * width) / (values.length - 1); const y = height - 3 - ((value - min) / (max - min || 1)) * (height - 8); return `${x.toFixed(1)},${y.toFixed(1)}`; }); const colors = { coinseller: "#B45309", google: "#1B873F", thirdparty: "#0E7490", total: "#2557D6", }; const color = colors[tone] || colors.total; return ( ); } function TrendChart({ daily, showCoins }) { const buckets = daily || []; if (!buckets.length) { return

当前时间范围内没有充值数据

; } const totals = buckets.map((bucket) => showCoins ? bucket.googleCoinAmount + bucket.thirdPartyCoinAmount + bucket.coinSellerCoinAmount : bucket.googleUsdMinor + bucket.thirdPartyUsdMinor + bucket.coinSellerUsdMinor, ); const max = Math.max(1, ...totals); const value = (bucket, channel) => { const fields = DAILY_FIELDS[channel]; return bucket[showCoins ? fields.coin : fields.usd]; }; return (
{buckets.map((bucket) => (
{["googlePlay", "thirdParty", "coinSeller"].map((channel) => { const amount = value(bucket, channel); if (amount <= 0) { return null; } return ( ); })}
))}
{buckets[0].date.slice(5)} {buckets.length > 2 ? {buckets[Math.floor(buckets.length / 2)].date.slice(5)} : null} {buckets[buckets.length - 1].date.slice(5)}
); } function trendTip(bucket, channel, showCoins) { const fields = DAILY_FIELDS[channel]; const amount = bucket[showCoins ? fields.coin : fields.usd]; return showCoins ? formatAmount(amount) : formatUsdMinor(amount, "USD"); } function DeductionBreakdown({ paid }) { const covered = paid.coveredUsdMinor; if (covered <= 0) { return (

暂无已同步的谷歌实付明细;点「查询谷歌实付」同步后这里会展示手续费与税费拆解。

); } const rows = [ { amount: paid.estNetUsdMinor, color: "var(--fin-pos)", label: "净入账(估)" }, { amount: paid.estFeeUsdMinor, color: "#E19B3C", label: "谷歌服务费(估)" }, { amount: paid.estTaxUsdMinor, color: "#C86A6A", label: "代缴税费(估)" }, ]; return (
{rows.map((row) => ( ))}
{rows.map((row) => (
{row.label} {formatUsdMinor(row.amount, "USD")} {((row.amount / covered) * 100).toLocaleString("zh-CN", { maximumFractionDigits: 1 })}%
))}

口径:已同步 {formatAmount(paid.syncedCount)} / {formatAmount(paid.googleBillCount)}{" "} 笔谷歌订单,覆盖流水 {formatUsdMinor(covered, "USD")};按各订单实付占比折算成 USD

); } function RegionRanks({ regions }) { const top = (regions || []).slice(0, 5); if (!top.length) { return

当前筛选下暂无区域数据

; } const max = Math.max(1, ...top.map((region) => region.usdMinorAmount)); return (
{top.map((region, index) => (
{index + 1} {region.name || `区域 ${region.regionId}`} {formatUsdMinor(region.usdMinorAmount, "USD")}
))}
); }