feat: K线增加分钟/小时周期切换,拆分独立KLineCard组件

- 后端:腾讯 mkline 新增 /api/stock/history-minute(m1/m5/m15/m30/m60)
- 新组件 kline-card.tsx:自包含周期/折线蜡烛/指标开关与K线数据加载,
  切周期只重拉K线,不刷新页面其他模块
- 详情页瘦身为独立模块:K线图 / 今开最高最低昨收 / 每日行情明细互不耦合
- 时间统一按 UTC 解析传 Unix 秒,修复日线 invalid date/N/A 与分钟线时区问题
- 资金流向失败降级为非致命,不再导致整页报错
- vite 构建拆分 recharts/lightweight-charts/router 独立 chunk
This commit is contained in:
Sakurasan
2026-08-28 17:43:11 +08:00
parent c4ed3346ab
commit b1f216b2a4
8 changed files with 396 additions and 253 deletions
+41
View File
@@ -181,6 +181,47 @@ export async function fetchStockQuote(code: string): Promise<StockQuote | null>
}
}
/**
* 获取股票分钟/小时级K线数据
* @param code 股票代码(6位)
* @param period 周期:m1/m5/m15/m30/m60(60=小时线)
* @param count K线数量(默认320)
*/
export async function fetchStockHistoryMinute(
code: string,
period: "m1" | "m5" | "m15" | "m30" | "m60" = "m60",
count: number = 320,
): Promise<KLineData[]> {
if (!/^\d{6}$/.test(code)) {
throw new Error("股票代码格式错误,需为6位数字");
}
const baseUrl = getApiBaseUrl();
const url = `${baseUrl}/api/stock/history-minute?code=${code}&period=${period}&count=${count}`;
try {
const resp = await fetch(url, { method: "GET" });
if (!resp.ok) {
let errorMsg = `请求失败 (${resp.status})`;
try {
const errData = await resp.json();
errorMsg = errData.detail || errorMsg;
} catch {
// 忽略 JSON 解析错误
}
throw new Error(errorMsg);
}
const result = await resp.json();
if (!result.data || !Array.isArray(result.data)) {
throw new Error(result.detail || "未获取到分钟K线数据");
}
return result.data as KLineData[];
} catch (err) {
console.error("[stock-api] 获取分钟K线数据失败:", err);
return [];
}
}
/**
* 获取股票历史K线数据(通过Edge Function代理腾讯财经API)
* @param code 股票代码(6位)