feat: 提交迷你分时图组件

This commit is contained in:
zdl
2025-11-02 16:38:44 +08:00
parent e22a39c5cd
commit e7e2b3bb11
2 changed files with 23 additions and 11 deletions

View File

@@ -15,9 +15,10 @@ import {
*
* @param {string} stockCode - 股票代码
* @param {string} eventTime - 事件时间(可选)
* @param {Function} onClick - 点击回调(可选)
* @returns {JSX.Element}
*/
const MiniTimelineChart = React.memo(function MiniTimelineChart({ stockCode, eventTime }) {
const MiniTimelineChart = React.memo(function MiniTimelineChart({ stockCode, eventTime, onClick }) {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const mountedRef = useRef(true);
@@ -162,7 +163,14 @@ const MiniTimelineChart = React.memo(function MiniTimelineChart({ stockCode, eve
}, [data, loading, stableEventTime]);
return (
<div style={{ width: 140, height: 40 }}>
<div
style={{
width: 140,
height: 40,
cursor: onClick ? 'pointer' : 'default'
}}
onClick={onClick}
>
<ReactECharts
option={chartOption}
style={{ width: '100%', height: '100%' }}
@@ -172,9 +180,10 @@ const MiniTimelineChart = React.memo(function MiniTimelineChart({ stockCode, eve
</div>
);
}, (prevProps, nextProps) => {
// 自定义比较函数只有当stockCodeeventTime变化时才重新渲染
// 自定义比较函数只有当stockCodeeventTime或onClick变化时才重新渲染
return prevProps.stockCode === nextProps.stockCode &&
prevProps.eventTime === nextProps.eventTime;
prevProps.eventTime === nextProps.eventTime &&
prevProps.onClick === nextProps.onClick;
});
export default MiniTimelineChart;

View File

@@ -15,11 +15,12 @@ const REQUEST_INTERVAL = 30000; // 30秒内不重复请求同一只股票的数
* 获取缓存键
* @param {string} stockCode - 股票代码
* @param {string} eventTime - 事件时间
* @param {string} chartType - 图表类型timeline/daily
* @returns {string} 缓存键
*/
export const getCacheKey = (stockCode, eventTime) => {
export const getCacheKey = (stockCode, eventTime, chartType = 'timeline') => {
const date = eventTime ? moment(eventTime).format('YYYY-MM-DD') : moment().format('YYYY-MM-DD');
return `${stockCode}|${date}`;
return `${stockCode}|${date}|${chartType}`;
};
/**
@@ -52,10 +53,11 @@ export const shouldRefreshData = (cacheKey) => {
* 获取K线数据带缓存和防重复请求
* @param {string} stockCode - 股票代码
* @param {string} eventTime - 事件时间
* @param {string} chartType - 图表类型timeline/daily
* @returns {Promise<Array>} K线数据
*/
export const fetchKlineData = async (stockCode, eventTime) => {
const cacheKey = getCacheKey(stockCode, eventTime);
export const fetchKlineData = async (stockCode, eventTime, chartType = 'timeline') => {
const cacheKey = getCacheKey(stockCode, eventTime, chartType);
// 1. 检查缓存
if (klineDataCache.has(cacheKey)) {
@@ -73,10 +75,10 @@ export const fetchKlineData = async (stockCode, eventTime) => {
}
// 3. 发起新请求
logger.debug('klineDataCache', '发起新K线数据请求', { cacheKey });
logger.debug('klineDataCache', '发起新K线数据请求', { cacheKey, chartType });
const normalizedEventTime = eventTime ? moment(eventTime).format('YYYY-MM-DD HH:mm') : undefined;
const requestPromise = stockService
.getKlineData(stockCode, 'timeline', normalizedEventTime)
.getKlineData(stockCode, chartType, normalizedEventTime)
.then((res) => {
const data = Array.isArray(res?.data) ? res.data : [];
// 更新缓存
@@ -86,12 +88,13 @@ export const fetchKlineData = async (stockCode, eventTime) => {
pendingRequests.delete(cacheKey);
logger.debug('klineDataCache', 'K线数据请求完成并缓存', {
cacheKey,
chartType,
dataPoints: data.length
});
return data;
})
.catch((error) => {
logger.error('klineDataCache', 'fetchKlineData', error, { stockCode, cacheKey });
logger.error('klineDataCache', 'fetchKlineData', error, { stockCode, chartType, cacheKey });
// 清除pending状态
pendingRequests.delete(cacheKey);
// 如果有旧缓存,返回旧数据