feat: UI 层面:

-  只显示一套标签(在搜索框下方)
    -  标签样式统一(Ant Design Tag 组件)
    -  所有筛选条件都有对应的标签显示
  2. 功能层面:
    -  标签内容与实际筛选条件完全同步
    -  点击标签删除按钮,对应筛选条件被清除
    -  删除标签后自动刷新事件列表
    -  完整的日志记录,便于调试
  3. 代码层面:
    -  消除重复代码
    -  单一数据源(UnifiedSearchBox 的内部状态)
    -  逻辑统一,易于维护
This commit is contained in:
zdl
2025-10-26 20:04:10 +08:00
parent b4b7eae1ba
commit aa332537d4

View File

@@ -73,18 +73,6 @@ import { useNotification } from '../../contexts/NotificationContext';
// 导航栏已由 MainLayout 提供,无需在此导入
// const { RangePicker } = DatePicker;
// const { Option } = AntSelect;
const filterLabelMap = {
date_range: v => v ? `日期: ${v}` : '',
sort: v => v ? `排序: ${v === 'new' ? '最新' : v === 'hot' ? '热门' : v === 'returns' ? '收益率' : v}` : '',
importance: v => v && v !== 'all' ? `重要性: ${v}` : '',
industry_classification: v => v ? `行业: ${v}` : '',
industry_code: v => v ? `行业代码: ${v}` : '',
q: v => v ? `关键词: ${v}` : '',
};
const Community = () => {
const [searchParams, setSearchParams] = useSearchParams();
const navigate = useNavigate();
@@ -127,16 +115,17 @@ const Community = () => {
importance: searchParams.get('importance') || 'all',
date_range: searchParams.get('date_range') || '',
q: searchParams.get('q') || '',
search_type: searchParams.get('search_type') || 'topic',
industry_classification: searchParams.get('industry_classification') || '',
industry_code: searchParams.get('industry_code') || '',
stock_code: searchParams.get('stock_code') || '',
page: parseInt(searchParams.get('page') || '1', 10)
};
});
// 更新筛选参数 - 不再修改URL
// 更新筛选参数 - 直接替换(由 UnifiedSearchBox 输出完整参数)
const updateFilters = useCallback((newFilters) => {
setFilters(prev => ({ ...prev, ...newFilters }));
logger.debug('Community', 'updateFilters 接收到完整参数', newFilters);
setFilters(newFilters);
}, []);
// 加载事件列表
@@ -169,14 +158,10 @@ const Community = () => {
}
}, [filters, pagination.pageSize]);
// 处理筛选变化
const handleFilterChange = useCallback((filterType, value) => {
updateFilters({ [filterType]: value, page: 1 });
}, [updateFilters]);
// 处理分页变化
const handlePageChange = useCallback((page) => {
updateFilters({ page });
// 保持现有筛选条件,只更新页码
updateFilters({ ...filters, page });
// 滚动到实时事件时间轴(平滑滚动)
setTimeout(() => {
@@ -187,7 +172,7 @@ const Community = () => {
});
}
}, 100); // 延迟100ms确保DOM更新
}, [updateFilters]);
}, [updateFilters, filters]);
// 处理事件点击
const handleEventClick = useCallback((event) => {
@@ -200,36 +185,6 @@ const Community = () => {
navigate(`/event-detail/${eventId}`);
}, [navigate]);
// 处理关键词点击
const handleKeywordClick = useCallback((keyword) => {
updateFilters({ q: keyword, page: 1 });
}, [updateFilters]);
// 处理标签删除
const handleRemoveFilterTag = (key) => {
let reset = '';
if (key === 'sort') reset = 'new';
if (key === 'importance') reset = 'all';
updateFilters({ [key]: reset, page: 1 });
};
// 获取筛选标签
const filterTags = Object.entries(filters)
.filter(([key, value]) => {
if (key === 'industry_code') return !!value;
if (key === 'importance') return value && value !== 'all';
if (key === 'sort') return value && value !== 'new';
if (key === 'date_range') return !!value;
if (key === 'q') return !!value;
return false;
})
.map(([key, value]) => {
if (key === 'industry_code') return { key, label: `行业代码: ${value}` };
return { key, label: filterLabelMap[key] ? filterLabelMap[key](value) : `${key}: ${value}` };
});
// 创建防抖的 loadEvents 函数500ms 防抖延迟)
const debouncedLoadEvents = useRef(
debounce((page) => {
@@ -306,7 +261,7 @@ const Community = () => {
{/* 主体内容 */}
<CardBody>
{/* 统一搜索组件(整合了话题、股票、行业、日期、排序、重要性、热门概念) */}
{/* 统一搜索组件(整合了话题、股票、行业、日期、排序、重要性、热门概念、筛选标签 */}
<Box mb={4}>
<UnifiedSearchBox
onSearch={updateFilters}
@@ -316,20 +271,6 @@ const Community = () => {
/>
</Box>
{/* 筛选标签 */}
{filterTags.length > 0 && (
<Wrap spacing={2} mb={4}>
{filterTags.map(tag => (
<WrapItem key={tag.key}>
<Tag size="md" variant="solid" colorScheme="blue">
<TagLabel>{tag.label}</TagLabel>
<TagCloseButton onClick={() => handleRemoveFilterTag(tag.key)} />
</Tag>
</WrapItem>
))}
</Wrap>
)}
{/* 事件列表 */}
{loading ? (
<Center py={10}>