错题处理失败时直接显示具体错误信息。
This commit is contained in:
@@ -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 && (
|
||||
|
||||
@@ -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 识别与标注,请核对后再使用"
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user