Files
AIclinicalresearch/frontend/src/components/review/ScoreCard.tsx
HaHafeng 0fe6821a89 feat(frontend): add batch processing and review features
- Add batch processing API and mode
- Add deep read mode for full-text analysis
- Add document selector and switcher components
- Add review page with editorial and methodology assessment
- Add capacity indicator and usage info modal
- Add custom hooks for batch tasks and chat modes
- Update layouts and routing
- Add TypeScript types for chat features
2025-11-16 15:43:39 +08:00

123 lines
2.5 KiB
TypeScript

import { Card, Progress, Space, Typography, Tag } from 'antd';
import { TrophyOutlined, CheckCircleOutlined, WarningOutlined, CloseCircleOutlined } from '@ant-design/icons';
import { getScoreLevel } from '../../api/reviewApi';
const { Title, Text } = Typography;
interface ScoreCardProps {
title: string;
score: number;
maxScore?: number;
description?: string;
showProgress?: boolean;
size?: 'small' | 'default' | 'large';
}
/**
* 评分卡片组件
* 用于展示单项评分
*/
const ScoreCard = ({
title,
score,
maxScore = 100,
description,
showProgress = true,
size = 'default',
}: ScoreCardProps) => {
const { level, text, color } = getScoreLevel(score);
// 获取等级图标
const getLevelIcon = () => {
switch (level) {
case 'excellent':
return <TrophyOutlined style={{ color }} />;
case 'good':
return <CheckCircleOutlined style={{ color }} />;
case 'fair':
return <WarningOutlined style={{ color }} />;
case 'poor':
return <CloseCircleOutlined style={{ color }} />;
}
};
// 根据size调整字体大小
const scoreFontSize = size === 'large' ? 56 : size === 'small' ? 32 : 44;
const titleSize = size === 'large' ? 3 : size === 'small' ? 5 : 4;
return (
<Card hoverable>
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
{/* 标题 */}
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Title level={titleSize as 3 | 4 | 5} style={{ margin: 0 }}>
{title}
</Title>
<Tag icon={getLevelIcon()} color={color} style={{ margin: 0 }}>
{text}
</Tag>
</div>
{/* 分数 */}
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: scoreFontSize, fontWeight: 'bold', color }}>
{score.toFixed(1)}
</div>
<Text type="secondary" style={{ fontSize: size === 'small' ? 12 : 14 }}>
{maxScore}
</Text>
</div>
{/* 进度条 */}
{showProgress && (
<Progress
percent={Math.round((score / maxScore) * 100)}
strokeColor={color}
status="active"
/>
)}
{/* 描述 */}
{description && (
<Text type="secondary" style={{ fontSize: 12 }}>
{description}
</Text>
)}
</Space>
</Card>
);
};
export default ScoreCard;