fix(api): 实现跨市场行情日期智能提取,确保历史价格时间戳绝对准确

This commit is contained in:
2026-05-01 21:48:50 +08:00
parent 371ac24c0e
commit f059aeb08f
2 changed files with 36 additions and 6 deletions
+27 -6
View File
@@ -14,7 +14,23 @@ function formatDateStr(date: Date): string {
return `${year}-${month}-${day}`;
}
async function fetchStockPrice(asset: { symbol: string; exchange: string | null }): Promise<string | null> {
function parseMarketDate(rawString: string): string {
const parts = rawString.split('~');
const rawDate = parts[30];
if (!rawDate) return new Date().toISOString().split('T')[0];
if (/^\d{14}$/.test(rawDate)) {
return `${rawDate.slice(0, 4)}-${rawDate.slice(4, 6)}-${rawDate.slice(6, 8)}`;
}
if (rawDate.includes('/')) {
return rawDate.split(' ')[0].replace(/\//g, '-');
}
return rawDate.split(' ')[0];
}
async function fetchStockPrice(asset: { symbol: string; exchange: string | null }): Promise<{ price: string | null; rawResponse: string | null }> {
const cleanSymbol = asset.symbol.trim().toUpperCase().replace(/[^0-9A-Z]/g, '');
let tCode: string;
@@ -44,10 +60,10 @@ async function fetchStockPrice(asset: { symbol: string; exchange: string | null
const dataArr = match[1].split('~');
const latestPrice = dataArr[3];
if (latestPrice && !isNaN(Number(latestPrice)) && Number(latestPrice) > 0) {
return latestPrice;
return { price: latestPrice, rawResponse: match[1] };
}
}
return null;
return { price: null, rawResponse: null };
}
async function fetchCryptoPrice(asset: { symbol: string }): Promise<string | null> {
@@ -113,9 +129,12 @@ export async function GET(req: Request) {
for (const asset of allAssets) {
try {
let price: string | null = null;
let rawResponse: string | null = null;
if (asset.type === 'STOCK') {
price = await fetchStockPrice(asset);
const result = await fetchStockPrice(asset);
price = result.price;
rawResponse = result.rawResponse;
} else if (asset.type === 'CRYPTO') {
price = await fetchCryptoPrice(asset);
}
@@ -127,6 +146,8 @@ export async function GET(req: Request) {
continue;
}
const entryDate = asset.type === 'STOCK' && rawResponse ? parseMarketDate(rawResponse) : dateStr;
const existing = await db
.select()
.from(assetPricesHistory)
@@ -134,7 +155,7 @@ export async function GET(req: Request) {
eq(assetPricesHistory.assetId, asset.id)
)
.then((rows) =>
rows.filter((row) => row.date === dateStr)
rows.filter((row) => row.date === entryDate)
);
if (existing.length > 0) {
@@ -152,7 +173,7 @@ export async function GET(req: Request) {
.values({
assetId: asset.id,
price,
date: dateStr,
date: entryDate,
});
syncedCount++;
results.push({ symbol: asset.symbol, price, status: 'inserted' });