错题处理失败时直接显示具体错误信息。

This commit is contained in:
dekun
2026-06-28 13:54:43 +08:00
parent a2a6d59f7c
commit a145f38606
9 changed files with 159 additions and 106 deletions
+54 -33
View File
@@ -1,5 +1,5 @@
import { DeleteOutlined } from '@ant-design/icons'
import { Button, Popconfirm, Tag, Typography, message } from 'antd'
import { Button, Popconfirm, Space, Tag, Typography, message } from 'antd'
import { wrongQuestionApi } from '../api/client'
import type { WrongQuestion } from '../types'
import { STATUS_LABELS } from '../types'
@@ -14,6 +14,19 @@ interface Props {
emptyText?: string
}
function cardSummary(wq: WrongQuestion): { tone: 'error' | 'pending' | 'normal'; text: string } {
if (wq.error_message) {
return { tone: 'error', text: wq.error_message }
}
if (wq.status === 'pending') {
return { tone: 'pending', text: '正在识别、标注并生成解题思路…' }
}
return {
tone: 'normal',
text: wq.question_text || wq.ocr_raw_text || STATUS_LABELS[wq.status],
}
}
export default function WrongQuestionList({
items,
selectedId,
@@ -35,40 +48,48 @@ export default function WrongQuestionList({
return (
<>
<div className="wq-grid">
{items.map((wq) => (
<div key={wq.id} className="wq-card">
<div className="wq-card-click" onClick={() => onSelect(wq.id)}>
<AuthenticatedImage questionId={wq.id} variant="annotated" alt="题目" className="wq-card-img" />
<div className="wq-card-body">
<Typography.Text strong>{wq.subject_name}</Typography.Text>
{wq.category === 'olympiad' && (
<Tag color="gold" style={{ marginLeft: 4 }}>
</Tag>
)}
<Typography.Text type="secondary" style={{ fontSize: 12, marginLeft: 8 }}>
{STATUS_LABELS[wq.status]}
</Typography.Text>
<Typography.Paragraph ellipsis={{ rows: 2 }} style={{ margin: '8px 0 0', fontSize: 13 }}>
{wq.question_text || wq.ocr_raw_text || '处理中…'}
</Typography.Paragraph>
{items.map((wq) => {
const summary = cardSummary(wq)
return (
<div key={wq.id} className="wq-card">
<div className="wq-card-click" onClick={() => onSelect(wq.id)}>
<AuthenticatedImage questionId={wq.id} variant="annotated" alt="题目" className="wq-card-img" />
<div className="wq-card-body">
<Space size={4} wrap>
<Typography.Text strong>{wq.subject_name}</Typography.Text>
{wq.category === 'olympiad' && <Tag color="gold"></Tag>}
<Tag color={wq.error_message || wq.status === 'failed' ? 'error' : wq.status === 'pending' ? 'processing' : 'default'}>
{wq.error_message ? '失败' : STATUS_LABELS[wq.status]}
</Tag>
</Space>
<Typography.Paragraph
ellipsis={{ rows: 3 }}
style={{
margin: '8px 0 0',
fontSize: 13,
color: summary.tone === 'error' ? '#ff4d4f' : summary.tone === 'pending' ? '#1677ff' : undefined,
}}
>
{summary.text}
</Typography.Paragraph>
</div>
</div>
<div className="wq-card-actions">
<Popconfirm title="确定删除该题?" onConfirm={() => handleDelete(wq.id)}>
<Button
type="text"
danger
size="small"
icon={<DeleteOutlined />}
onClick={(e) => e.stopPropagation()}
>
</Button>
</Popconfirm>
</div>
</div>
<div className="wq-card-actions">
<Popconfirm title="确定删除该题?" onConfirm={() => handleDelete(wq.id)}>
<Button
type="text"
danger
size="small"
icon={<DeleteOutlined />}
onClick={(e) => e.stopPropagation()}
>
</Button>
</Popconfirm>
</div>
</div>
))}
)
})}
</div>
{items.length === 0 && <Typography.Text type="secondary">{emptyText}</Typography.Text>}
{selectedId && (
+13 -1
View File
@@ -135,10 +135,22 @@ export default function WrongQuestionDetail({
<>
<Space wrap style={{ marginBottom: 8 }}>
<Typography.Text type="secondary">{STATUS_LABELS[wq.status]}</Typography.Text>
{wq.has_annotated_image && (
{wq.has_annotated_image && !wq.error_message && (
<Typography.Text type="danger"></Typography.Text>
)}
</Space>
{wq.error_message && (
<Alert
message="处理失败"
description={wq.error_message}
type="error"
showIcon
style={{ marginBottom: 12 }}
/>
)}
{wq.status === 'pending' && !wq.error_message && (
<Alert message="正在识别、标注并生成解题思路,请稍候…" type="info" showIcon style={{ marginBottom: 12 }} />
)}
{(wq.solution_approach || wq.solution_text) && (
<Alert
message="AI 识别与标注,请核对后再使用"
+1
View File
@@ -114,6 +114,7 @@ export interface WrongQuestion {
solution_text: string | null
mark_regions: MarkRegion[] | null
has_annotated_image: boolean
error_message: string | null
status: WrongQuestionStatus
created_at: string
}