fix: enable full preview in review flows

This commit is contained in:
yangqianqian
2026-07-01 13:49:28 +08:00
parent 033ef89536
commit a634fcbea2
4 changed files with 89 additions and 21 deletions

View File

@@ -3,8 +3,11 @@
* ReviewCard — 单条待审笔记卡
* 通过(+5) / 打回(-3必填原因)
*/
import { useState } from 'react';
import { ReviewQueueItem } from '@/types/index';
import { ImageLightbox } from '@/components/tasks/ImageLightbox';
import { ScoreDimBars } from '@/components/tasks/ScoreDimBars';
import { TextLightbox } from '@/components/tasks/TextLightbox';
interface ReviewCardProps {
item: ReviewQueueItem;
@@ -14,6 +17,13 @@ interface ReviewCardProps {
export function ReviewCard({ item, onApprove, onReject }: ReviewCardProps) {
const sets = item.selected_sets?.filter((s) => s.selected_text || s.selected_images.length) ?? [];
const [zoomText, setZoomText] = useState<{
content: string;
label?: string;
score?: number;
} | null>(null);
const [zoomImage, setZoomImage] = useState<{ url: string; caption?: string } | null>(null);
return (
<article
className="border border-border-default rounded-xl bg-surface-primary p-4"
@@ -28,9 +38,18 @@ export function ReviewCard({ item, onApprove, onReject }: ReviewCardProps) {
</div>
<h3 className="font-medium text-text-primary text-sm line-clamp-1">{item.theme}</h3>
{sets.length === 0 && item.selected_text && (
<p className="text-xs text-text-secondary mt-1 line-clamp-2">
{item.selected_text.content}
</p>
<button
type="button"
onClick={() => setZoomText({
content: item.selected_text!.content,
label: item.selected_text!.angle_label,
score: item.selected_text!.score?.total,
})}
className="mt-1 block w-full text-left text-xs text-text-secondary hover:text-brand-orange"
>
<span className="line-clamp-2">{item.selected_text.content}</span>
<span className="mt-1 block text-[11px] text-text-tertiary"></span>
</button>
)}
{/* 质量分:审核可判断(C2)。合格线80=红线,不用组件默认85 */}
{sets.length === 0 && item.selected_text?.score && (
@@ -38,8 +57,18 @@ export function ReviewCard({ item, onApprove, onReject }: ReviewCardProps) {
)}
</div>
{sets.length === 0 && item.selected_image && (
<img src={item.selected_image.url} alt="已选图预览"
className="w-16 h-16 rounded-lg object-cover flex-shrink-0" />
<button
type="button"
onClick={() => setZoomImage({
url: item.selected_image!.url,
caption: `已选图 · 套${item.selected_image!.strategy}`,
})}
className="w-16 h-16 rounded-lg overflow-hidden flex-shrink-0 cursor-zoom-in"
aria-label="放大已选图"
>
<img src={item.selected_image.url} alt="已选图预览"
className="h-full w-full object-cover" />
</button>
)}
</div>
@@ -53,9 +82,18 @@ export function ReviewCard({ item, onApprove, onReject }: ReviewCardProps) {
</div>
{set.selected_text && (
<>
<p className="text-xs text-text-secondary line-clamp-2">
{set.selected_text.content}
</p>
<button
type="button"
onClick={() => setZoomText({
content: set.selected_text!.content,
label: `${set.strategy} · ${set.selected_text!.angle_label}`,
score: set.selected_text!.score?.total,
})}
className="block w-full text-left text-xs text-text-secondary hover:text-brand-orange"
>
<span className="line-clamp-2">{set.selected_text.content}</span>
<span className="mt-1 block text-[11px] text-text-tertiary"></span>
</button>
{set.selected_text.score && (
<ScoreDimBars score={set.selected_text.score} passLine={80} />
)}
@@ -64,12 +102,22 @@ export function ReviewCard({ item, onApprove, onReject }: ReviewCardProps) {
{set.selected_images.length > 0 && (
<div className="mt-2 flex gap-2 overflow-x-auto">
{set.selected_images.filter(Boolean).map((img) => (
<img
<button
key={img!.candidate_id}
src={img!.url}
alt={`${set.strategy}已选图`}
className="h-16 w-12 flex-shrink-0 rounded-md object-cover"
/>
type="button"
onClick={() => setZoomImage({
url: img!.url,
caption: `${set.strategy}${img!.role ? ` · ${img!.role}` : ''}`,
})}
className="h-16 w-12 flex-shrink-0 cursor-zoom-in overflow-hidden rounded-md"
aria-label={`放大套${set.strategy}已选图`}
>
<img
src={img!.url}
alt={`${set.strategy}已选图`}
className="h-full w-full object-cover"
/>
</button>
))}
</div>
)}
@@ -91,6 +139,17 @@ export function ReviewCard({ item, onApprove, onReject }: ReviewCardProps) {
+
</button>
</div>
<TextLightbox
text={zoomText?.content ?? null}
label={zoomText?.label}
score={zoomText?.score}
onClose={() => setZoomText(null)}
/>
<ImageLightbox
url={zoomImage?.url ?? null}
caption={zoomImage?.caption}
onClose={() => setZoomImage(null)}
/>
</article>
);
}