diff --git a/src/views/Concept/ConceptTimelineModal.js b/src/views/Concept/ConceptTimelineModal.js
index 51c35ec6..b876d28c 100644
--- a/src/views/Concept/ConceptTimelineModal.js
+++ b/src/views/Concept/ConceptTimelineModal.js
@@ -137,58 +137,130 @@ const ConceptTimelineModal = ({
);
// 获取新闻(精确匹配,最近100天,最多100条)
- const newsParams = new URLSearchParams({
- query: conceptName,
- exact_match: 1,
- start_date: startDateStr,
- end_date: endDateStr,
- top_k: 100
- });
+ // 🔄 添加回退逻辑:如果结果不足30条,去掉 exact_match 参数重新搜索
+ const fetchNews = async () => {
+ try {
+ // 第一次尝试:使用精确匹配
+ const newsParams = new URLSearchParams({
+ query: conceptName,
+ exact_match: 1,
+ start_date: startDateStr,
+ end_date: endDateStr,
+ top_k: 100
+ });
- const newsUrl = `${NEWS_API_URL}/search_china_news?${newsParams}`;
+ const newsUrl = `${NEWS_API_URL}/search_china_news?${newsParams}`;
+ const res = await fetch(newsUrl);
- promises.push(
- fetch(newsUrl)
- .then(async res => {
- if (!res.ok) {
- const text = await res.text();
- logger.error('ConceptTimelineModal', 'fetchTimelineData - News API', new Error(`HTTP ${res.status}`), { conceptName, status: res.status, response: text.substring(0, 200) });
- return [];
- }
- return res.json();
- })
- .catch(err => {
- logger.error('ConceptTimelineModal', 'fetchTimelineData - News API', err, { conceptName });
+ if (!res.ok) {
+ const text = await res.text();
+ logger.error('ConceptTimelineModal', 'fetchTimelineData - News API (exact_match=1)', new Error(`HTTP ${res.status}`), { conceptName, status: res.status, response: text.substring(0, 200) });
return [];
- })
- );
+ }
+
+ const newsResult = await res.json();
+ const newsArray = Array.isArray(newsResult) ? newsResult : [];
+
+ // 检查结果数量,如果不足30条则进行回退搜索
+ if (newsArray.length < 30) {
+ logger.info('ConceptTimelineModal', `新闻精确搜索结果不足30条 (${newsArray.length}),尝试模糊搜索`, { conceptName });
+
+ // 第二次尝试:去掉精确匹配参数
+ const fallbackParams = new URLSearchParams({
+ query: conceptName,
+ start_date: startDateStr,
+ end_date: endDateStr,
+ top_k: 100
+ });
+
+ const fallbackUrl = `${NEWS_API_URL}/search_china_news?${fallbackParams}`;
+ const fallbackRes = await fetch(fallbackUrl);
+
+ if (!fallbackRes.ok) {
+ logger.warn('ConceptTimelineModal', '新闻模糊搜索失败,使用精确搜索结果', { conceptName });
+ return newsArray;
+ }
+
+ const fallbackResult = await fallbackRes.json();
+ const fallbackArray = Array.isArray(fallbackResult) ? fallbackResult : [];
+
+ logger.info('ConceptTimelineModal', `新闻模糊搜索成功,获取 ${fallbackArray.length} 条结果`, { conceptName });
+ return fallbackArray;
+ }
+
+ return newsArray;
+ } catch (err) {
+ logger.error('ConceptTimelineModal', 'fetchTimelineData - News API', err, { conceptName });
+ return [];
+ }
+ };
+
+ promises.push(fetchNews());
// 获取研报(文本模式、精确匹配,最近100天,最多30条)
- const reportParams = new URLSearchParams({
- query: conceptName,
- mode: 'text',
- exact_match: 1,
- size: 30,
- start_date: startDateStr
- });
+ // 🔄 添加回退逻辑:如果结果不足10条,去掉 exact_match 参数重新搜索
+ const fetchReports = async () => {
+ try {
+ // 第一次尝试:使用精确匹配
+ const reportParams = new URLSearchParams({
+ query: conceptName,
+ mode: 'text',
+ exact_match: 1,
+ size: 30,
+ start_date: startDateStr
+ });
- const reportUrl = `${REPORT_API_URL}/search?${reportParams}`;
+ const reportUrl = `${REPORT_API_URL}/search?${reportParams}`;
+ const res = await fetch(reportUrl);
- promises.push(
- fetch(reportUrl)
- .then(async res => {
- if (!res.ok) {
- const text = await res.text();
- logger.error('ConceptTimelineModal', 'fetchTimelineData - Report API', new Error(`HTTP ${res.status}`), { conceptName, status: res.status, response: text.substring(0, 200) });
- return { results: [] };
- }
- return res.json();
- })
- .catch(err => {
- logger.error('ConceptTimelineModal', 'fetchTimelineData - Report API', err, { conceptName });
+ if (!res.ok) {
+ const text = await res.text();
+ logger.error('ConceptTimelineModal', 'fetchTimelineData - Report API (exact_match=1)', new Error(`HTTP ${res.status}`), { conceptName, status: res.status, response: text.substring(0, 200) });
return { results: [] };
- })
- );
+ }
+
+ const reportResult = await res.json();
+ const reports = (reportResult.data && Array.isArray(reportResult.data.results))
+ ? reportResult.data.results
+ : (Array.isArray(reportResult.results) ? reportResult.results : []);
+
+ // 检查结果数量,如果不足10条则进行回退搜索
+ if (reports.length < 10) {
+ logger.info('ConceptTimelineModal', `研报精确搜索结果不足10条 (${reports.length}),尝试模糊搜索`, { conceptName });
+
+ // 第二次尝试:去掉精确匹配参数
+ const fallbackParams = new URLSearchParams({
+ query: conceptName,
+ mode: 'text',
+ size: 30,
+ start_date: startDateStr
+ });
+
+ const fallbackUrl = `${REPORT_API_URL}/search?${fallbackParams}`;
+ const fallbackRes = await fetch(fallbackUrl);
+
+ if (!fallbackRes.ok) {
+ logger.warn('ConceptTimelineModal', '研报模糊搜索失败,使用精确搜索结果', { conceptName });
+ return { results: reports };
+ }
+
+ const fallbackResult = await fallbackRes.json();
+ const fallbackReports = (fallbackResult.data && Array.isArray(fallbackResult.data.results))
+ ? fallbackResult.data.results
+ : (Array.isArray(fallbackResult.results) ? fallbackResult.results : []);
+
+ logger.info('ConceptTimelineModal', `研报模糊搜索成功,获取 ${fallbackReports.length} 条结果`, { conceptName });
+ return { results: fallbackReports };
+ }
+
+ return { results: reports };
+ } catch (err) {
+ logger.error('ConceptTimelineModal', 'fetchTimelineData - Report API', err, { conceptName });
+ return { results: [] };
+ }
+ };
+
+ promises.push(fetchReports());
const [priceResult, newsResult, reportResult] = await Promise.all(promises);
diff --git a/src/views/EventDetail/components/LimitAnalyse.js b/src/views/EventDetail/components/LimitAnalyse.js
index 0c180f9f..6732efdb 100644
--- a/src/views/EventDetail/components/LimitAnalyse.js
+++ b/src/views/EventDetail/components/LimitAnalyse.js
@@ -819,7 +819,9 @@ const StockCard = ({ stock, idx }) => {
- (\s*)/g, '\n').replace(/\n{2,}/g, '\n').replace(/\n/g, '
') }} />
+
+ {(stock.summary || '').replace(/
/gi, '\n')}
+