feat: 添加消息推送能力,添加新闻催化分析页的合规提示

This commit is contained in:
zdl
2025-10-21 10:59:52 +08:00
parent 6c96299b8f
commit 5a3a3ad42b
15 changed files with 1800 additions and 125 deletions

View File

@@ -1,7 +1,7 @@
// src/components/Citation/CitedContent.js
import React from 'react';
import { Typography, Space, Tag } from 'antd';
import { RobotOutlined, FileSearchOutlined } from '@ant-design/icons';
import { Typography, Tag } from 'antd';
import { RobotOutlined } from '@ant-design/icons';
import CitationMark from './CitationMark';
import { processCitationData } from '../../utils/citationUtils';
import { logger } from '../../utils/logger';
@@ -9,20 +9,25 @@ import { logger } from '../../utils/logger';
const { Text } = Typography;
/**
* 带引用标注的内容组件
* 带引用标注的内容组件(块级模式)
* 展示拼接的文本每句话后显示上标引用【1】【2】【3】
* 支持鼠标悬浮和点击查看引用来源
* AI 标识统一显示在右上角,不占用布局高度
*
* @param {Object} props
* @param {Object} props.data - API 返回的原始数据 { data: [...] }
* @param {string} props.title - 标题文本,默认 "AI 分析结果"
* @param {boolean} props.showAIBadge - 是否显示 AI 生成标识,默认 true
* @param {string} props.prefix - 内容前的前缀标签,如 "机制:"(可选)
* @param {Object} props.prefixStyle - 前缀标签的自定义样式(可选)
* @param {boolean} props.showAIBadge - 是否显示右上角 AI 标识,默认 true可选
* @param {Object} props.containerStyle - 容器额外样式(可选)
*
* @example
* <CitedContent
* data={apiData}
* title="关联描述"
* prefix="机制:"
* prefixStyle={{ color: '#666' }}
* showAIBadge={true}
* containerStyle={{ marginTop: 16 }}
* />
@@ -30,6 +35,8 @@ const { Text } = Typography;
const CitedContent = ({
data,
title = 'AI 分析结果',
prefix = '',
prefixStyle = {},
showAIBadge = true,
containerStyle = {}
}) => {
@@ -45,59 +52,65 @@ const CitedContent = ({
return null;
}
// 判断是否显示标题栏内联模式title为空且不显示AI徽章
const showHeader = title || showAIBadge;
// 根据是否显示标题栏决定容器样式
const defaultContainerStyle = showHeader ? {
backgroundColor: '#f5f5f5',
borderRadius: 6,
padding: 16
} : {};
// 检查是否为内联模式
const isInlineMode = containerStyle?.display && containerStyle.display.includes('inline');
// 根据内联模式选择容器元素类型
const ContainerTag = isInlineMode ? 'span' : 'div';
const ContentTag = isInlineMode ? 'span' : 'div';
return (
<ContainerTag
<div
style={{
...defaultContainerStyle,
position: 'relative',
width: '100%',
backgroundColor: '#f5f5f5',
borderRadius: 6,
padding: 16,
paddingTop: title ? 16 : 20,
...containerStyle
}}
>
{/* 标题栏 - 仅在需要时显示 */}
{showHeader && (
<Space
{/* AI 标识 - 固定在右上角 */}
{showAIBadge && (
<Tag
icon={<RobotOutlined />}
color="purple"
style={{
width: '100%',
justifyContent: 'space-between',
marginBottom: 12
position: 'absolute',
top: 12,
right: 12,
margin: 0,
zIndex: 10,
fontSize: 12,
padding: '2px 8px'
}}
className="ai-badge-responsive"
>
<Space>
<FileSearchOutlined style={{ color: '#1890ff', fontSize: 16 }} />
<Text strong style={{ fontSize: 14 }}>
{title}
</Text>
</Space>
{showAIBadge && (
<Tag
icon={<RobotOutlined />}
color="purple"
style={{ margin: 0 }}
>
AI 生成
</Tag>
)}
</Space>
AI合成
</Tag>
)}
{/* 标题栏 */}
{title && (
<div style={{ marginBottom: 12, paddingRight: 80 }}>
<Text strong style={{ fontSize: 14 }}>
{title}
</Text>
</div>
)}
{/* 带引用的文本内容 */}
<ContentTag style={{ lineHeight: isInlineMode ? 'inherit' : 1.8 }}>
<div style={{
lineHeight: 1.8,
paddingRight: title ? 0 : (showAIBadge ? 80 : 0)
}}>
{/* 前缀标签(如果有) */}
{prefix && (
<Text style={{
fontSize: 14,
fontWeight: 'bold',
display: 'inline',
marginRight: 4,
...prefixStyle
}}>
{prefix}
</Text>
)}
{processed.segments.map((segment, index) => (
<React.Fragment key={`segment-${segment.citationId}`}>
{/* 文本片段 */}
@@ -117,8 +130,18 @@ const CitedContent = ({
)}
</React.Fragment>
))}
</ContentTag>
</ContainerTag>
</div>
{/* 响应式样式 */}
<style jsx>{`
@media (max-width: 768px) {
.ai-badge-responsive {
font-size: 10px !important;
padding: 1px 6px !important;
}
}
`}</style>
</div>
);
};