update pay function
This commit is contained in:
@@ -137,6 +137,10 @@ const ConceptTimelineModal = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 获取新闻(精确匹配,最近100天,最多100条)
|
// 获取新闻(精确匹配,最近100天,最多100条)
|
||||||
|
// 🔄 添加回退逻辑:如果结果不足30条,去掉 exact_match 参数重新搜索
|
||||||
|
const fetchNews = async () => {
|
||||||
|
try {
|
||||||
|
// 第一次尝试:使用精确匹配
|
||||||
const newsParams = new URLSearchParams({
|
const newsParams = new URLSearchParams({
|
||||||
query: conceptName,
|
query: conceptName,
|
||||||
exact_match: 1,
|
exact_match: 1,
|
||||||
@@ -146,24 +150,58 @@ const ConceptTimelineModal = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
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) {
|
if (!res.ok) {
|
||||||
const text = await res.text();
|
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) });
|
logger.error('ConceptTimelineModal', 'fetchTimelineData - News API (exact_match=1)', new Error(`HTTP ${res.status}`), { conceptName, status: res.status, response: text.substring(0, 200) });
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return res.json();
|
|
||||||
})
|
const newsResult = await res.json();
|
||||||
.catch(err => {
|
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 });
|
logger.error('ConceptTimelineModal', 'fetchTimelineData - News API', err, { conceptName });
|
||||||
return [];
|
return [];
|
||||||
})
|
}
|
||||||
);
|
};
|
||||||
|
|
||||||
|
promises.push(fetchNews());
|
||||||
|
|
||||||
// 获取研报(文本模式、精确匹配,最近100天,最多30条)
|
// 获取研报(文本模式、精确匹配,最近100天,最多30条)
|
||||||
|
// 🔄 添加回退逻辑:如果结果不足10条,去掉 exact_match 参数重新搜索
|
||||||
|
const fetchReports = async () => {
|
||||||
|
try {
|
||||||
|
// 第一次尝试:使用精确匹配
|
||||||
const reportParams = new URLSearchParams({
|
const reportParams = new URLSearchParams({
|
||||||
query: conceptName,
|
query: conceptName,
|
||||||
mode: 'text',
|
mode: 'text',
|
||||||
@@ -173,22 +211,56 @@ const ConceptTimelineModal = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
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) {
|
if (!res.ok) {
|
||||||
const text = await res.text();
|
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) });
|
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: [] };
|
return { results: [] };
|
||||||
}
|
}
|
||||||
return res.json();
|
|
||||||
})
|
const reportResult = await res.json();
|
||||||
.catch(err => {
|
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 });
|
logger.error('ConceptTimelineModal', 'fetchTimelineData - Report API', err, { conceptName });
|
||||||
return { results: [] };
|
return { results: [] };
|
||||||
})
|
}
|
||||||
);
|
};
|
||||||
|
|
||||||
|
promises.push(fetchReports());
|
||||||
|
|
||||||
const [priceResult, newsResult, reportResult] = await Promise.all(promises);
|
const [priceResult, newsResult, reportResult] = await Promise.all(promises);
|
||||||
|
|
||||||
|
|||||||
@@ -819,7 +819,9 @@ const StockCard = ({ stock, idx }) => {
|
|||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
<ModalCloseButton color="#eacd76" top={3} right={3} />
|
<ModalCloseButton color="#eacd76" top={3} right={3} />
|
||||||
<ModalBody p={6} bg={useColorModeValue('white', 'gray.800')}>
|
<ModalBody p={6} bg={useColorModeValue('white', 'gray.800')}>
|
||||||
<Box fontSize="md" color="#222" lineHeight={1.9} whiteSpace="pre-line" dangerouslySetInnerHTML={{ __html: (stock.summary || '').replace(/<br\s*\/?>(\s*)/g, '\n').replace(/\n{2,}/g, '\n').replace(/\n/g, '<br/>') }} />
|
<Box fontSize="md" color="#222" lineHeight={1.9} whiteSpace="pre-wrap">
|
||||||
|
{(stock.summary || '').replace(/<br\s*\/?>/gi, '\n')}
|
||||||
|
</Box>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter bg={useColorModeValue('white', 'gray.800')} justifyContent="center">
|
<ModalFooter bg={useColorModeValue('white', 'gray.800')} justifyContent="center">
|
||||||
<Button onClick={onClose} colorScheme="yellow" borderRadius="md" px={8} fontWeight="bold">关闭</Button>
|
<Button onClick={onClose} colorScheme="yellow" borderRadius="md" px={8} fontWeight="bold">关闭</Button>
|
||||||
|
|||||||
Reference in New Issue
Block a user