feat: 添加合规内容

This commit is contained in:
zdl
2025-10-15 20:59:27 +08:00
parent 0bc1892086
commit 587e3df20e
3 changed files with 116 additions and 14 deletions

View File

@@ -5,6 +5,7 @@ import ReactECharts from 'echarts-for-react';
import * as echarts from 'echarts';
import moment from 'moment';
import { stockService } from '../../services/eventService';
import CitedContent from '../Citation/CitedContent';
const { Text } = Typography;
@@ -524,12 +525,21 @@ const StockChartAntdModal = ({
</div>
{/* 关联描述 */}
{stock?.relation_desc && (
{stock?.relation_desc?.data ? (
// 使用引用组件(带研报来源)
<CitedContent
data={stock.relation_desc.data}
title="关联描述"
showAIBadge={true}
containerStyle={{ marginTop: 16 }}
/>
) : stock?.relation_desc ? (
// 降级显示(无引用数据)
<div style={{ marginTop: 16, padding: 16, backgroundColor: '#f5f5f5', borderRadius: 6 }}>
<Text strong style={{ display: 'block', marginBottom: 8 }}>关联描述:</Text>
<Text>{stock.relation_desc}AI合成</Text>
</div>
)}
) : null}
{/* 调试信息 */}
{process.env.NODE_ENV === 'development' && chartData && (

View File

@@ -6,7 +6,7 @@ import {
} from 'antd';
import {
StarFilled, StarOutlined, CalendarOutlined, LinkOutlined, StockOutlined,
TagsOutlined, ClockCircleOutlined, InfoCircleOutlined, LockOutlined
TagsOutlined, ClockCircleOutlined, InfoCircleOutlined, LockOutlined, RobotOutlined
} from '@ant-design/icons';
import moment from 'moment';
import ReactMarkdown from 'react-markdown';
@@ -14,6 +14,8 @@ import { eventService, stockService } from '../../../services/eventService';
import StockChartAntdModal from '../../../components/StockChart/StockChartAntdModal';
import { useSubscription } from '../../../hooks/useSubscription';
import SubscriptionUpgradeModal from '../../../components/SubscriptionUpgradeModal';
import CitationMark from '../../../components/Citation/CitationMark';
import { processCitationData } from '../../../utils/citationUtils';
import './InvestmentCalendar.css';
const { TabPane } = Tabs;
@@ -482,6 +484,75 @@ const InvestmentCalendar = () => {
}));
};
// 检查是否有引用数据(可能在 record.reason_citation 或 record[4]
const citationData = record.reason;
const hasCitation = citationData && citationData.data && Array.isArray(citationData.data);
if (hasCitation) {
// 使用引用组件,支持展开/收起
const processed = processCitationData(citationData);
if (processed) {
// 计算所有段落的总长度
const totalLength = processed.segments.reduce((sum, seg) => sum + seg.text.length, 0);
const shouldTruncate = totalLength > 100;
// 确定要显示的段落
let displaySegments = processed.segments;
if (shouldTruncate && !isExpanded) {
// 需要截断:计算应该显示到哪个段落
let charCount = 0;
displaySegments = [];
for (const seg of processed.segments) {
if (charCount + seg.text.length <= 100) {
// 完整显示这个段落
displaySegments.push(seg);
charCount += seg.text.length;
} else {
// 截断这个段落
const remainingChars = 100 - charCount;
if (remainingChars > 0) {
const truncatedText = seg.text.substring(0, remainingChars) + '...';
displaySegments.push({ ...seg, text: truncatedText });
}
break;
}
}
}
return (
<div>
<div style={{ lineHeight: '1.6' }}>
{displaySegments.map((segment, index) => (
<React.Fragment key={segment.citationId}>
<Text>{segment.text}</Text>
<CitationMark
citationId={segment.citationId}
citation={processed.citations[segment.citationId]}
/>
{index < displaySegments.length - 1 && <Text></Text>}
</React.Fragment>
))}
</div>
{shouldTruncate && (
<Button
type="link"
size="small"
onClick={toggleExpanded}
style={{ padding: 0, marginLeft: 4 }}
>
({isExpanded ? '收起' : '展开'})
</Button>
)}
<div style={{ marginTop: 4 }}>
<Text type="secondary" style={{ fontSize: '12px' }}>(AI合成)</Text>
</div>
</div>
);
}
}
// 降级显示:纯文本 + 展开/收起
return (
<div>
<Text>

View File

@@ -33,6 +33,7 @@ import {
import { InfoIcon, ViewIcon } from '@chakra-ui/icons';
import ReactECharts from 'echarts-for-react';
import { eventService } from '../../../services/eventService';
import CitedContent from '../../../components/Citation/CitedContent';
// 节点样式配置 - 完全复刻Flask版本
const NODE_STYLES = {
@@ -896,11 +897,21 @@ const TransmissionChainAnalysis = ({ eventId }) => {
<HStack justify="space-between" align="flex-start">
<VStack align="stretch" spacing={1} flex={1}>
<Text fontWeight="bold" fontSize="sm">{parent.name}</Text>
{parent.transmission_mechanism && (
{parent.transmission_mechanism_citation?.data ? (
<Box fontSize="xs">
<Text as="span" fontWeight="bold">机制: </Text>
<CitedContent
data={parent.transmission_mechanism_citation.data}
title=""
showAIBadge={false}
containerStyle={{ backgroundColor: 'transparent', padding: 0, display: 'inline' }}
/>
</Box>
) : parent.transmission_mechanism ? (
<Text fontSize="xs" color="gray.600">
机制: {parent.transmission_mechanism}AI合成
</Text>
)}
) : null}
</VStack>
<HStack spacing={2}>
<Badge colorScheme={parent.direction === 'positive' ? 'green' : parent.direction === 'negative' ? 'red' : 'gray'} size="sm">
@@ -936,11 +947,21 @@ const TransmissionChainAnalysis = ({ eventId }) => {
<HStack justify="space-between" align="flex-start">
<VStack align="stretch" spacing={1} flex={1}>
<Text fontWeight="bold" fontSize="sm">{child.name}</Text>
{child.transmission_mechanism && (
{child.transmission_mechanism?.data ? (
<Box fontSize="xs">
<Text as="span" fontWeight="bold">机制: </Text>
<CitedContent
data={child.transmission_mechanism.data}
title=""
showAIBadge={false}
containerStyle={{ backgroundColor: 'transparent', padding: 0, display: 'inline' }}
/>
</Box>
) : child.transmission_mechanism ? (
<Text fontSize="xs" color="gray.600">
机制: {child.transmission_mechanism}AI合成
</Text>
)}
) : null}
</VStack>
<HStack spacing={2}>
<Badge colorScheme={child.direction === 'positive' ? 'green' : child.direction === 'negative' ? 'red' : 'gray'} size="sm">