更新Company页面的UI为FUI风格
This commit is contained in:
@@ -26,7 +26,8 @@ import { getApiBase } from '@utils/apiConfig';
|
||||
/**
|
||||
* 相关概念区组件
|
||||
* @param {Object} props
|
||||
* @param {string} props.eventTitle - 事件标题(用于搜索概念)
|
||||
* @param {number} props.eventId - 事件ID(用于获取 related_concepts 表数据)
|
||||
* @param {string} props.eventTitle - 事件标题(备用,当 eventId 不存在时使用搜索)
|
||||
* @param {string} props.effectiveTradingDate - 有效交易日期(涨跌幅数据日期)
|
||||
* @param {string|Object} props.eventTime - 事件发生时间
|
||||
* @param {React.ReactNode} props.subscriptionBadge - 订阅徽章组件(可选)
|
||||
@@ -34,6 +35,7 @@ import { getApiBase } from '@utils/apiConfig';
|
||||
* @param {Function} props.onLockedClick - 锁定时的点击回调(触发付费弹窗)
|
||||
*/
|
||||
const RelatedConceptsSection = ({
|
||||
eventId,
|
||||
eventTitle,
|
||||
effectiveTradingDate,
|
||||
eventTime,
|
||||
@@ -57,6 +59,7 @@ const RelatedConceptsSection = ({
|
||||
const textColor = useColorModeValue('gray.600', 'gray.400');
|
||||
|
||||
console.log('[RelatedConceptsSection] 组件渲染', {
|
||||
eventId,
|
||||
eventTitle,
|
||||
effectiveTradingDate,
|
||||
eventTime,
|
||||
@@ -65,16 +68,76 @@ const RelatedConceptsSection = ({
|
||||
error
|
||||
});
|
||||
|
||||
// 搜索相关概念
|
||||
// 获取相关概念 - 优先使用 eventId 从数据库获取
|
||||
useEffect(() => {
|
||||
const searchConcepts = async () => {
|
||||
const fetchConcepts = async () => {
|
||||
console.log('[RelatedConceptsSection] useEffect 触发', {
|
||||
eventId,
|
||||
eventTitle,
|
||||
effectiveTradingDate
|
||||
});
|
||||
|
||||
// 优先使用 eventId 获取数据库中的相关概念
|
||||
if (eventId) {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const apiUrl = `${getApiBase()}/api/events/${eventId}/concepts`;
|
||||
console.log('[RelatedConceptsSection] 从数据库获取相关概念', { url: apiUrl });
|
||||
|
||||
const response = await fetch(apiUrl, {
|
||||
method: 'GET',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include'
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
// 如果是 403,说明需要订阅,不是错误
|
||||
if (response.status === 403) {
|
||||
console.log('[RelatedConceptsSection] 需要订阅才能查看');
|
||||
setConcepts([]);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('[RelatedConceptsSection] 数据库响应', data);
|
||||
|
||||
if (data.success && Array.isArray(data.data)) {
|
||||
// 转换数据格式,使其与原有展示逻辑兼容
|
||||
const formattedConcepts = data.data.map(item => ({
|
||||
concept: item.concept,
|
||||
reason: item.reason,
|
||||
concept_code: item.concept_code,
|
||||
// 保留原有字段以兼容 DetailedConceptCard
|
||||
score: 1, // 数据库中的都是高相关度
|
||||
description: item.reason, // reason 作为描述
|
||||
stocks: [], // 暂无股票数据
|
||||
stock_count: 0
|
||||
}));
|
||||
console.log('[RelatedConceptsSection] 设置概念数据', formattedConcepts);
|
||||
setConcepts(formattedConcepts);
|
||||
} else {
|
||||
setConcepts([]);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[RelatedConceptsSection] 获取概念失败', err);
|
||||
logger.error('RelatedConceptsSection', 'fetchConcepts', err);
|
||||
setError('加载概念数据失败');
|
||||
setConcepts([]);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 降级方案:使用 eventTitle 搜索概念(兼容旧逻辑)
|
||||
if (!eventTitle || !effectiveTradingDate) {
|
||||
console.log('[RelatedConceptsSection] 缺少必要参数,跳过搜索', {
|
||||
hasEventId: !!eventId,
|
||||
hasEventTitle: !!eventTitle,
|
||||
hasEffectiveTradingDate: !!effectiveTradingDate
|
||||
});
|
||||
@@ -86,19 +149,14 @@ const RelatedConceptsSection = ({
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
// 格式化交易日期 - 统一使用 moment 处理
|
||||
// 格式化交易日期
|
||||
let formattedTradeDate;
|
||||
try {
|
||||
// 不管传入的是什么格式,都用 moment 解析并格式化为 YYYY-MM-DD
|
||||
formattedTradeDate = dayjs(effectiveTradingDate).format('YYYY-MM-DD');
|
||||
|
||||
// 验证日期是否有效
|
||||
if (!dayjs(formattedTradeDate, 'YYYY-MM-DD', true).isValid()) {
|
||||
console.warn('[RelatedConceptsSection] 无效日期,使用当前日期');
|
||||
formattedTradeDate = dayjs().format('YYYY-MM-DD');
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('[RelatedConceptsSection] 日期格式化失败,使用当前日期', error);
|
||||
formattedTradeDate = dayjs().format('YYYY-MM-DD');
|
||||
}
|
||||
|
||||
@@ -111,67 +169,37 @@ const RelatedConceptsSection = ({
|
||||
};
|
||||
|
||||
const apiUrl = `${getApiBase()}/concept-api/search`;
|
||||
console.log('[RelatedConceptsSection] 发送请求', {
|
||||
url: apiUrl,
|
||||
requestBody
|
||||
});
|
||||
logger.debug('RelatedConceptsSection', '搜索概念', requestBody);
|
||||
console.log('[RelatedConceptsSection] 降级:使用搜索接口', { url: apiUrl, requestBody });
|
||||
|
||||
const response = await fetch(apiUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(requestBody)
|
||||
});
|
||||
|
||||
console.log('[RelatedConceptsSection] 响应状态', {
|
||||
ok: response.ok,
|
||||
status: response.status,
|
||||
statusText: response.statusText
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('[RelatedConceptsSection] 响应数据', {
|
||||
hasResults: !!data.results,
|
||||
resultsCount: data.results?.length || 0,
|
||||
hasDataConcepts: !!(data.data && data.data.concepts),
|
||||
data: data
|
||||
});
|
||||
logger.debug('RelatedConceptsSection', '概念搜索响应', {
|
||||
hasResults: !!data.results,
|
||||
resultsCount: data.results?.length || 0
|
||||
});
|
||||
|
||||
// 设置概念数据
|
||||
if (data.results && Array.isArray(data.results)) {
|
||||
console.log('[RelatedConceptsSection] 设置概念数据 (results)', data.results);
|
||||
setConcepts(data.results);
|
||||
} else if (data.data && data.data.concepts) {
|
||||
// 向后兼容
|
||||
console.log('[RelatedConceptsSection] 设置概念数据 (data.concepts)', data.data.concepts);
|
||||
setConcepts(data.data.concepts);
|
||||
} else {
|
||||
console.log('[RelatedConceptsSection] 没有找到概念数据,设置为空数组');
|
||||
setConcepts([]);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[RelatedConceptsSection] 搜索概念失败', err);
|
||||
logger.error('RelatedConceptsSection', 'searchConcepts', err);
|
||||
setError('加载概念数据失败');
|
||||
setConcepts([]);
|
||||
} finally {
|
||||
console.log('[RelatedConceptsSection] 加载完成');
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
searchConcepts();
|
||||
}, [eventTitle, effectiveTradingDate]);
|
||||
fetchConcepts();
|
||||
}, [eventId, eventTitle, effectiveTradingDate]);
|
||||
|
||||
// 加载中状态
|
||||
if (loading) {
|
||||
|
||||
Reference in New Issue
Block a user