feat:添加mock接口
1. ✅ Profile 和 Settings 页面(2个文件) 2. ✅ EventDetail 页面(1个文件) 3. ✅ 身份验证组件(WechatRegister.js) 4. ✅ Company 页面(CompanyOverview, index, FinancialPanorama, MarketDataView) 5. ✅ Concept 页面(ConceptTimelineModal, ConceptStatsPanel, index)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { logger } from '../../utils/logger';
|
||||
import {
|
||||
Modal,
|
||||
ModalOverlay,
|
||||
@@ -111,13 +112,13 @@ const ConceptTimelineModal = ({
|
||||
`end_date=${endDateStr}`
|
||||
).then(res => {
|
||||
if (!res.ok) {
|
||||
console.error('Price API error:', res.status);
|
||||
logger.error('ConceptTimelineModal', 'fetchTimelineData - Price API', new Error(`HTTP ${res.status}`), { conceptId, startDateStr, endDateStr });
|
||||
throw new Error(`Price API error: ${res.status}`);
|
||||
}
|
||||
return res.json();
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Price API error:', err);
|
||||
logger.error('ConceptTimelineModal', 'fetchTimelineData - Price API', err, { conceptId });
|
||||
return { timeseries: [] };
|
||||
})
|
||||
);
|
||||
@@ -138,13 +139,13 @@ const ConceptTimelineModal = ({
|
||||
.then(async res => {
|
||||
if (!res.ok) {
|
||||
const text = await res.text();
|
||||
console.error('News API error:', res.status, text);
|
||||
logger.error('ConceptTimelineModal', 'fetchTimelineData - News API', new Error(`HTTP ${res.status}`), { conceptName, status: res.status, response: text.substring(0, 200) });
|
||||
return [];
|
||||
}
|
||||
return res.json();
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('News API error:', err);
|
||||
logger.error('ConceptTimelineModal', 'fetchTimelineData - News API', err, { conceptName });
|
||||
return [];
|
||||
})
|
||||
);
|
||||
@@ -165,13 +166,13 @@ const ConceptTimelineModal = ({
|
||||
.then(async res => {
|
||||
if (!res.ok) {
|
||||
const text = await res.text();
|
||||
console.error('Report API error:', res.status, text);
|
||||
logger.error('ConceptTimelineModal', 'fetchTimelineData - Report API', new Error(`HTTP ${res.status}`), { conceptName, status: res.status, response: text.substring(0, 200) });
|
||||
return { results: [] };
|
||||
}
|
||||
return res.json();
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Report API error:', err);
|
||||
logger.error('ConceptTimelineModal', 'fetchTimelineData - Report API', err, { conceptName });
|
||||
return { results: [] };
|
||||
})
|
||||
);
|
||||
@@ -296,15 +297,12 @@ const ConceptTimelineModal = ({
|
||||
|
||||
|
||||
setTimelineData(timeline);
|
||||
logger.info('ConceptTimelineModal', '时间轴数据加载成功', { conceptId, conceptName, timelineCount: timeline.length });
|
||||
} catch (error) {
|
||||
console.error('获取时间轴数据失败:', error);
|
||||
toast({
|
||||
title: '获取数据失败',
|
||||
description: error.message,
|
||||
status: 'error',
|
||||
duration: 3000,
|
||||
isClosable: true,
|
||||
});
|
||||
logger.error('ConceptTimelineModal', 'fetchTimelineData', error, { conceptId, conceptName });
|
||||
|
||||
// ❌ 移除获取数据失败toast
|
||||
// toast({ title: '获取数据失败', description: error.message, status: 'error', duration: 3000, isClosable: true });
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { logger } from '../../../utils/logger';
|
||||
import {
|
||||
Box,
|
||||
SimpleGrid,
|
||||
@@ -96,7 +97,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
|
||||
throw new Error(`Concept API错误: ${response.status}`);
|
||||
}
|
||||
} catch (conceptApiError) {
|
||||
console.warn('concept-api路由失败,尝试直接访问:', conceptApiError.message);
|
||||
logger.warn('ConceptStatsPanel', 'concept-api路由失败,尝试直接访问', { error: conceptApiError.message, days, startDate, endDate });
|
||||
|
||||
// 备用方案:直接访问concept_api服务(开发环境回退)
|
||||
try {
|
||||
@@ -105,6 +106,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
|
||||
result = await response.json();
|
||||
if (result.success && result.data) {
|
||||
setStatsData(result.data);
|
||||
logger.info('ConceptStatsPanel', '统计数据加载成功(备用API)', { dataKeys: Object.keys(result.data) });
|
||||
return;
|
||||
} else {
|
||||
throw new Error(result.note || '直接API返回错误');
|
||||
@@ -113,20 +115,16 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
|
||||
throw new Error(`直接API错误: ${response.status}`);
|
||||
}
|
||||
} catch (directError) {
|
||||
console.error('所有API都失败:', directError);
|
||||
logger.error('ConceptStatsPanel', '所有API都失败', directError, { days, startDate, endDate });
|
||||
throw new Error('无法访问概念统计API');
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('获取统计数据失败:', error);
|
||||
toast({
|
||||
title: '获取统计数据失败',
|
||||
description: '正在使用默认数据,请稍后刷新重试',
|
||||
status: 'warning',
|
||||
duration: 3000,
|
||||
isClosable: true,
|
||||
});
|
||||
logger.error('ConceptStatsPanel', 'fetchStatsData', error, { days, startDate, endDate });
|
||||
|
||||
// ❌ 移除获取统计数据失败toast
|
||||
// toast({ title: '获取统计数据失败', description: '正在使用默认数据,请稍后刷新重试', status: 'warning', duration: 3000, isClosable: true });
|
||||
|
||||
// 使用简化的默认数据作为最后的fallback
|
||||
setStatsData({
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { useSearchParams, useNavigate } from 'react-router-dom';
|
||||
import { logger } from '../../utils/logger';
|
||||
import {
|
||||
Box,
|
||||
Container,
|
||||
@@ -175,7 +176,7 @@ const ConceptCenter = () => {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取最新交易日期失败:', error);
|
||||
logger.error('ConceptCenter', 'fetchLatestTradeDate', error);
|
||||
}
|
||||
return null;
|
||||
}, []);
|
||||
@@ -286,17 +287,14 @@ const ConceptCenter = () => {
|
||||
setSelectedDate(new Date(data.price_date));
|
||||
}
|
||||
} catch (error) {
|
||||
toast({
|
||||
title: '获取数据失败',
|
||||
description: error.message,
|
||||
status: 'error',
|
||||
duration: 3000,
|
||||
isClosable: true,
|
||||
});
|
||||
logger.error('ConceptCenter', 'fetchConcepts', error, { query, page, date: date?.toISOString(), sortToUse });
|
||||
|
||||
// ❌ 移除获取数据失败toast
|
||||
// toast({ title: '获取数据失败', description: error.message, status: 'error', duration: 3000, isClosable: true });
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [pageSize, sortBy, toast]);
|
||||
}, [pageSize, sortBy]);
|
||||
|
||||
// 清除搜索
|
||||
const handleClearSearch = () => {
|
||||
@@ -401,7 +399,7 @@ const ConceptCenter = () => {
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`获取股票 ${seccode} 行情数据失败:`, error);
|
||||
logger.warn('ConceptCenter', `获取股票行情数据失败`, { stockCode: seccode, error: error.message });
|
||||
}
|
||||
return null;
|
||||
});
|
||||
@@ -413,10 +411,11 @@ const ConceptCenter = () => {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
setStockMarketData(newMarketData);
|
||||
logger.info('ConceptCenter', '股票行情数据批量加载完成', { totalStocks: stocks.length, loadedCount: Object.keys(newMarketData).length });
|
||||
} catch (error) {
|
||||
console.error('批量获取股票行情数据失败:', error);
|
||||
logger.error('ConceptCenter', 'fetchStockMarketData', error, { stockCount: stocks?.length });
|
||||
} finally {
|
||||
setLoadingStockData(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user