feat:Community 组件 (2个文件,8个console)
- EventDetailModal.js - 2个
- InvestmentCalendar.js - 6个
EventDetail 组件 (5个文件,54个console)
- TransmissionChainAnalysis.js - 43个 ⚠️ 最复杂
- RelatedConcepts.js - 14个
- LimitAnalyse.js - 5个 (保留2个toast)
- RelatedStocks.js - 3个 (保留4个toast)
- HistoricalEvents.js - 1个
StockChart 组件 (1个文件,4个console)
This commit is contained in:
@@ -6,6 +6,7 @@ import * as echarts from 'echarts';
|
||||
import moment from 'moment';
|
||||
import { stockService } from '../../services/eventService';
|
||||
import CitedContent from '../Citation/CitedContent';
|
||||
import { logger } from '../../utils/logger';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
@@ -43,14 +44,25 @@ const StockChartAntdModal = ({
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('事件时间解析失败:', e);
|
||||
logger.warn('StockChartAntdModal', '事件时间解析失败', {
|
||||
eventTime,
|
||||
error: e.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const response = await stockService.getKlineData(stock.stock_code, type, adjustedEventTime);
|
||||
setPreloadedData(prev => ({...prev, [type]: response}));
|
||||
logger.debug('StockChartAntdModal', '数据预加载成功', {
|
||||
stockCode: stock.stock_code,
|
||||
type,
|
||||
dataLength: response?.data?.length || 0
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(`预加载${type}数据失败:`, err);
|
||||
logger.error('StockChartAntdModal', 'preloadData', err, {
|
||||
stockCode: stock?.stock_code,
|
||||
type
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -89,7 +101,10 @@ const StockChartAntdModal = ({
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('事件时间解析失败:', e);
|
||||
logger.warn('StockChartAntdModal', '事件时间解析失败', {
|
||||
eventTime,
|
||||
error: e.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,8 +112,16 @@ const StockChartAntdModal = ({
|
||||
}
|
||||
|
||||
setChartData(data);
|
||||
logger.debug('StockChartAntdModal', '图表数据加载成功', {
|
||||
stockCode: stock.stock_code,
|
||||
chartType: activeChartType,
|
||||
dataLength: data?.data?.length || 0
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('加载图表数据失败:', error);
|
||||
logger.error('StockChartAntdModal', 'loadChartData', error, {
|
||||
stockCode: stock?.stock_code,
|
||||
chartType: activeChartType
|
||||
});
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import { FaHeart, FaRegHeart, FaComment } from 'react-icons/fa';
|
||||
import { format } from 'date-fns';
|
||||
import { zhCN } from 'date-fns/locale';
|
||||
import { eventService } from '../../../services/eventService';
|
||||
import { logger } from '../../../utils/logger';
|
||||
|
||||
const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussionType = '事件讨论' }) => {
|
||||
const [posts, setPosts] = useState([]);
|
||||
@@ -73,7 +74,16 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
|
||||
if (response.ok && result.success) {
|
||||
setPosts(result.data || []);
|
||||
logger.debug('EventDiscussionModal', '帖子列表加载成功', {
|
||||
eventId,
|
||||
postsCount: result.data?.length || 0
|
||||
});
|
||||
} else {
|
||||
logger.error('EventDiscussionModal', 'loadPosts', new Error('API返回错误'), {
|
||||
eventId,
|
||||
status: response.status,
|
||||
message: result.message
|
||||
});
|
||||
toast({
|
||||
title: '加载帖子失败',
|
||||
status: 'error',
|
||||
@@ -82,7 +92,7 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load posts:', error);
|
||||
logger.error('EventDiscussionModal', 'loadPosts', error, { eventId });
|
||||
toast({
|
||||
title: '加载帖子失败',
|
||||
status: 'error',
|
||||
@@ -107,9 +117,13 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
|
||||
if (response.ok && result.success) {
|
||||
setPostComments(prev => ({ ...prev, [postId]: result.data || [] }));
|
||||
logger.debug('EventDiscussionModal', '评论加载成功', {
|
||||
postId,
|
||||
commentsCount: result.data?.length || 0
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load comments:', error);
|
||||
logger.error('EventDiscussionModal', 'loadPostComments', error, { postId });
|
||||
} finally {
|
||||
setLoadingComments(prev => ({ ...prev, [postId]: false }));
|
||||
}
|
||||
@@ -147,6 +161,10 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
setNewPostContent('');
|
||||
setNewPostTitle('');
|
||||
loadPosts();
|
||||
logger.info('EventDiscussionModal', '帖子发布成功', {
|
||||
eventId,
|
||||
postId: result.data?.id
|
||||
});
|
||||
toast({
|
||||
title: '帖子发布成功',
|
||||
status: 'success',
|
||||
@@ -154,6 +172,10 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
isClosable: true,
|
||||
});
|
||||
} else {
|
||||
logger.error('EventDiscussionModal', 'handleSubmitPost', new Error('API返回错误'), {
|
||||
eventId,
|
||||
message: result.message
|
||||
});
|
||||
toast({
|
||||
title: result.message || '帖子发布失败',
|
||||
status: 'error',
|
||||
@@ -162,7 +184,7 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to submit post:', error);
|
||||
logger.error('EventDiscussionModal', 'handleSubmitPost', error, { eventId });
|
||||
toast({
|
||||
title: '帖子发布失败',
|
||||
status: 'error',
|
||||
@@ -188,6 +210,7 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
|
||||
if (response.ok && result.success) {
|
||||
loadPosts();
|
||||
logger.info('EventDiscussionModal', '帖子删除成功', { postId });
|
||||
toast({
|
||||
title: '帖子已删除',
|
||||
status: 'success',
|
||||
@@ -195,6 +218,10 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
isClosable: true,
|
||||
});
|
||||
} else {
|
||||
logger.error('EventDiscussionModal', 'handleDeletePost', new Error('API返回错误'), {
|
||||
postId,
|
||||
message: result.message
|
||||
});
|
||||
toast({
|
||||
title: result.message || '删除失败',
|
||||
status: 'error',
|
||||
@@ -203,7 +230,7 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to delete post:', error);
|
||||
logger.error('EventDiscussionModal', 'handleDeletePost', error, { postId });
|
||||
toast({
|
||||
title: '删除失败',
|
||||
status: 'error',
|
||||
@@ -230,9 +257,14 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
? { ...post, likes_count: result.likes_count, liked: result.liked }
|
||||
: post
|
||||
));
|
||||
logger.debug('EventDiscussionModal', '点赞操作成功', {
|
||||
postId,
|
||||
liked: result.liked,
|
||||
likesCount: result.likes_count
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to like post:', error);
|
||||
logger.error('EventDiscussionModal', 'handleLikePost', error, { postId });
|
||||
toast({
|
||||
title: '操作失败',
|
||||
status: 'error',
|
||||
@@ -268,6 +300,10 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
? { ...post, comments_count: (post.comments_count || 0) + 1 }
|
||||
: post
|
||||
));
|
||||
logger.info('EventDiscussionModal', '评论发布成功', {
|
||||
postId,
|
||||
commentId: result.data?.id
|
||||
});
|
||||
toast({
|
||||
title: '评论发布成功',
|
||||
status: 'success',
|
||||
@@ -276,7 +312,7 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to submit comment:', error);
|
||||
logger.error('EventDiscussionModal', 'handleSubmitComment', error, { postId });
|
||||
toast({
|
||||
title: '评论发布失败',
|
||||
status: 'error',
|
||||
@@ -307,6 +343,7 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
? { ...post, comments_count: Math.max(0, (post.comments_count || 0) - 1) }
|
||||
: post
|
||||
));
|
||||
logger.info('EventDiscussionModal', '评论删除成功', { commentId, postId });
|
||||
toast({
|
||||
title: '评论已删除',
|
||||
status: 'success',
|
||||
@@ -315,7 +352,7 @@ const EventDiscussionModal = ({ isOpen, onClose, eventId, eventTitle, discussion
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to delete comment:', error);
|
||||
logger.error('EventDiscussionModal', 'handleDeleteComment', error, { commentId, postId });
|
||||
toast({
|
||||
title: '删除失败',
|
||||
status: 'error',
|
||||
|
||||
@@ -5,6 +5,7 @@ import { FilterOutlined } from '@ant-design/icons';
|
||||
import moment from 'moment';
|
||||
import locale from 'antd/es/date-picker/locale/zh_CN';
|
||||
import { industryService } from '../../../services/industryService';
|
||||
import { logger } from '../../../utils/logger';
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
const { Option } = Select;
|
||||
@@ -36,8 +37,11 @@ const EventFilters = ({ filters, onFilterChange, loading }) => {
|
||||
try {
|
||||
const response = await industryService.getClassifications();
|
||||
setIndustryData(prev => ({ ...prev, classifications: response.data }));
|
||||
logger.debug('EventFilters', '行业分类加载成功', {
|
||||
count: response.data?.length || 0
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to load industry classifications:', error);
|
||||
logger.error('EventFilters', 'loadIndustryClassifications', error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -50,8 +54,12 @@ const EventFilters = ({ filters, onFilterChange, loading }) => {
|
||||
for (let l = level + 1; l <= 4; l++) {
|
||||
setIndustryData(prev => ({ ...prev, [`level${l}`]: [] }));
|
||||
}
|
||||
logger.debug('EventFilters', '行业层级数据加载成功', {
|
||||
level,
|
||||
count: response.data?.length || 0
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to load industry levels:', error);
|
||||
logger.error('EventFilters', 'loadIndustryLevels', error, { level, params });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ import {
|
||||
} from '@chakra-ui/icons';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import moment from 'moment';
|
||||
import { logger } from '../../../utils/logger';
|
||||
|
||||
// ========== 工具函数定义在组件外部 ==========
|
||||
// 涨跌颜色配置(中国A股配色:红涨绿跌)- 分档次显示
|
||||
@@ -186,10 +187,12 @@ const EventList = ({ events, pagination, onPageChange, onEventClick, onViewDetai
|
||||
const map = {};
|
||||
(data.data || []).forEach(ev => { map[ev.id] = true; });
|
||||
setFollowingMap(map);
|
||||
logger.debug('EventList', '关注状态加载成功', {
|
||||
followingCount: Object.keys(map).length
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// 静默失败
|
||||
console.warn('load following failed', e);
|
||||
logger.warn('EventList', '加载关注状态失败', { error: e.message });
|
||||
}
|
||||
};
|
||||
loadFollowing();
|
||||
@@ -210,8 +213,16 @@ const EventList = ({ events, pagination, onPageChange, onEventClick, onViewDetai
|
||||
const count = data.data?.follower_count ?? 0;
|
||||
setFollowingMap(prev => ({ ...prev, [eventId]: isFollowing }));
|
||||
setFollowCountMap(prev => ({ ...prev, [eventId]: count }));
|
||||
logger.debug('EventList', '关注状态切换成功', {
|
||||
eventId,
|
||||
isFollowing,
|
||||
followerCount: count
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn('toggle follow failed', e);
|
||||
logger.warn('EventList', '关注操作失败', {
|
||||
eventId,
|
||||
error: e.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Card, Tag, Space, Spin, Empty, Button } from 'antd';
|
||||
import { FireOutlined, RightOutlined } from '@ant-design/icons';
|
||||
import { logger } from '../../../utils/logger';
|
||||
|
||||
const API_BASE_URL = process.env.NODE_ENV === 'production'
|
||||
? '/concept-api'
|
||||
@@ -44,9 +45,12 @@ const PopularKeywords = ({ onKeywordClick }) => {
|
||||
concept_id: item.concept_id
|
||||
}));
|
||||
setKeywords(formattedData);
|
||||
logger.debug('PopularKeywords', '热门概念加载成功', {
|
||||
count: formattedData.length
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load popular concepts:', error);
|
||||
logger.error('PopularKeywords', 'loadPopularConcepts', error);
|
||||
setKeywords([]);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
|
||||
Reference in New Issue
Block a user