community增加事件详情

This commit is contained in:
2026-01-07 16:33:30 +08:00
parent 9b42c2c7c2
commit 131e92b0b9
3 changed files with 324 additions and 149 deletions

View File

@@ -2316,174 +2316,44 @@ const CombinedCalendar = () => {
const [currentMonth, setCurrentMonth] = useState(new Date());
const [selectedDate, setSelectedDate] = useState(null);
// 涨停数据
const [ztDatesData, setZtDatesData] = useState([]);
// 日历综合数据(涨停 + 事件 + 上证涨跌幅)- 使用新的综合 API
const [calendarData, setCalendarData] = useState([]);
const [ztDailyDetails, setZtDailyDetails] = useState({});
const [selectedZtDetail, setSelectedZtDetail] = useState(null);
// 投资日历数据
const [eventCounts, setEventCounts] = useState([]);
const [selectedEvents, setSelectedEvents] = useState([]);
// 上证指数涨跌幅数据
const [indexChangeMap, setIndexChangeMap] = useState({});
const [detailLoading, setDetailLoading] = useState(false);
const [modalOpen, setModalOpen] = useState(false);
// 加载涨停 dates.json
// 加载日历综合数据(一次 API 调用获取所有数据)
useEffect(() => {
const loadZtDatesData = async () => {
try {
const response = await fetch('/data/zt/dates.json');
if (response.ok) {
const data = await response.json();
setZtDatesData(data.dates || []);
}
} catch (error) {
console.error('Failed to load zt dates.json:', error);
}
};
loadZtDatesData();
}, []);
// 加载投资日历事件数量
useEffect(() => {
const loadEventCounts = async () => {
const loadCalendarCombinedData = async () => {
try {
const year = currentMonth.getFullYear();
const month = currentMonth.getMonth() + 1;
const response = await eventService.calendar.getEventCounts(year, month);
if (response.success) {
setEventCounts(response.data || []);
}
} catch (error) {
console.error('Failed to load event counts:', error);
}
};
loadEventCounts();
}, [currentMonth]);
// 加载上证指数历史涨跌幅数据
useEffect(() => {
const loadIndexData = async () => {
try {
const response = await fetch(`${getApiBase()}/api/index/000001.SH/kline?type=daily`);
const response = await fetch(`${getApiBase()}/api/v1/calendar/combined-data?year=${year}&month=${month}`);
if (response.ok) {
const result = await response.json();
// API 直接返回 { code, name, data, ... },没有 success 字段
if (result.data && Array.isArray(result.data)) {
// 构建日期到涨跌幅的映射
const changeMap = {};
result.data.forEach(item => {
// API返回的是 time 字段(不是 date格式是 YYYY-MM-DD转为 YYYYMMDD
const dateField = item.time || item.date;
if (!dateField) return;
const yyyymmdd = dateField.replace(/-/g, '');
// 计算涨跌幅 = (close - prev_close) / prev_close * 100
if (item.close && item.prev_close) {
const change = ((item.close - item.prev_close) / item.prev_close) * 100;
changeMap[yyyymmdd] = change;
}
});
console.log('[HeroPanel] 加载上证指数数据成功,数据条数:', result.data.length, '映射条目数:', Object.keys(changeMap).length);
setIndexChangeMap(changeMap);
if (result.success && result.data) {
// 转换为 FullCalendarPro 需要的格式
const formattedData = result.data.map(item => ({
date: item.date,
count: item.zt_count || 0,
topSector: item.top_sector || '',
eventCount: item.event_count || 0,
indexChange: item.index_change,
}));
console.log('[HeroPanel] 加载日历综合数据成功,数据条数:', formattedData.length);
setCalendarData(formattedData);
}
}
} catch (error) {
console.error('Failed to load index data:', error);
console.error('Failed to load calendar combined data:', error);
}
};
loadIndexData();
}, []);
loadCalendarCombinedData();
}, [currentMonth]);
// 获取涨停板块详情(加载所有数据,不限于当月)
useEffect(() => {
const loadZtDetails = async () => {
const details = {};
const promises = [];
// 加载所有有数据的日期
ztDatesData.forEach(d => {
const dateStr = d.date;
if (!ztDailyDetails[dateStr]) {
promises.push(
fetch(`/data/zt/daily/${dateStr}.json`)
.then(res => res.ok ? res.json() : null)
.then(data => {
if (data) {
// 优先使用词云图最高频词fallback 到板块数据
let topWord = '';
if (data.word_freq_data && data.word_freq_data.length > 0) {
topWord = data.word_freq_data[0].name;
} else if (data.sector_data) {
let maxCount = 0;
Object.entries(data.sector_data).forEach(([sector, info]) => {
if (info.count > maxCount) {
maxCount = info.count;
topWord = sector;
}
});
}
details[dateStr] = { top_sector: topWord, fullData: data };
}
})
.catch(() => null)
);
}
});
if (promises.length > 0) {
await Promise.all(promises);
setZtDailyDetails(prev => ({ ...prev, ...details }));
}
};
if (ztDatesData.length > 0) {
loadZtDetails();
}
}, [ztDatesData]);
// 构建 FullCalendarPro 所需的数据格式
// 需要合并涨停数据、未来事件数据和上证指数涨跌幅
const calendarData = useMemo(() => {
// 创建日期到数据的映射
const dataMap = new Map();
// 先添加涨停数据
ztDatesData.forEach(d => {
const detail = ztDailyDetails[d.date] || {};
dataMap.set(d.date, {
date: d.date,
count: d.count,
topSector: detail.top_sector || '',
eventCount: 0,
indexChange: indexChangeMap[d.date] ?? null,
});
});
// 再添加/合并未来事件数据
eventCounts.forEach(e => {
// e.date 格式是 YYYY-MM-DD需要转为 YYYYMMDD
const yyyymmdd = e.date.replace(/-/g, '');
if (dataMap.has(yyyymmdd)) {
// 已有涨停数据,只更新事件数
const existing = dataMap.get(yyyymmdd);
existing.eventCount = e.count;
} else {
// 纯未来事件日期,没有涨停数据
dataMap.set(yyyymmdd, {
date: yyyymmdd,
count: 0,
topSector: '',
eventCount: e.count,
indexChange: indexChangeMap[yyyymmdd] ?? null,
});
}
});
return Array.from(dataMap.values());
}, [ztDatesData, ztDailyDetails, eventCounts, indexChangeMap]);
// 处理日期点击 - 打开弹窗
const handleDateClick = useCallback(async (date) => {