fix: streamline detail candidate search layout
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-03-22 21:56:41 +08:00
parent 1826cbf6b8
commit 6e493cf589

View File

@ -27,6 +27,7 @@ import {
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import {
Select,
@ -2417,7 +2418,7 @@ export function AgentGenerationWorkspaceDarkV2({
</div>
<div className="mb-3 flex flex-col gap-2 sm:flex-row">
<Textarea
<Input
value={detailReplacementQueryInput}
onChange={(e) =>
updateDetailReplacementState({
@ -2426,13 +2427,13 @@ export function AgentGenerationWorkspaceDarkV2({
})
}
placeholder={`输入 SPU,查询任务整套中的${detailReferenceSourceLabel}参考图`}
className="min-h-[56px] resize-none rounded-[22px] border-white/10 bg-black/20 text-sm text-white placeholder:text-white/22 focus:border-emerald-400/30"
className="h-12 rounded-[22px] border-white/10 bg-black/20 text-sm text-white placeholder:text-white/22 focus:border-emerald-400/30"
/>
<Button
type="button"
onClick={handleDetailReplacementSearch}
disabled={detailReplacementSearchState.isLoading}
className="h-14 rounded-[22px] bg-white/[0.04] px-5 text-sm text-white hover:bg-white/[0.08]"
className="h-12 rounded-[22px] bg-white/[0.04] px-5 text-sm text-white hover:bg-white/[0.08]"
>
{detailReplacementSearchState.isLoading ? (
<>
@ -2448,7 +2449,7 @@ export function AgentGenerationWorkspaceDarkV2({
type="button"
variant="outline"
onClick={handleClearDetailReferenceCards}
className="h-14 rounded-[22px] border-white/10 bg-white/[0.03] px-5 text-sm text-white hover:bg-white/[0.08]"
className="h-12 rounded-[22px] border-white/10 bg-white/[0.03] px-5 text-sm text-white hover:bg-white/[0.08]"
>
清空参考图
</Button>
@ -2480,7 +2481,7 @@ export function AgentGenerationWorkspaceDarkV2({
默认载入最新一套,可随时切换
</div>
</div>
<div className="agent-dark-scrollbar grid max-h-[360px] grid-cols-2 gap-3 overflow-y-auto pr-1 xl:grid-cols-4">
<div className="agent-dark-scrollbar grid max-h-[360px] grid-cols-1 gap-3 overflow-y-auto pr-1 xl:grid-cols-2">
{detailReplacementCandidates.map((candidate) => {
const isSelected = detailReplacementSelectedCandidateId === candidate.id;
const previewUrls = getCandidatePreviewUrls(
@ -2488,6 +2489,7 @@ export function AgentGenerationWorkspaceDarkV2({
detailReferenceTarget,
4
);
const primaryPreviewUrl = previewUrls[0] || getCandidatePreviewUrl(candidate, detailReferenceTarget);
return (
<button
key={candidate.id}
@ -2500,55 +2502,52 @@ export function AgentGenerationWorkspaceDarkV2({
: "border-white/10 bg-white/[0.03] hover:border-white/18"
)}
>
<div className="relative overflow-hidden bg-[radial-gradient(circle_at_top,rgba(16,185,129,0.18),transparent_58%),linear-gradient(180deg,#0b0d0f_0%,#11161a_100%)] p-2.5">
<div className="grid grid-cols-2 gap-2">
{Array.from({ length: 4 }).map((_, previewIndex) => {
const previewUrl = previewUrls[previewIndex];
return (
<div
key={`${candidate.id}-preview-${previewIndex}`}
className="aspect-[3/4] overflow-hidden rounded-[14px] border border-white/8 bg-black/20"
>
{previewUrl ? (
<img
src={buildPreviewImageUrl(previewUrl, 360)}
alt={`${candidate.sceneName || candidate.taskNo || candidate.productModel || "候选整套"} 预览 ${previewIndex + 1}`}
className="h-full w-full object-cover object-top"
/>
) : (
<div className="h-full w-full bg-[linear-gradient(180deg,rgba(255,255,255,0.03),rgba(255,255,255,0.01))]" />
)}
</div>
);
})}
</div>
<div className="absolute left-3 top-3 rounded-full border border-white/10 bg-black/45 px-2.5 py-1 text-[11px] text-white/78">
{getCandidateTargetCount(candidate, detailReferenceTarget)} 张{detailReferenceSourceLabel}
</div>
{isSelected ? (
<div className="absolute right-3 top-3 rounded-full border border-emerald-300/35 bg-emerald-500/[0.14] px-2.5 py-1 text-[11px] text-emerald-100">
当前使用
<div className="flex items-stretch gap-3 bg-[radial-gradient(circle_at_top,rgba(16,185,129,0.18),transparent_58%),linear-gradient(180deg,#0b0d0f_0%,#11161a_100%)] p-3">
<div className="relative w-[112px] shrink-0 overflow-hidden rounded-[16px] border border-white/8 bg-black/20 sm:w-[124px]">
<div className="aspect-[3/4]">
{primaryPreviewUrl ? (
<img
src={buildPreviewImageUrl(primaryPreviewUrl, 360)}
alt={candidate.sceneName || candidate.taskNo || candidate.productModel || "候选整套"}
className="h-full w-full object-cover object-top"
/>
) : (
<div className="h-full w-full bg-[linear-gradient(180deg,rgba(255,255,255,0.03),rgba(255,255,255,0.01))]" />
)}
</div>
<div className="absolute left-2 top-2 rounded-full border border-white/10 bg-black/50 px-2 py-0.5 text-[10px] text-white/78">
{getCandidateTargetCount(candidate, detailReferenceTarget)} 张
</div>
) : null}
</div>
<div className="space-y-2 px-3 py-3">
<div className="truncate text-[13px] font-medium text-white">
{candidate.sceneName || candidate.taskNo || candidate.productModel || "候选整套"}
</div>
<div className="line-clamp-2 text-[11px] leading-5 text-white/42">
{formatCandidateMeta(candidate, detailReferenceTarget) || `点击切换这套${detailReferenceSourceLabel}参考图`}
</div>
<div className="flex flex-wrap gap-1.5 text-[11px] text-white/48">
{candidate.shopName ? (
<span className="rounded-full bg-white/[0.05] px-2 py-1">
{candidate.shopName}
</span>
) : null}
{candidate.categoryName ? (
<span className="rounded-full bg-white/[0.05] px-2 py-1">
{candidate.categoryName}
</span>
) : null}
<div className="min-w-0 flex-1 py-1">
<div className="flex items-start justify-between gap-2">
<div className="truncate text-sm font-medium text-white">
{candidate.sceneName || candidate.taskNo || candidate.productModel || "候选整套"}
</div>
{isSelected ? (
<div className="shrink-0 rounded-full border border-emerald-300/35 bg-emerald-500/[0.14] px-2.5 py-1 text-[11px] text-emerald-100">
当前使用
</div>
) : null}
</div>
<div className="mt-2 line-clamp-3 text-[12px] leading-6 text-white/46">
{formatCandidateMeta(candidate, detailReferenceTarget) || `点击切换这套${detailReferenceSourceLabel}参考图`}
</div>
<div className="mt-3 flex flex-wrap gap-1.5 text-[11px] text-white/48">
{candidate.shopName ? (
<span className="rounded-full bg-white/[0.05] px-2 py-1">
{candidate.shopName}
</span>
) : null}
{candidate.categoryName ? (
<span className="rounded-full bg-white/[0.05] px-2 py-1">
{candidate.categoryName}
</span>
) : null}
</div>
<div className="mt-3 text-[11px] text-emerald-200/72">
点击后下方直接展开这套详情每一屏
</div>
</div>
</div>
</button>
@ -2851,7 +2850,7 @@ export function AgentGenerationWorkspaceDarkV2({
</div>
<div className="mb-3 flex flex-col gap-2 sm:flex-row">
<Textarea
<Input
value={skuReplacementQueryInput}
onChange={(e) =>
updateSkuReplacementState({
@ -2859,13 +2858,13 @@ export function AgentGenerationWorkspaceDarkV2({
})
}
placeholder={`输入${skuReplacementQueryType === "spu" ? "SPU" : "SKU"},查询任务整套中的${skuReferenceSourceLabel}参考图`}
className="min-h-[56px] resize-none rounded-[22px] border-white/10 bg-black/20 text-sm text-white placeholder:text-white/22 focus:border-emerald-400/30"
className="h-12 rounded-[22px] border-white/10 bg-black/20 text-sm text-white placeholder:text-white/22 focus:border-emerald-400/30"
/>
<Button
type="button"
onClick={handleSkuReplacementSearch}
disabled={skuReplacementSearchState.isLoading}
className="h-14 rounded-[22px] bg-white/[0.04] px-5 text-sm text-white hover:bg-white/[0.08]"
className="h-12 rounded-[22px] bg-white/[0.04] px-5 text-sm text-white hover:bg-white/[0.08]"
>
{skuReplacementSearchState.isLoading ? (
<>
@ -2881,7 +2880,7 @@ export function AgentGenerationWorkspaceDarkV2({
type="button"
variant="outline"
onClick={handleClearSkuReferenceCards}
className="h-14 rounded-[22px] border-white/10 bg-white/[0.03] px-5 text-sm text-white hover:bg-white/[0.08]"
className="h-12 rounded-[22px] border-white/10 bg-white/[0.03] px-5 text-sm text-white hover:bg-white/[0.08]"
>
清空参考图
</Button>