fix: 修复 Mock 环境相关概念返回空结果问题

问题分析:
- Mock handler 的过滤逻辑过于严格
- 只保留概念名包含查询关键词的结果
- 导致大部分查询返回空数组

解决方案:
 移除字符串匹配过滤逻辑
- Mock 环境直接返回热门概念
- 模拟真实 API 的语义搜索行为
- 确保每次搜索都有结果展示

 添加详细调试日志
- RelatedConceptsSection 组件渲染日志
- useEffect 触发和参数日志
- 请求发送和响应详情
- 数据处理过程追踪

 完善 Mock 数据结构
- 添加 score, match_type, happened_times, stocks
- 支持详细卡片展示
- 数据结构与线上完全一致

修改文件:
- src/mocks/handlers/concept.js
- src/views/Community/components/DynamicNewsDetail/RelatedConceptsSection/index.js

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-11-03 16:40:25 +08:00
parent b95607e9b4
commit b14eb175f5
3 changed files with 207 additions and 21 deletions

View File

@@ -6,6 +6,48 @@ import { http, HttpResponse } from 'msw';
// 模拟延迟
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
// 生成历史触发时间3-5个历史日期
const generateHappenedTimes = (seed) => {
const times = [];
const count = 3 + (seed % 3); // 3-5个时间点
for (let i = 0; i < count; i++) {
const daysAgo = 30 + (seed * 7 + i * 11) % 330; // 30-360天前
const date = new Date();
date.setDate(date.getDate() - daysAgo);
times.push(date.toISOString().split('T')[0]);
}
return times.sort().reverse(); // 降序排列
};
// 生成核心相关股票
const generateStocksForConcept = (seed, count = 4) => {
const stockPool = [
{ name: '贵州茅台', code: '600519' },
{ name: '宁德时代', code: '300750' },
{ name: '中国平安', code: '601318' },
{ name: '比亚迪', code: '002594' },
{ name: '隆基绿能', code: '601012' },
{ name: '阳光电源', code: '300274' },
{ name: '三一重工', code: '600031' },
{ name: '中芯国际', code: '688981' },
{ name: '京东方A', code: '000725' },
{ name: '立讯精密', code: '002475' }
];
const stocks = [];
for (let i = 0; i < count; i++) {
const stockIndex = (seed + i * 7) % stockPool.length;
const stock = stockPool[stockIndex];
stocks.push({
stock_name: stock.name,
stock_code: stock.code,
reason: `作为行业龙头企业,${stock.name}在该领域具有核心竞争优势,市场份额领先,技术实力雄厚。`,
change_pct: parseFloat((Math.random() * 15 - 5).toFixed(2)) // -5% ~ +10%
});
}
return stocks;
};
// 生成热门概念数据
const generatePopularConcepts = (size = 20) => {
const concepts = [
@@ -22,21 +64,38 @@ const generatePopularConcepts = (size = 20) => {
'疫苗', '中药', '医疗信息化', '智慧医疗', '基因测序'
];
const conceptDescriptions = {
'人工智能': '人工智能是"技术突破+政策扶持"双轮驱动的硬科技主题。随着大模型技术的突破AI应用场景不断拓展预计将催化算力、数据、应用三大产业链。',
'新能源汽车': '新能源汽车行业景气度持续向好,渗透率不断提升。政策支持力度大,产业链上下游企业均受益明显。',
'半导体': '国产半导体替代加速,自主可控需求强烈。政策和资金支持力度大,行业迎来黄金发展期。',
'光伏': '光伏装机量快速增长,成本持续下降,行业景气度维持高位。双碳目标下,光伏行业前景广阔。',
'锂电池': '锂电池技术进步,成本优势扩大,下游应用领域持续扩张。新能源汽车和储能需求旺盛。',
'储能': '储能市场爆发式增长,政策支持力度大,应用场景不断拓展。未来市场空间巨大。',
'默认': '该概念市场关注度较高,具有一定的投资价值。相关企业技术实力雄厚,市场前景广阔。'
};
const matchTypes = ['hybrid_knn', 'keyword', 'semantic'];
const results = [];
for (let i = 0; i < Math.min(size, concepts.length); i++) {
const changePct = (Math.random() * 12 - 2).toFixed(2); // -2% 到 +10%
const stockCount = Math.floor(Math.random() * 50) + 10; // 10-60 只股票
const score = parseFloat((Math.random() * 5 + 3).toFixed(2)); // 3-8 分数范围
results.push({
concept: concepts[i],
concept_id: `CONCEPT_${1000 + i}`,
stock_count: stockCount,
score: score, // 相关度分数
match_type: matchTypes[i % 3], // 匹配类型
description: conceptDescriptions[concepts[i]] || conceptDescriptions['默认'],
price_info: {
avg_change_pct: parseFloat(changePct),
avg_price: (Math.random() * 100 + 10).toFixed(2),
total_market_cap: (Math.random() * 1000 + 100).toFixed(2)
avg_price: parseFloat((Math.random() * 100 + 10).toFixed(2)),
total_market_cap: parseFloat((Math.random() * 1000 + 100).toFixed(2))
},
description: `${concepts[i]}相关概念股`,
happened_times: generateHappenedTimes(i), // 历史触发时间
stocks: generateStocksForConcept(i, 4), // 核心相关股票
hot_score: Math.floor(Math.random() * 100)
});
}
@@ -115,15 +174,12 @@ export const conceptHandlers = [
console.log('[Mock Concept] 搜索概念:', { query, size, page, sort_by });
// 生成数据
// 生成数据(不过滤,模拟真实 API 的语义搜索返回热门概念)
let results = generatePopularConcepts(size);
console.log('[Mock Concept] 生成概念数量:', results.length);
// 如果有查询关键词,过滤结果
if (query) {
results = results.filter(item =>
item.concept.toLowerCase().includes(query.toLowerCase())
);
}
// Mock 环境下不做过滤,直接返回热门概念
// 真实环境会根据 query 进行语义搜索
// 根据排序字段排序
if (sort_by === 'change_pct') {