fix(api): 实现跨市场行情日期智能提取,确保历史价格时间戳绝对准确
This commit is contained in:
@@ -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' });
|
||||
|
||||
Reference in New Issue
Block a user