K线图修复时间轴排序问题 & 行情指标合并到顶部卡片

- 修复K线图tickDates排序忽略年份导致跨年时期轴从右往左的问题
- 将行情指标(PE/PB/ROE/换手率/成交额/市值)合并到顶部股票信息卡片

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Sakurasan
2026-07-13 15:10:43 +08:00
co-authored by Claude
parent 60eff4a955
commit aaa618b15d
+45 -52
View File
@@ -351,12 +351,8 @@ function StockDetail() {
ticks.push(added);
}
ticks.push(last);
return [...new Set(ticks)].sort((a, b) => {
// 按日期排序(MM/DD格式需按MM和DD比较)
const [am, ad] = a.split('/').map(Number);
const [bm, bd] = b.split('/').map(Number);
return am - bm || ad - bd;
});
// 保持chartData的原始顺序(已按日期升序排列),不做二次排序
return [...new Set(ticks)];
})();
// 东方财富市场标识:0=深圳(000/002/300), 1=上海(60), 6=科创板(688)
@@ -467,6 +463,48 @@ function StockDetail() {
)}
</div>
</div>
{/* 行情指标合并到顶部卡片 */}
<div className="mt-4 md:mt-5 pt-4 md:pt-5 border-t border-border/50">
<div className="grid grid-cols-2 md:grid-cols-4 gap-2 md:gap-3">
<div className="text-center p-2 md:p-3 rounded-lg bg-muted/30">
<p className="text-[10px] md:text-xs text-muted-foreground mb-0.5">(PE)</p>
<p className="text-sm md:text-base font-semibold">{stockInfo.pe > 0 ? stockInfo.pe.toFixed(2) : '-'}</p>
</div>
<div className="text-center p-2 md:p-3 rounded-lg bg-muted/30">
<p className="text-[10px] md:text-xs text-muted-foreground mb-0.5">(PB)</p>
<p className="text-sm md:text-base font-semibold">{stockInfo.pb > 0 ? stockInfo.pb.toFixed(2) : '-'}</p>
</div>
<div className="text-center p-2 md:p-3 rounded-lg bg-muted/30">
<p className="text-[10px] md:text-xs text-muted-foreground mb-0.5">ROE</p>
<p className={`text-sm md:text-base font-semibold ${latestROE !== null ? (latestROE > 0 ? 'text-red-500' : 'text-green-500') : ''}`}>
{latestROE !== null ? `${latestROE.toFixed(2)}%` : '加载中...'}
</p>
</div>
<div className="text-center p-2 md:p-3 rounded-lg bg-muted/30">
<p className="text-[10px] md:text-xs text-muted-foreground mb-0.5"></p>
<p className="text-sm md:text-base font-semibold">{stockInfo.turnoverRate > 0 ? `${stockInfo.turnoverRate}%` : '-'}</p>
</div>
<div className="text-center p-2 md:p-3 rounded-lg bg-muted/30">
<p className="text-[10px] md:text-xs text-muted-foreground mb-0.5"></p>
<p className="text-sm md:text-base font-semibold">
{stockInfo.volume > 0 ? `${(stockInfo.volume / 100).toLocaleString()}` : '-'}
</p>
</div>
<div className="text-center p-2 md:p-3 rounded-lg bg-muted/30">
<p className="text-[10px] md:text-xs text-muted-foreground mb-0.5"></p>
<p className="text-sm md:text-base font-semibold">{formatMoney(stockInfo.amount)}</p>
</div>
<div className="text-center p-2 md:p-3 rounded-lg bg-muted/30">
<p className="text-[10px] md:text-xs text-muted-foreground mb-0.5"></p>
<p className="text-sm md:text-base font-semibold">{stockInfo.totalMarketCap > 0 ? formatMoney(stockInfo.totalMarketCap) : '-'}</p>
</div>
<div className="text-center p-2 md:p-3 rounded-lg bg-muted/30">
<p className="text-[10px] md:text-xs text-muted-foreground mb-0.5"></p>
<p className="text-sm md:text-base font-semibold">{stockInfo.circulatingMarketCap > 0 ? formatMoney(stockInfo.circulatingMarketCap) : '-'}</p>
</div>
</div>
</div>
</CardContent>
</Card>
@@ -673,52 +711,7 @@ function StockDetail() {
</Card>
</div>
{/* 行情指标:PE / PB / ROE / 换手率 / 总手 / 成交额 / 市值 */}
<Card className="mt-4 md:mt-6 shadow-lg">
<CardHeader className="pb-2 md:pb-4 px-3 md:px-6 pt-4 md:pt-6">
<CardTitle className="text-base md:text-lg"></CardTitle>
</CardHeader>
<CardContent className="px-3 md:px-6 pb-3 md:pb-6">
<div className="grid grid-cols-2 md:grid-cols-4 gap-3 md:gap-4">
<div className="text-center p-3 rounded-lg bg-muted/30">
<p className="text-xs text-muted-foreground mb-1">(PE)</p>
<p className="text-lg font-semibold">{stockInfo.pe > 0 ? stockInfo.pe.toFixed(2) : '-'}</p>
</div>
<div className="text-center p-3 rounded-lg bg-muted/30">
<p className="text-xs text-muted-foreground mb-1">(PB)</p>
<p className="text-lg font-semibold">{stockInfo.pb > 0 ? stockInfo.pb.toFixed(2) : '-'}</p>
</div>
<div className="text-center p-3 rounded-lg bg-muted/30">
<p className="text-xs text-muted-foreground mb-1">ROE()</p>
<p className={`text-lg font-semibold ${latestROE !== null ? (latestROE > 0 ? 'text-red-500' : 'text-green-500') : ''}`}>
{latestROE !== null ? `${latestROE.toFixed(2)}%` : '加载中...'}
</p>
</div>
<div className="text-center p-3 rounded-lg bg-muted/30">
<p className="text-xs text-muted-foreground mb-1"></p>
<p className="text-lg font-semibold">{stockInfo.turnoverRate > 0 ? `${stockInfo.turnoverRate}%` : '-'}</p>
</div>
<div className="text-center p-3 rounded-lg bg-muted/30">
<p className="text-xs text-muted-foreground mb-1"></p>
<p className="text-lg font-semibold">
{stockInfo.volume > 0 ? `${(stockInfo.volume / 100).toLocaleString()}` : '-'}
</p>
</div>
<div className="text-center p-3 rounded-lg bg-muted/30">
<p className="text-xs text-muted-foreground mb-1"></p>
<p className="text-lg font-semibold">{formatMoney(stockInfo.amount)}</p>
</div>
<div className="text-center p-3 rounded-lg bg-muted/30">
<p className="text-xs text-muted-foreground mb-1"></p>
<p className="text-lg font-semibold">{stockInfo.totalMarketCap > 0 ? formatMoney(stockInfo.totalMarketCap) : '-'}</p>
</div>
<div className="text-center p-3 rounded-lg bg-muted/30">
<p className="text-xs text-muted-foreground mb-1"></p>
<p className="text-lg font-semibold">{stockInfo.circulatingMarketCap > 0 ? formatMoney(stockInfo.circulatingMarketCap) : '-'}</p>
</div>
</div>
</CardContent>
</Card>
{/* Daily Data Table - Independent from fund flow */}
{chartData.length > 0 && (