feature: 重要性支持多选
This commit is contained in:
@@ -34,7 +34,7 @@ const UnifiedSearchBox = ({
|
|||||||
|
|
||||||
// 筛选条件状态
|
// 筛选条件状态
|
||||||
const [sort, setSort] = useState('new'); // 排序方式
|
const [sort, setSort] = useState('new'); // 排序方式
|
||||||
const [importance, setImportance] = useState('all'); // 重要性
|
const [importance, setImportance] = useState([]); // 重要性(数组,支持多选)
|
||||||
const [dateRange, setDateRange] = useState(null); // 日期范围
|
const [dateRange, setDateRange] = useState(null); // 日期范围
|
||||||
|
|
||||||
// ✅ 本地输入状态 - 管理用户的实时输入
|
// ✅ 本地输入状态 - 管理用户的实时输入
|
||||||
@@ -129,9 +129,22 @@ const UnifiedSearchBox = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!filters) return;
|
if (!filters) return;
|
||||||
|
|
||||||
// 初始化排序和重要性
|
// 初始化排序
|
||||||
if (filters.sort) setSort(filters.sort);
|
if (filters.sort) setSort(filters.sort);
|
||||||
if (filters.importance) setImportance(filters.importance);
|
|
||||||
|
// 初始化重要性(字符串解析为数组)
|
||||||
|
if (filters.importance) {
|
||||||
|
const importanceArray = filters.importance === 'all'
|
||||||
|
? [] // 'all' 对应空数组(不显示任何选中)
|
||||||
|
: filters.importance.split(',').map(v => v.trim()).filter(Boolean);
|
||||||
|
setImportance(importanceArray);
|
||||||
|
logger.debug('UnifiedSearchBox', '初始化重要性', {
|
||||||
|
filters_importance: filters.importance,
|
||||||
|
importanceArray
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setImportance([]);
|
||||||
|
}
|
||||||
|
|
||||||
// ✅ 初始化日期范围
|
// ✅ 初始化日期范围
|
||||||
if (filters.date_range) {
|
if (filters.date_range) {
|
||||||
@@ -247,30 +260,28 @@ const UnifiedSearchBox = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ✅ 重要性变化(使用防抖)
|
// ✅ 重要性变化(立即执行)- 支持多选
|
||||||
const handleImportanceChange = (value) => {
|
const handleImportanceChange = (value) => {
|
||||||
logger.debug('UnifiedSearchBox', '【1/5】重要性值改变', {
|
logger.debug('UnifiedSearchBox', '重要性值改变', {
|
||||||
oldValue: importance,
|
oldValue: importance,
|
||||||
newValue: value
|
newValue: value
|
||||||
});
|
});
|
||||||
|
|
||||||
setImportance(value);
|
setImportance(value);
|
||||||
|
|
||||||
// ⚠️ 注意:setState是异步的,此时importance仍是旧值
|
// 取消之前的防抖搜索
|
||||||
logger.debug('UnifiedSearchBox', '【2/5】调用buildFilterParams前的状态', {
|
|
||||||
importance: importance, // 旧值
|
|
||||||
sort: sort,
|
|
||||||
dateRange: dateRange,
|
|
||||||
industryValue: industryValue
|
|
||||||
});
|
|
||||||
|
|
||||||
// 使用防抖搜索
|
|
||||||
const params = buildFilterParams({ importance: value });
|
|
||||||
logger.debug('UnifiedSearchBox', '【3/5】buildFilterParams返回的参数', params);
|
|
||||||
|
|
||||||
if (debouncedSearchRef.current) {
|
if (debouncedSearchRef.current) {
|
||||||
logger.debug('UnifiedSearchBox', '【4/5】调用防抖函数(300ms延迟)');
|
debouncedSearchRef.current.cancel();
|
||||||
debouncedSearchRef.current(params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 转换为逗号分隔字符串传给后端(空数组表示"全部")
|
||||||
|
const importanceStr = value.length === 0 ? 'all' : value.join(',');
|
||||||
|
|
||||||
|
// 立即触发搜索
|
||||||
|
const params = buildFilterParams({ importance: importanceStr });
|
||||||
|
logger.debug('UnifiedSearchBox', '重要性改变,立即触发搜索', params);
|
||||||
|
|
||||||
|
triggerSearch(params);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ✅ 排序变化(使用防抖)
|
// ✅ 排序变化(使用防抖)
|
||||||
@@ -401,10 +412,18 @@ const UnifiedSearchBox = ({
|
|||||||
returnType = 'week';
|
returnType = 'week';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理重要性参数:数组转换为逗号分隔字符串
|
||||||
|
let importanceValue = overrides.importance ?? importance;
|
||||||
|
if (Array.isArray(importanceValue)) {
|
||||||
|
importanceValue = importanceValue.length === 0
|
||||||
|
? 'all'
|
||||||
|
: importanceValue.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
// 基础参数(overrides 优先级高于本地状态)
|
// 基础参数(overrides 优先级高于本地状态)
|
||||||
sort: actualSort,
|
sort: actualSort,
|
||||||
importance: overrides.importance ?? importance,
|
importance: importanceValue,
|
||||||
date_range: dateRange ? `${dateRange[0].format('YYYY-MM-DD')} 至 ${dateRange[1].format('YYYY-MM-DD')}` : '',
|
date_range: dateRange ? `${dateRange[0].format('YYYY-MM-DD')} 至 ${dateRange[1].format('YYYY-MM-DD')}` : '',
|
||||||
page: 1,
|
page: 1,
|
||||||
|
|
||||||
@@ -445,7 +464,7 @@ const UnifiedSearchBox = ({
|
|||||||
setStockOptions([]);
|
setStockOptions([]);
|
||||||
setIndustryValue([]);
|
setIndustryValue([]);
|
||||||
setSort('new');
|
setSort('new');
|
||||||
setImportance('all');
|
setImportance([]); // 改为空数组
|
||||||
setDateRange(null);
|
setDateRange(null);
|
||||||
|
|
||||||
// 输出重置后的完整参数
|
// 输出重置后的完整参数
|
||||||
@@ -453,7 +472,7 @@ const UnifiedSearchBox = ({
|
|||||||
q: '',
|
q: '',
|
||||||
industry_code: '',
|
industry_code: '',
|
||||||
sort: 'new',
|
sort: 'new',
|
||||||
importance: 'all',
|
importance: 'all', // 传给后端时转为'all'
|
||||||
date_range: '',
|
date_range: '',
|
||||||
page: 1
|
page: 1
|
||||||
};
|
};
|
||||||
@@ -483,9 +502,10 @@ const UnifiedSearchBox = ({
|
|||||||
tags.push({ key: 'date_range', label: `日期: ${dateLabel}` });
|
tags.push({ key: 'date_range', label: `日期: ${dateLabel}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重要性标签(排除默认值 'all')
|
// 重要性标签(多选合并显示为单个标签)
|
||||||
if (importance && importance !== 'all') {
|
if (importance && importance.length > 0) {
|
||||||
tags.push({ key: 'importance', label: `重要性: ${importance}级` });
|
const importanceLabel = importance.map(imp => `${imp}级`).join(', ');
|
||||||
|
tags.push({ key: 'importance', label: `重要性: ${importanceLabel}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 排序标签(排除默认值 'new')
|
// 排序标签(排除默认值 'new')
|
||||||
@@ -506,6 +526,11 @@ const UnifiedSearchBox = ({
|
|||||||
const handleRemoveTag = (key) => {
|
const handleRemoveTag = (key) => {
|
||||||
logger.debug('UnifiedSearchBox', '移除标签', { key });
|
logger.debug('UnifiedSearchBox', '移除标签', { key });
|
||||||
|
|
||||||
|
// 取消所有待执行的防抖搜索(避免旧的防抖覆盖删除操作)
|
||||||
|
if (debouncedSearchRef.current) {
|
||||||
|
debouncedSearchRef.current.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
if (key === 'search') {
|
if (key === 'search') {
|
||||||
// 清除搜索关键词和输入框,立即触发搜索
|
// 清除搜索关键词和输入框,立即触发搜索
|
||||||
setInputValue(''); // 清空输入框
|
setInputValue(''); // 清空输入框
|
||||||
@@ -523,8 +548,8 @@ const UnifiedSearchBox = ({
|
|||||||
const params = buildFilterParams({ date_range: '' });
|
const params = buildFilterParams({ date_range: '' });
|
||||||
triggerSearch(params);
|
triggerSearch(params);
|
||||||
} else if (key === 'importance') {
|
} else if (key === 'importance') {
|
||||||
// 重置重要性为默认值
|
// 重置重要性为空数组(传给后端为'all')
|
||||||
setImportance('all');
|
setImportance([]);
|
||||||
const params = buildFilterParams({ importance: 'all' });
|
const params = buildFilterParams({ importance: 'all' });
|
||||||
triggerSearch(params);
|
triggerSearch(params);
|
||||||
} else if (key === 'sort') {
|
} else if (key === 'sort') {
|
||||||
@@ -624,12 +649,14 @@ const UnifiedSearchBox = ({
|
|||||||
<Space size="small">
|
<Space size="small">
|
||||||
<span style={{ fontSize: 14, color: '#666' }}>重要性:</span>
|
<span style={{ fontSize: 14, color: '#666' }}>重要性:</span>
|
||||||
<AntSelect
|
<AntSelect
|
||||||
|
mode="multiple"
|
||||||
value={importance}
|
value={importance}
|
||||||
onChange={handleImportanceChange}
|
onChange={handleImportanceChange}
|
||||||
style={{ width: 100 }}
|
style={{ width: 150 }}
|
||||||
size="middle"
|
size="middle"
|
||||||
|
placeholder="全部"
|
||||||
|
maxTagCount={3}
|
||||||
>
|
>
|
||||||
<Option value="all">全部</Option>
|
|
||||||
<Option value="S">S级</Option>
|
<Option value="S">S级</Option>
|
||||||
<Option value="A">A级</Option>
|
<Option value="A">A级</Option>
|
||||||
<Option value="B">B级</Option>
|
<Option value="B">B级</Option>
|
||||||
|
|||||||
Reference in New Issue
Block a user