102 lines
3.0 KiB
JavaScript
102 lines
3.0 KiB
JavaScript
import { EChart } from "../charts/EChart.jsx";
|
|
import { trendLabels } from "../data.js";
|
|
import { formatPercent, formatUsd } from "../format.js";
|
|
|
|
export function MoneyTrendPanel({ summary }) {
|
|
return (
|
|
<section className="money-analysis">
|
|
<article className="money-panel money-panel--chart">
|
|
<PanelHead label="充值与流水趋势" meta="近 7 日" value={formatUsd(summary.revenueUsd)} />
|
|
<EChart className="money-trend-chart" option={createTrendOption(summary)} />
|
|
</article>
|
|
<article className="money-panel money-panel--targets">
|
|
<PanelHead label="目标达成" meta="当日 / 当月" value={formatPercent(summary.monthProgress)} />
|
|
<ProgressRow label="当日充值" percent={summary.dayProgress} value={`${formatUsd(summary.rechargeUsd)} / ${formatUsd(summary.dayTargetUsd)}`} />
|
|
<ProgressRow label="当月充值" percent={summary.monthProgress} value={`${formatUsd(summary.monthActualUsd)} / ${formatUsd(summary.monthTargetUsd)}`} />
|
|
<div className="money-retention">
|
|
<span>次留 {formatPercent(summary.retention1)}</span>
|
|
<span>7日 {formatPercent(summary.retention7)}</span>
|
|
<span>30日 {formatPercent(summary.retention30)}</span>
|
|
</div>
|
|
</article>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
export function PanelHead({ label, meta, value }) {
|
|
return (
|
|
<div className="money-panel-head">
|
|
<div>
|
|
<h2>{label}</h2>
|
|
<span>{meta}</span>
|
|
</div>
|
|
<strong>{value}</strong>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function ProgressRow({ label, percent, value }) {
|
|
return (
|
|
<div className="money-progress">
|
|
<div>
|
|
<span>{label}</span>
|
|
<strong>{formatPercent(percent)}</strong>
|
|
</div>
|
|
<i>
|
|
<b style={{ width: `${Math.min(Number(percent) || 0, 100)}%` }} />
|
|
</i>
|
|
<small>{value}</small>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function createTrendOption(summary) {
|
|
return {
|
|
animationDuration: 520,
|
|
color: ["#2563eb", "#16a34a"],
|
|
grid: { bottom: 30, containLabel: true, left: 6, right: 16, top: 24 },
|
|
legend: {
|
|
bottom: 0,
|
|
icon: "roundRect",
|
|
itemHeight: 8,
|
|
itemWidth: 16,
|
|
textStyle: { color: "#64748b" }
|
|
},
|
|
tooltip: {
|
|
backgroundColor: "#ffffff",
|
|
borderColor: "#d8e0ec",
|
|
trigger: "axis",
|
|
textStyle: { color: "#0f172a" },
|
|
valueFormatter: (value) => formatUsd(value)
|
|
},
|
|
xAxis: {
|
|
axisLine: { lineStyle: { color: "rgba(100, 116, 139, 0.18)" } },
|
|
axisTick: { show: false },
|
|
data: trendLabels,
|
|
type: "category"
|
|
},
|
|
yAxis: {
|
|
axisLabel: { formatter: (value) => `${Math.round(value / 1000)}k` },
|
|
splitLine: { lineStyle: { color: "rgba(100, 116, 139, 0.16)" } },
|
|
type: "value"
|
|
},
|
|
series: [
|
|
{
|
|
areaStyle: { opacity: 0.12 },
|
|
data: summary.rechargeTrend,
|
|
name: "充值",
|
|
smooth: true,
|
|
symbol: "circle",
|
|
symbolSize: 6,
|
|
type: "line"
|
|
},
|
|
{
|
|
barMaxWidth: 18,
|
|
data: summary.revenueTrend,
|
|
name: "流水",
|
|
type: "bar"
|
|
}
|
|
]
|
|
};
|
|
}
|