feat: 搜索框接入交易时间段筛选能力

This commit is contained in:
zdl
2025-11-06 11:48:31 +08:00
parent f4b58b42cc
commit 935c933cb8

View File

@@ -16,6 +16,7 @@ import { fetchIndustryData, selectIndustryData, selectIndustryLoading } from '..
import { stockService } from '../../../services/stockService';
import { logger } from '../../../utils/logger';
import PopularKeywords from './PopularKeywords';
import TradingTimeFilter from './TradingTimeFilter';
const { RangePicker } = DatePicker;
const { Option } = AntSelect;
@@ -36,6 +37,7 @@ const UnifiedSearchBox = ({
const [sort, setSort] = useState('new'); // 排序方式
const [importance, setImportance] = useState([]); // 重要性(数组,支持多选)
const [dateRange, setDateRange] = useState(null); // 日期范围
const [tradingTimeRange, setTradingTimeRange] = useState(null); // 交易时段筛选
// ✅ 本地输入状态 - 管理用户的实时输入
const [inputValue, setInputValue] = useState('');
@@ -360,6 +362,46 @@ const UnifiedSearchBox = ({
triggerSearch(params);
};
// ✅ 交易时段筛选变化(立即触发搜索)
const handleTradingTimeChange = (timeConfig) => {
if (!timeConfig) {
// 清空筛选
setTradingTimeRange(null);
const params = buildFilterParams({
start_date: '',
end_date: '',
recent_days: ''
});
triggerSearch(params);
return;
}
const { range, type, label } = timeConfig;
let params = {};
if (type === 'recent_days') {
// 近一周/近一月使用 recent_days
params.recent_days = range;
params.start_date = '';
params.end_date = '';
} else {
// 其他使用 start_date + end_date
params.start_date = range[0].format('YYYY-MM-DD HH:mm:ss');
params.end_date = range[1].format('YYYY-MM-DD HH:mm:ss');
params.recent_days = '';
}
setTradingTimeRange({ ...params, label });
// 立即触发搜索
const searchParams = buildFilterParams(params);
logger.debug('UnifiedSearchBox', '交易时段筛选变化,立即触发搜索', {
timeConfig,
params: searchParams
});
triggerSearch(searchParams);
};
// 主搜索(点击搜索按钮或回车)
const handleMainSearch = () => {
// 取消之前的防抖
@@ -432,6 +474,11 @@ const UnifiedSearchBox = ({
// 行业代码: 取选中路径的最后一级(最具体的行业代码)
industry_code: overrides.industry_code ?? (industryValue?.[industryValue.length - 1] || ''),
// 交易时段筛选参数
start_date: overrides.start_date ?? (tradingTimeRange?.start_date || ''),
end_date: overrides.end_date ?? (tradingTimeRange?.end_date || ''),
recent_days: overrides.recent_days ?? (tradingTimeRange?.recent_days || ''),
// 最终 overrides 具有最高优先级
...overrides
};
@@ -443,7 +490,7 @@ const UnifiedSearchBox = ({
logger.debug('UnifiedSearchBox', '🔧 buildFilterParams - 输出结果', result);
return result;
}, [sort, importance, dateRange, filters.q, industryValue]);
}, [sort, importance, dateRange, filters.q, industryValue, tradingTimeRange]);
// ✅ 应用筛选(立即搜索,取消防抖)
const handleApplyFilters = () => {
@@ -466,6 +513,7 @@ const UnifiedSearchBox = ({
setSort('new');
setImportance([]); // 改为空数组
setDateRange(null);
setTradingTimeRange(null); // 清空交易时段筛选
// 输出重置后的完整参数
const resetParams = {
@@ -474,6 +522,9 @@ const UnifiedSearchBox = ({
sort: 'new',
importance: 'all', // 传给后端时转为'all'
date_range: '',
start_date: '',
end_date: '',
recent_days: '',
page: 1
};
@@ -522,6 +573,14 @@ const UnifiedSearchBox = ({
tags.push({ key: 'date_range', label: `日期: ${dateLabel}` });
}
// 交易时段筛选标签
if (tradingTimeRange?.label) {
tags.push({
key: 'trading_time',
label: `时间: ${tradingTimeRange.label}`
});
}
// 重要性标签(多选合并显示为单个标签)
if (importance && importance.length > 0) {
const importanceLabel = importance.map(imp => `${imp}`).join(', ');
@@ -540,7 +599,7 @@ const UnifiedSearchBox = ({
}
return tags;
}, [filters.q, industryValue, dateRange, importance, sort]);
}, [filters.q, industryValue, dateRange, importance, sort, tradingTimeRange]);
// ✅ 移除单个标签 - 构建新参数并触发搜索
const handleRemoveTag = (key) => {
@@ -567,6 +626,15 @@ const UnifiedSearchBox = ({
setDateRange(null);
const params = buildFilterParams({ date_range: '' });
triggerSearch(params);
} else if (key === 'trading_time') {
// 清除交易时段筛选
setTradingTimeRange(null);
const params = buildFilterParams({
start_date: '',
end_date: '',
recent_days: ''
});
triggerSearch(params);
} else if (key === 'importance') {
// 重置重要性为空数组(传给后端为'all'
setImportance([]);
@@ -633,6 +701,10 @@ const UnifiedSearchBox = ({
{/* 左侧:筛选器组 */}
<Space size="middle" wrap>
<span style={{ fontSize: 14, color: '#666', fontWeight: 'bold' }}>筛选:</span>
{/* 交易时段筛选 */}
<TradingTimeFilter onChange={handleTradingTimeChange} />
{/* 行业分类 */}
<Cascader
value={industryValue}