From 19810e4519b175e752cc53d05f7a45c25ba10d6e Mon Sep 17 00:00:00 2001 From: Lxy Date: Fri, 13 Mar 2026 00:15:47 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=9B=91=E6=B5=8B=E9=A1=B5=E9=9D=A2=E6=89=93=E4=B8=8D=E5=BC=80?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B=E9=A1=B5=E9=9D=A2=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=8F=8A=E6=95=B0=E6=8D=AE=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E4=BE=9D=E7=84=B6=E5=AD=98=E5=9C=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/admin/pages/DataCheck.tsx | 64 ++++++++++++++---------------- app/src/admin/pages/DataImport.tsx | 4 +- app/src/services/adminApi.ts | 33 ++++++++++----- 3 files changed, 54 insertions(+), 47 deletions(-) diff --git a/app/src/admin/pages/DataCheck.tsx b/app/src/admin/pages/DataCheck.tsx index a3cfd75..d4d9814 100644 --- a/app/src/admin/pages/DataCheck.tsx +++ b/app/src/admin/pages/DataCheck.tsx @@ -259,18 +259,12 @@ export default function DataCheck() { }; // 计算统计数据(优先使用后端返回的 summary 数据) - const completionRate = summary?.completenessRate ?? (dataStatus.length > 0 - ? Math.round((dataStatus.filter(d => d.status === 'complete').length / dataStatus.length) * 100) - : 0); + // 新的 summary 格式: { stockCount, quoteCount, klineCount, localLatestDate, externalLatestDate, externalStatus, daysBehind, syncStatus } + const completionRate = summary?.syncStatus === 'complete' ? 100 : summary?.syncStatus === 'incomplete' ? 70 : 0; - const totalMissing = summary?.missingQuotesCount ?? dataStatus.reduce((acc, item) => { - if (item.status !== 'complete') { - return acc + (item.total - item.current); - } - return acc; - }, 0); + const totalMissing = summary?.daysBehind ?? 0; - const estimatedTime = Math.ceil(totalMissing / 1000); // 估算时间(分钟) + const estimatedTime = Math.ceil(totalMissing * 1000); // 估算时间(分钟) return (
@@ -336,7 +330,7 @@ export default function DataCheck() {

{currentTask && ( <> - 已处理: {currentTask.processedRecords.toLocaleString()} / {currentTask.totalRecords.toLocaleString()} + 已处理: {(currentTask.processedRecords || 0).toLocaleString()} / {(currentTask.totalRecords || 0).toLocaleString()} )}

@@ -473,15 +467,17 @@ export default function DataCheck() { >
-

数据完整度

-

{summary.completenessRate}%

+

数据同步状态

+

+ {summary.syncStatus === 'complete' ? '已同步' : summary.syncStatus === 'incomplete' ? '部分同步' : '未同步'} +

-
+
@@ -493,15 +489,15 @@ export default function DataCheck() { >
-

缺失数据条数

-

{summary.missingQuotesCount.toLocaleString()}

+

落后天数

+

{summary.daysBehind ?? '-'} 天

- {summary.missingQuotesCount > 0 ? '建议执行一键缓冲' : '数据完整无需缓冲'} + {summary.daysBehind && summary.daysBehind > 0 ? '建议执行一键缓冲' : '数据已同步'}

@@ -513,15 +509,17 @@ export default function DataCheck() { >
-

一年内可交易日

-

{summary.tradingDaysCount} 天

+

数据源状态

+

+ {summary.externalStatus === 'connected' ? '已连接' : summary.externalStatus === 'disabled' ? '未配置' : '异常'} +

- 参考日期: {summary.referenceDate}, 当日股票数: {summary.dailyStockCount}只 + 本地: {summary.localLatestDate || '无'}, 数据源: {summary.externalLatestDate || '无'}

@@ -537,28 +535,26 @@ export default function DataCheck() {

数据统计详情

-

预期数据条数

-

{summary.expectedTotalQuotes.toLocaleString()}

+

股票数量

+

{(summary.stockCount || 0).toLocaleString()}

-

实际数据条数

-

{summary.actualTotalQuotes.toLocaleString()}

+

行情记录数

+

{(summary.quoteCount || 0).toLocaleString()}

-

缺失数据条数

-

0 ? 'text-red-400' : 'text-green-400'}`}> - {summary.missingQuotesCount.toLocaleString()} +

落后天数

+

0 ? 'text-red-400' : 'text-green-400'}`}> + {summary.daysBehind ?? '-'} 天

-

数据完整度

-

= 90 ? 'text-green-400' : summary.completenessRate >= 50 ? 'text-yellow-400' : 'text-red-400'}`}> - {summary.completenessRate}% -

+

K线数据

+

{(summary.klineCount || 0).toLocaleString()}

- * 计算公式: 预期数据 = 单日股票数({summary.dailyStockCount}只) × 可交易日({summary.tradingDaysCount}天) = {summary.expectedTotalQuotes.toLocaleString()}条 + * 本地最新数据: {summary.localLatestDate || '无'}, 数据源最新: {summary.externalLatestDate || '无'}

)} @@ -635,11 +631,11 @@ export default function DataCheck() { />
- {((item.current / item.total) * 100).toFixed(1)}% + {item.total > 0 ? ((item.current / item.total) * 100).toFixed(1) : '0.0'}%

- {item.current.toLocaleString()} / {item.total.toLocaleString()} + {(item.current || 0).toLocaleString()} / {(item.total || 0).toLocaleString()}

{item.details && ( diff --git a/app/src/admin/pages/DataImport.tsx b/app/src/admin/pages/DataImport.tsx index 50ee730..bbc1053 100644 --- a/app/src/admin/pages/DataImport.tsx +++ b/app/src/admin/pages/DataImport.tsx @@ -320,9 +320,9 @@ export default function DataImport() {
{task.createdAt} 类型: {task.type} - {task.status !== 'pending' && task.totalRecords > 0 && ( + {task.status !== 'pending' && (task.totalRecords || 0) > 0 && ( - 记录: {task.importedRecords.toLocaleString()} / {task.totalRecords.toLocaleString()} + 记录: {(task.importedRecords || 0).toLocaleString()} / {(task.totalRecords || 0).toLocaleString()} )}
diff --git a/app/src/services/adminApi.ts b/app/src/services/adminApi.ts index 6acacb1..09aa61f 100644 --- a/app/src/services/adminApi.ts +++ b/app/src/services/adminApi.ts @@ -78,13 +78,23 @@ export interface DataCheckItem { // 数据检查结果汇总 export interface DataCheckSummary { - tradingDaysCount: number; - referenceDate: string; - dailyStockCount: number; - expectedTotalQuotes: number; - actualTotalQuotes: number; - missingQuotesCount: number; - completenessRate: number; + // 新的数据源对比格式 + stockCount?: number; + quoteCount?: number; + klineCount?: number; + localLatestDate?: string | null; + externalLatestDate?: string | null; + externalStatus?: 'connected' | 'disconnected' | 'error' | 'disabled'; + daysBehind?: number | null; + syncStatus?: 'complete' | 'incomplete' | 'missing'; + // 兼容旧格式 + tradingDaysCount?: number; + referenceDate?: string; + dailyStockCount?: number; + expectedTotalQuotes?: number; + actualTotalQuotes?: number; + missingQuotesCount?: number; + completenessRate?: number; } // 数据检查响应 @@ -98,13 +108,14 @@ export interface SyncTask { id: string; type: string; status: 'pending' | 'running' | 'completed' | 'failed'; - progress: number; - currentTask: string; - totalRecords: number; - processedRecords: number; + progress?: number; + currentTask?: string; + totalRecords?: number; + processedRecords?: number; createdAt: string; completedAt?: string; error?: string; + result?: any; } // 管理员 API