Skip to content

Commit 273242f

Browse files
committed
修复中转站余额趋势方向错误
1 parent 430bee1 commit 273242f

1 file changed

Lines changed: 24 additions & 23 deletions

File tree

app/(dashboard)/stations/page.tsx

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// 中转站管理页:站点列表 + 添加/编辑弹窗 + 单站刷新/删除 + 余额趋势详情弹窗
33
// 功能对照 v1 app.js:renderStations/stationRow(553-586、193-288)、站点表单弹窗(1487-1614)、
44
// 趋势弹窗 openTrend/drawChart(1675-1822)——文案与数字口径逐条对齐,布局用 Pro 风格重排
5-
import { useCallback, useEffect, useMemo, useState } from "react";
5+
import { useCallback, useEffect, useState } from "react";
66
import { PageContainer, ProCard } from "@ant-design/pro-components";
77
import {
88
App,
@@ -25,12 +25,10 @@ import {
2525
DeleteOutlined,
2626
CloseOutlined,
2727
} from "@ant-design/icons";
28-
import { Line } from "@ant-design/plots";
2928
import TrendModal from "../trend-modal";
3029
import LastRefreshed from "../last-refreshed";
3130
import dayjs from "dayjs";
3231
import { api, cny, usd, rateOf, fmtTokens, fmtEta, statusOf } from "../../../lib/client";
33-
import { useThemeMode } from "../../providers";
3432

3533
// ---- 展示工具(v1 app.js 同名函数平移)--------------------------------------
3634
const PLATE: Record<string, string> = { newapi: "NA", "newapi-key": "KEY", sub2api: "S2", "sub2api-password": "S2" };
@@ -86,28 +84,31 @@ const hintStyle = (token: ReturnType<typeof theme.useToken>["token"]): React.CSS
8684
lineHeight: 1.6,
8785
});
8886

89-
// ---- 迷你余额走势(近 48 小时,v1 sparkSvg 的 plots 版)-----------------------
90-
function Spark({ pts }: { pts: any[] }) {
91-
const { dark } = useThemeMode();
92-
const data = useMemo(() => (pts || []).map((p: any) => ({ date: new Date(p[0]), v: p[1] })), [pts]);
87+
// ---- 迷你余额走势(近 48 小时,与总览卡片使用相同坐标口径)--------------------
88+
function Spark({ pts }: { pts: [number, number][] }) {
89+
const { token } = theme.useToken();
9390
if (!pts || pts.length < 2) return null;
91+
92+
const W = 170, H = 30, P = 3;
93+
const t0 = pts[0][0], t1 = pts[pts.length - 1][0];
94+
let min = Infinity, max = -Infinity;
95+
for (const [, v] of pts) {
96+
if (v < min) min = v;
97+
if (v > max) max = v;
98+
}
99+
if (max - min < 1e-9) { min -= 1; max += 1; }
100+
const x = (t: number) => P + ((t - t0) / (t1 - t0 || 1)) * (W - 2 * P);
101+
const y = (v: number) => P + (1 - (v - min) / (max - min)) * (H - 2 * P);
102+
const line = pts.map((p, i) => `${i ? "L" : "M"}${x(p[0]).toFixed(1)},${y(p[1]).toFixed(1)}`).join("");
103+
const area = `${line}L${x(t1).toFixed(1)},${H - P}L${x(t0).toFixed(1)},${H - P}Z`;
104+
const last = pts[pts.length - 1];
105+
94106
return (
95-
<div style={{ width: 170, maxWidth: "100%", height: 30, overflow: "hidden" }}>
96-
<Line
97-
data={data}
98-
xField="date"
99-
yField="v"
100-
width={170}
101-
height={30}
102-
axis={false}
103-
legend={false}
104-
tooltip={false}
105-
animate={false}
106-
padding={3}
107-
theme={dark ? "classicDark" : "classic"}
108-
style={{ lineWidth: 1.5 }}
109-
/>
110-
</div>
107+
<svg viewBox={`0 0 ${W} ${H}`} width={170} height={30} aria-hidden="true" style={{ display: "block", maxWidth: "100%" }}>
108+
<path d={area} fill={token.colorPrimaryBg} />
109+
<path d={line} fill="none" stroke={token.colorPrimary} strokeWidth={1.5} />
110+
<circle cx={x(last[0]).toFixed(1)} cy={y(last[1]).toFixed(1)} r={2.5} fill={token.colorPrimary} />
111+
</svg>
111112
);
112113
}
113114

0 commit comments

Comments
 (0)