diff --git a/src/views/Community/components/UnifiedSearchBox.js b/src/views/Community/components/UnifiedSearchBox.js
index f3fc8dd6..45dfa04c 100644
--- a/src/views/Community/components/UnifiedSearchBox.js
+++ b/src/views/Community/components/UnifiedSearchBox.js
@@ -35,23 +35,18 @@ const UnifiedSearchBox = ({
const [importance, setImportance] = useState('all'); // 重要性
const [dateRange, setDateRange] = useState(null); // 日期范围
+ // ✅ 本地输入状态 - 管理用户的实时输入
+ const [inputValue, setInputValue] = useState('');
+
// 使用全局行业数据
const { industryData, loadIndustryData, loading: industryLoading } = useIndustry();
- // ✅ 从 filters 推导搜索框显示值(受控状态)
- const searchValue = useMemo(() => {
- if (filters.stock_code && allStocks.length > 0) {
- // 股票搜索模式:显示 "代码 名称"
- const stock = allStocks.find(s => s.code === filters.stock_code);
- return stock ? `${stock.code} ${stock.name}` : filters.stock_code;
- }
- // 话题搜索模式:显示关键词
- return filters.q || '';
- }, [filters.stock_code, filters.q, allStocks]);
-
// 搜索触发函数
const triggerSearch = useCallback((params) => {
- logger.debug('UnifiedSearchBox', '触发搜索', params);
+ logger.debug('UnifiedSearchBox', '【5/5】✅ 最终触发搜索 - 调用onSearch回调', {
+ params: params,
+ timestamp: new Date().toISOString()
+ });
onSearch(params);
}, [onSearch]);
@@ -61,7 +56,10 @@ const UnifiedSearchBox = ({
useEffect(() => {
// 创建防抖函数,使用 triggerSearch 而不是直接调用 onSearch
debouncedSearchRef.current = debounce((params) => {
- logger.debug('UnifiedSearchBox', '防抖搜索触发', params);
+ logger.debug('UnifiedSearchBox', '⏱️ 防抖延迟结束,执行搜索', {
+ params: params,
+ delayMs: 300
+ });
triggerSearch(params);
}, 300);
@@ -116,7 +114,7 @@ const UnifiedSearchBox = ({
return null;
}, []);
- // ✅ 从 props.filters 初始化筛选条件(不包括搜索值,搜索值由 searchValue useMemo 推导)
+ // ✅ 从 props.filters 初始化筛选条件和输入框值
useEffect(() => {
if (!filters) return;
@@ -146,7 +144,15 @@ const UnifiedSearchBox = ({
});
}
}
- }, [filters.sort, filters.importance, filters.date_range, filters.industry_code, industryData, findIndustryPath]);
+
+ // ✅ 同步 filters.q 到输入框显示值
+ if (filters.q) {
+ setInputValue(filters.q);
+ } else if (!filters.q) {
+ // 如果 filters 中没有搜索关键词,清空输入框
+ setInputValue('');
+ }
+ }, [filters.sort, filters.importance, filters.date_range, filters.industry_code, filters.q, industryData, findIndustryPath]);
// AutoComplete 搜索股票(模糊匹配 code 或 name)
const handleSearch = (value) => {
@@ -179,7 +185,7 @@ const UnifiedSearchBox = ({
});
};
- // ✅ 选中股票(从下拉选择) - 直接构建参数并触发搜索
+ // ✅ 选中股票(从下拉选择) - 更新输入框并触发搜索
const handleStockSelect = (_value, option) => {
const stockInfo = option.stockInfo;
if (stockInfo) {
@@ -188,12 +194,13 @@ const UnifiedSearchBox = ({
name: stockInfo.name
});
- // 直接构建参数并触发搜索(股票搜索模式)
+ // 更新输入框显示
+ setInputValue(`${stockInfo.code} ${stockInfo.name}`);
+
+ // 直接构建参数并触发搜索 - 使用股票代码作为 q 参数
const params = buildFilterParams({
- stock_code: stockInfo.code,
- q: '',
- industry_code: '',
- industry_classification: ''
+ q: stockInfo.code, // 使用股票代码作为搜索关键词
+ industry_code: ''
});
logger.debug('UnifiedSearchBox', '自动触发股票搜索', params);
triggerSearch(params);
@@ -202,53 +209,119 @@ const UnifiedSearchBox = ({
// ✅ 日期范围变化(使用防抖)
const handleDateRangeChange = (dates) => {
+ logger.debug('UnifiedSearchBox', '【1/5】日期范围值改变', {
+ oldValue: dateRange,
+ newValue: dates
+ });
setDateRange(dates);
- // 使用防抖搜索(与其他筛选器保持一致)
- const params = buildFilterParams();
- logger.debug('UnifiedSearchBox', '日期范围变化,准备触发搜索', { dates, params });
+
+ // ⚠️ 注意: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', '【1/5】重要性值改变', {
+ oldValue: importance,
+ newValue: 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', '重要性变化,准备触发搜索', params);
+ logger.debug('UnifiedSearchBox', '【3/5】buildFilterParams返回的参数', params);
+
if (debouncedSearchRef.current) {
+ logger.debug('UnifiedSearchBox', '【4/5】调用防抖函数(300ms延迟)');
debouncedSearchRef.current(params);
}
};
// ✅ 排序变化(使用防抖)
const handleSortChange = (value) => {
+ logger.debug('UnifiedSearchBox', '【1/5】排序值改变', {
+ oldValue: sort,
+ newValue: value
+ });
setSort(value);
+
+ // ⚠️ 注意:setState是异步的,此时sort仍是旧值
+ logger.debug('UnifiedSearchBox', '【2/5】调用buildFilterParams前的状态', {
+ sort: sort, // 旧值
+ importance: importance,
+ dateRange: dateRange,
+ industryValue: industryValue
+ });
+
// 使用防抖搜索
const params = buildFilterParams({ sort: value });
- logger.debug('UnifiedSearchBox', '排序变化,准备触发搜索', params);
+ logger.debug('UnifiedSearchBox', '【3/5】buildFilterParams返回的参数', params);
+
if (debouncedSearchRef.current) {
+ logger.debug('UnifiedSearchBox', '【4/5】调用防抖函数(300ms延迟)');
debouncedSearchRef.current(params);
}
};
// ✅ 行业分类变化(使用防抖)
const handleIndustryChange = (value) => {
- setIndustryValue(value);
- // 使用防抖搜索
- const params = buildFilterParams();
- logger.debug('UnifiedSearchBox', '行业分类变化,准备触发搜索', {
- industry: value,
- params
+ logger.debug('UnifiedSearchBox', '【1/5】行业分类值改变', {
+ oldValue: industryValue,
+ newValue: value
});
+ setIndustryValue(value);
+
+ // ⚠️ 注意:setState是异步的,此时industryValue仍是旧值
+ logger.debug('UnifiedSearchBox', '【2/5】调用buildFilterParams前的状态', {
+ industryValue: industryValue, // 旧值
+ sort: sort,
+ importance: importance,
+ dateRange: dateRange
+ });
+
+ // 使用防抖搜索 (需要从新值推导参数)
+ const params = {
+ ...buildFilterParams(),
+ industry_code: value?.[value.length - 1] || ''
+ };
+ logger.debug('UnifiedSearchBox', '【3/5】buildFilterParams返回的参数', params);
+
if (debouncedSearchRef.current) {
+ logger.debug('UnifiedSearchBox', '【4/5】调用防抖函数(300ms延迟)');
debouncedSearchRef.current(params);
}
};
- // ✅ 热门概念点击处理(立即搜索,不使用防抖) - 直接构建参数并触发搜索
+ // ✅ 热门概念点击处理(立即搜索,不使用防抖) - 更新输入框并触发搜索
const handleKeywordClick = (keyword) => {
+ // 更新输入框显示
+ setInputValue(keyword);
+
// 立即触发搜索(取消之前的防抖)
if (debouncedSearchRef.current) {
debouncedSearchRef.current.cancel();
@@ -256,9 +329,7 @@ const UnifiedSearchBox = ({
const params = buildFilterParams({
q: keyword,
- stock_code: '',
- industry_code: '',
- industry_classification: ''
+ industry_code: ''
});
logger.debug('UnifiedSearchBox', '热门概念点击,立即触发搜索', {
keyword,
@@ -269,37 +340,62 @@ const UnifiedSearchBox = ({
// 主搜索(点击搜索按钮或回车)
const handleMainSearch = () => {
- // 直接输入文本时,构建参数并触发搜索
- logger.debug('UnifiedSearchBox', '主搜索触发', { searchValue });
- handleApplyFilters();
+ // 取消之前的防抖
+ if (debouncedSearchRef.current) {
+ debouncedSearchRef.current.cancel();
+ }
+
+ // 构建参数并触发搜索 - 使用用户输入作为 q 参数
+ const params = buildFilterParams({
+ q: inputValue, // 使用用户输入(可能是话题、股票代码、股票名称等)
+ industry_code: ''
+ });
+
+ logger.debug('UnifiedSearchBox', '主搜索触发', {
+ inputValue,
+ params
+ });
+ triggerSearch(params);
};
- // ✅ 处理输入变化 - AutoComplete 内部处理显示,不需要更新状态
+ // ✅ 处理输入变化 - 更新本地输入状态
const handleInputChange = (value) => {
- // AutoComplete 组件会自动处理显示值
- // 这里可以添加其他逻辑(如实时搜索建议)
logger.debug('UnifiedSearchBox', '输入变化', { value });
+ setInputValue(value);
};
// ✅ 生成完整的筛选参数对象 - 直接从 filters 和本地筛选器状态构建
const buildFilterParams = useCallback((overrides = {}) => {
- return {
+ logger.debug('UnifiedSearchBox', '🔧 buildFilterParams - 输入参数', {
+ overrides: overrides,
+ currentState: {
+ sort,
+ importance,
+ dateRange,
+ industryValue,
+ 'filters.q': filters.q
+ }
+ });
+
+ const result = {
// 基础参数(overrides 优先级高于本地状态)
sort: overrides.sort ?? sort,
importance: overrides.importance ?? importance,
date_range: dateRange ? `${dateRange[0].format('YYYY-MM-DD')} 至 ${dateRange[1].format('YYYY-MM-DD')}` : '',
page: 1,
- // 搜索参数(从 filters 继承,overrides 可覆盖)
+ // 搜索参数: 统一使用 q 参数进行搜索(话题/股票/关键词)
q: overrides.q ?? filters.q ?? '',
- stock_code: overrides.stock_code ?? filters.stock_code ?? '',
+ // 行业代码: 取选中路径的最后一级(最具体的行业代码)
industry_code: overrides.industry_code ?? (industryValue?.[industryValue.length - 1] || ''),
- industry_classification: overrides.industry_classification ?? (industryValue?.[0] || ''),
// 最终 overrides 具有最高优先级
...overrides
};
- }, [sort, importance, dateRange, filters.q, filters.stock_code, industryValue]);
+
+ logger.debug('UnifiedSearchBox', '🔧 buildFilterParams - 输出结果', result);
+ return result;
+ }, [sort, importance, dateRange, filters.q, industryValue]);
// ✅ 应用筛选(立即搜索,取消防抖)
const handleApplyFilters = () => {
@@ -316,6 +412,7 @@ const UnifiedSearchBox = ({
// ✅ 重置筛选 - 清空所有筛选器并触发搜索
const handleReset = () => {
// 重置所有筛选器状态
+ setInputValue(''); // 清空输入框
setStockOptions([]);
setIndustryValue([]);
setSort('new');
@@ -325,9 +422,7 @@ const UnifiedSearchBox = ({
// 输出重置后的完整参数
const resetParams = {
q: '',
- stock_code: '',
industry_code: '',
- industry_classification: '',
sort: 'new',
importance: 'all',
date_range: '',
@@ -342,13 +437,9 @@ const UnifiedSearchBox = ({
const filterTags = useMemo(() => {
const tags = [];
- // 股票/话题标签 - 从 filters 读取
- if (filters.stock_code) {
- const stock = allStocks.find(s => s.code === filters.stock_code);
- const label = stock ? `${stock.code} ${stock.name}` : filters.stock_code;
- tags.push({ key: 'stock', label: `股票: ${label}` });
- } else if (filters.q) {
- tags.push({ key: 'topic', label: `话题: ${filters.q}` });
+ // 搜索关键词标签 - 从 filters.q 读取
+ if (filters.q) {
+ tags.push({ key: 'search', label: `搜索: ${filters.q}` });
}
// 行业标签
@@ -375,21 +466,22 @@ const UnifiedSearchBox = ({
}
return tags;
- }, [filters.stock_code, filters.q, allStocks, industryValue, dateRange, importance, sort]);
+ }, [filters.q, industryValue, dateRange, importance, sort]);
// ✅ 移除单个标签 - 构建新参数并触发搜索
const handleRemoveTag = (key) => {
logger.debug('UnifiedSearchBox', '移除标签', { key });
- if (key === 'topic' || key === 'stock') {
- // 清除搜索关键词/股票,立即触发搜索
- const params = buildFilterParams({ q: '', stock_code: '' });
+ if (key === 'search') {
+ // 清除搜索关键词和输入框,立即触发搜索
+ setInputValue(''); // 清空输入框
+ const params = buildFilterParams({ q: '' });
logger.debug('UnifiedSearchBox', '移除搜索标签后触发搜索', { key, params });
triggerSearch(params);
} else if (key === 'industry') {
// 清除行业选择
setIndustryValue([]);
- const params = buildFilterParams({ industry_code: '', industry_classification: '' });
+ const params = buildFilterParams({ industry_code: '' });
triggerSearch(params);
} else if (key === 'date_range') {
// 清除日期范围
@@ -425,7 +517,7 @@ const UnifiedSearchBox = ({
color: '#666'
}} />