From c6b3b56cb8a0d64d40016e96f156f3d6f1fb84a4 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Thu, 6 Nov 2025 12:40:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=90=9C=E7=B4=A2=E6=A1=86=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Community/components/UnifiedSearchBox.js | 211 ++++++------------ 1 file changed, 71 insertions(+), 140 deletions(-) diff --git a/src/views/Community/components/UnifiedSearchBox.js b/src/views/Community/components/UnifiedSearchBox.js index 46252412..55fa7276 100644 --- a/src/views/Community/components/UnifiedSearchBox.js +++ b/src/views/Community/components/UnifiedSearchBox.js @@ -2,14 +2,12 @@ // 搜索组件:三行布局(主搜索 + 热门概念 + 筛选区) import React, { useState, useMemo, useEffect, useCallback, useRef } from 'react'; import { - Card, Input, Cascader, Button, Space, Tag, AutoComplete, DatePicker, Select as AntSelect + Card, Input, Cascader, Button, Space, Tag, AutoComplete, Select as AntSelect } from 'antd'; import { SearchOutlined, CloseCircleOutlined, StockOutlined } from '@ant-design/icons'; -import moment from 'moment'; import dayjs from 'dayjs'; -import locale from 'antd/es/date-picker/locale/zh_CN'; import debounce from 'lodash/debounce'; import { useSelector, useDispatch } from 'react-redux'; import { fetchIndustryData, selectIndustryData, selectIndustryLoading } from '../../../store/slices/industrySlice'; @@ -18,7 +16,6 @@ import { logger } from '../../../utils/logger'; import PopularKeywords from './PopularKeywords'; import TradingTimeFilter from './TradingTimeFilter'; -const { RangePicker } = DatePicker; const { Option } = AntSelect; const UnifiedSearchBox = ({ @@ -36,7 +33,6 @@ const UnifiedSearchBox = ({ // 筛选条件状态 const [sort, setSort] = useState('new'); // 排序方式 const [importance, setImportance] = useState([]); // 重要性(数组,支持多选) - const [dateRange, setDateRange] = useState(null); // 日期范围 const [tradingTimeRange, setTradingTimeRange] = useState(null); // 交易时段筛选 // ✅ 本地输入状态 - 管理用户的实时输入 @@ -148,17 +144,6 @@ const UnifiedSearchBox = ({ setImportance([]); } - // ✅ 初始化日期范围 - if (filters.date_range) { - const parts = filters.date_range.split(' 至 '); - if (parts.length === 2) { - setDateRange([dayjs(parts[0]), dayjs(parts[1])]); - logger.debug('UnifiedSearchBox', '初始化日期范围', { - date_range: filters.date_range - }); - } - } - // ✅ 初始化行业分类(需要 industryData 加载完成) if (filters.industry_code && industryData && industryData.length > 0) { const path = findIndustryPath(filters.industry_code, industryData); @@ -178,7 +163,7 @@ const UnifiedSearchBox = ({ // 如果 filters 中没有搜索关键词,清空输入框 setInputValue(''); } - }, [filters.sort, filters.importance, filters.date_range, filters.industry_code, filters.q, industryData, findIndustryPath]); + }, [filters.sort, filters.importance, filters.industry_code, filters.q, industryData, findIndustryPath]); // AutoComplete 搜索股票(模糊匹配 code 或 name) const handleSearch = (value) => { @@ -233,35 +218,6 @@ const UnifiedSearchBox = ({ } }; - // ✅ 日期范围变化(使用防抖) - const handleDateRangeChange = (dates) => { - logger.debug('UnifiedSearchBox', '【1/5】日期范围值改变', { - oldValue: dateRange, - newValue: dates - }); - setDateRange(dates); - - // ⚠️ 注意:setState是异步的,此时dateRange仍是旧值 - logger.debug('UnifiedSearchBox', '【2/5】调用buildFilterParams前的状态', { - dateRange: dateRange, // 旧值 - sort: sort, - importance: importance, - industryValue: industryValue - }); - - // 使用防抖搜索(需要从新值推导参数) - const params = { - ...buildFilterParams(), - date_range: dates ? `${dates[0].format('YYYY-MM-DD')} 至 ${dates[1].format('YYYY-MM-DD')}` : '' - }; - logger.debug('UnifiedSearchBox', '【3/5】buildFilterParams返回的参数', params); - - if (debouncedSearchRef.current) { - logger.debug('UnifiedSearchBox', '【4/5】调用防抖函数(300ms延迟)'); - debouncedSearchRef.current(params); - } - }; - // ✅ 重要性变化(立即执行)- 支持多选 const handleImportanceChange = (value) => { logger.debug('UnifiedSearchBox', '重要性值改变', { @@ -376,7 +332,7 @@ const UnifiedSearchBox = ({ return; } - const { range, type, label } = timeConfig; + const { range, type, label, key } = timeConfig; let params = {}; if (type === 'recent_days') { @@ -391,7 +347,7 @@ const UnifiedSearchBox = ({ params.recent_days = ''; } - setTradingTimeRange({ ...params, label }); + setTradingTimeRange({ ...params, label, key }); // 立即触发搜索 const searchParams = buildFilterParams(params); @@ -435,7 +391,6 @@ const UnifiedSearchBox = ({ currentState: { sort, importance, - dateRange, industryValue, 'filters.q': filters.q } @@ -466,7 +421,6 @@ const UnifiedSearchBox = ({ // 基础参数(overrides 优先级高于本地状态) sort: actualSort, importance: importanceValue, - date_range: dateRange ? `${dateRange[0].format('YYYY-MM-DD')} 至 ${dateRange[1].format('YYYY-MM-DD')}` : '', page: 1, // 搜索参数: 统一使用 q 参数进行搜索(话题/股票/关键词) @@ -490,19 +444,7 @@ const UnifiedSearchBox = ({ logger.debug('UnifiedSearchBox', '🔧 buildFilterParams - 输出结果', result); return result; - }, [sort, importance, dateRange, filters.q, industryValue, tradingTimeRange]); - - // ✅ 应用筛选(立即搜索,取消防抖) - const handleApplyFilters = () => { - // 取消之前的防抖搜索 - if (debouncedSearchRef.current) { - debouncedSearchRef.current.cancel(); - } - - const params = buildFilterParams(); - logger.debug('UnifiedSearchBox', '应用筛选,立即触发搜索', params); - triggerSearch(params); - }; + }, [sort, importance, filters.q, industryValue, tradingTimeRange]); // ✅ 重置筛选 - 清空所有筛选器并触发搜索 const handleReset = () => { @@ -512,7 +454,6 @@ const UnifiedSearchBox = ({ setIndustryValue([]); setSort('new'); setImportance([]); // 改为空数组 - setDateRange(null); setTradingTimeRange(null); // 清空交易时段筛选 // 输出重置后的完整参数 @@ -521,7 +462,6 @@ const UnifiedSearchBox = ({ industry_code: '', sort: 'new', importance: 'all', // 传给后端时转为'all' - date_range: '', start_date: '', end_date: '', recent_days: '', @@ -547,9 +487,9 @@ const UnifiedSearchBox = ({ const findLabel = (code, data) => { for (const item of data) { if (code.startsWith(item.value)) { - if(item.value === code){ + if (item.value === code) { return item.label; - }else { + } else { return findLabel(code, item.children); } } @@ -567,12 +507,6 @@ const UnifiedSearchBox = ({ }); } - // 日期范围标签 - if (dateRange && dateRange.length === 2) { - const dateLabel = `${dateRange[0].format('YYYY-MM-DD')} 至 ${dateRange[1].format('YYYY-MM-DD')}`; - tags.push({ key: 'date_range', label: `日期: ${dateLabel}` }); - } - // 交易时段筛选标签 if (tradingTimeRange?.label) { tags.push({ @@ -599,7 +533,7 @@ const UnifiedSearchBox = ({ } return tags; - }, [filters.q, industryValue, dateRange, importance, sort, tradingTimeRange]); + }, [filters.q, industryValue, importance, sort, tradingTimeRange]); // ✅ 移除单个标签 - 构建新参数并触发搜索 const handleRemoveTag = (key) => { @@ -621,11 +555,6 @@ const UnifiedSearchBox = ({ setIndustryValue([]); const params = buildFilterParams({ industry_code: '' }); triggerSearch(params); - } else if (key === 'date_range') { - // 清除日期范围 - setDateRange(null); - const params = buildFilterParams({ date_range: '' }); - triggerSearch(params); } else if (key === 'trading_time') { // 清除交易时段筛选 setTradingTimeRange(null); @@ -650,61 +579,11 @@ const UnifiedSearchBox = ({ return ( - {/* 第一行:主搜索框 */} - - - { - if (e.key === 'Enter') { - handleMainSearch(); - } - }} - style={{ flex: 1 }} - size="large" - notFoundContent={inputValue && stockOptions.length === 0 ? "未找到匹配的股票" : null} - /> - - - - {/* 第二行:热门概念 */} -
- -
- - {/* 第三行:筛选器 + 排序 */} + {/* 第三行:行业 + 重要性 + 排序 */} {/* 左侧:筛选器组 */} 筛选: - - {/* 交易时段筛选 */} - - {/* 行业分类 */} - {/* 日期范围 */} - - {/* 重要性 */} 重要性: @@ -756,6 +625,49 @@ const UnifiedSearchBox = ({ + {/* 搜索图标(可点击) + 搜索框 */} + + { + e.currentTarget.style.color = '#1890ff'; + e.currentTarget.style.background = '#e6f7ff'; + }} + onMouseLeave={(e) => { + e.currentTarget.style.color = '#666'; + e.currentTarget.style.background = '#f5f5f5'; + }} + /> + { + if (e.key === 'Enter') { + handleMainSearch(); + } + }} + style={{ flex: 1 }} + size="middle" + notFoundContent={inputValue && stockOptions.length === 0 ? "未找到匹配的股票" : null} + /> + + {/* 重置按钮 - 现代化设计 */}