feat: 添加消息推送能力,添加新闻催化分析页的合规提示
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user