fix: streamline detail reference template lookup
This commit is contained in:
parent
824806406a
commit
84f105d4c8
@ -33,6 +33,7 @@ const querySchema = z.object({
|
||||
target: z.enum(["main", "detail", "sku"]),
|
||||
brandName: z.string().trim().max(64).optional(),
|
||||
channel: productDetailChannelSchema,
|
||||
strictQueryType: z.enum(["true", "false", "1", "0"]).optional(),
|
||||
});
|
||||
|
||||
function jsonNoStore(
|
||||
@ -854,6 +855,8 @@ export async function GET(request: NextRequest) {
|
||||
target: request.nextUrl.searchParams.get("target"),
|
||||
brandName: request.nextUrl.searchParams.get("brandName") || undefined,
|
||||
channel: request.nextUrl.searchParams.get("channel") || undefined,
|
||||
strictQueryType:
|
||||
request.nextUrl.searchParams.get("strictQueryType") || undefined,
|
||||
});
|
||||
|
||||
const setting = await getSystemSetting({ key: AGENT_WORKFLOW_MATERIAL_API_CONFIG_KEY });
|
||||
@ -928,12 +931,15 @@ export async function GET(request: NextRequest) {
|
||||
});
|
||||
}
|
||||
|
||||
const queryTypesToTry = Array.from(
|
||||
new Set<AgentWorkflowMaterialQueryType>([
|
||||
materialQueryType,
|
||||
materialQueryType === "spu" ? "sku" : "spu",
|
||||
])
|
||||
);
|
||||
const strictQueryType = parsed.strictQueryType === "true" || parsed.strictQueryType === "1";
|
||||
const queryTypesToTry = strictQueryType
|
||||
? [materialQueryType]
|
||||
: Array.from(
|
||||
new Set<AgentWorkflowMaterialQueryType>([
|
||||
materialQueryType,
|
||||
materialQueryType === "spu" ? "sku" : "spu",
|
||||
])
|
||||
);
|
||||
|
||||
let selectedAttempt:
|
||||
| Awaited<ReturnType<typeof requestTaskDetailAttempt>>
|
||||
|
||||
@ -1609,6 +1609,14 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
[getLatestWorkflowContext, workflowContext]
|
||||
);
|
||||
const workflowBrandName = getCurrentWorkflowBrandName();
|
||||
const getCurrentWorkflowPrimarySpu = useCallback(
|
||||
() =>
|
||||
String((getLatestWorkflowContext?.() ?? workflowContext)?.primarySku || "")
|
||||
.trim(),
|
||||
[getLatestWorkflowContext, workflowContext]
|
||||
);
|
||||
const workflowPrimarySpu = getCurrentWorkflowPrimarySpu();
|
||||
const normalizedWorkflowPrimarySpu = workflowPrimarySpu.toUpperCase();
|
||||
const shouldAllowModelOverride =
|
||||
!isWorkflowModelLocked &&
|
||||
(isDirectModelGenerationMode || !isSceneGenerationPreset || presetModeConfig.scene.allowModelOverride);
|
||||
@ -4836,19 +4844,6 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
setPendingGeneration(null);
|
||||
}
|
||||
}
|
||||
const handleDetailReplacementQueryTypeChange = useCallback(
|
||||
(queryType: AgentWorkflowReferenceQueryType) => {
|
||||
updateDetailReplacementState((current) => ({
|
||||
...current,
|
||||
queryType,
|
||||
candidates: current.queryType === queryType ? current.candidates : [],
|
||||
selectedCandidateId:
|
||||
current.queryType === queryType ? current.selectedCandidateId : null,
|
||||
references: current.queryType === queryType ? current.references : [],
|
||||
}));
|
||||
},
|
||||
[updateDetailReplacementState]
|
||||
);
|
||||
const handleDetailReplacementProductDetailChannelChange = useCallback(
|
||||
(channel: AgentWorkflowProductDetailChannel) => {
|
||||
updateDetailReplacementState((current) => ({
|
||||
@ -4960,25 +4955,22 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
},
|
||||
[detailReplacementReferenceCards.length, updateDetailReplacementState]
|
||||
);
|
||||
const handleDetailReplacementSearch = useCallback(async () => {
|
||||
const handleDetailReplacementSearch = useCallback(async (
|
||||
queryType: Extract<AgentWorkflowReferenceQueryType, "spu" | "productId">
|
||||
) => {
|
||||
const rawPrimarySpu = getCurrentWorkflowPrimarySpu();
|
||||
const normalized =
|
||||
detailReplacementQueryType === "productId"
|
||||
? detailReplacementQueryInput.trim()
|
||||
: detailReplacementQueryInput.trim().toUpperCase();
|
||||
queryType === "productId" ? rawPrimarySpu.trim() : rawPrimarySpu.trim().toUpperCase();
|
||||
const currentWorkflowBrandName = getCurrentWorkflowBrandName();
|
||||
if (!currentWorkflowBrandName && detailReplacementQueryType !== "productId") {
|
||||
toast.error("请先在第一步完成品牌选择后再查询参考图");
|
||||
if (!currentWorkflowBrandName && queryType !== "productId") {
|
||||
toast.error("请先在第一步完成品牌选择后再检索可用模版");
|
||||
return;
|
||||
}
|
||||
if (!normalized) {
|
||||
toast.error(
|
||||
`请输入${
|
||||
detailReplacementQueryType === "productId"
|
||||
? "商品ID"
|
||||
: detailReplacementQueryType === "sku"
|
||||
? "SKU"
|
||||
: "SPU"
|
||||
}后再查询${detailReferenceSourceLabel}`
|
||||
queryType === "productId"
|
||||
? "请先在第一步输入主商品市场ID后再查询详情"
|
||||
: "请先在第一步输入主商品SPU后再检索可用模版"
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -4991,14 +4983,16 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
try {
|
||||
const searchParams = new URLSearchParams({
|
||||
keyword: normalized,
|
||||
queryType: detailReplacementQueryType,
|
||||
queryType,
|
||||
target: detailReferenceTarget,
|
||||
});
|
||||
if (currentWorkflowBrandName) {
|
||||
searchParams.set("brandName", currentWorkflowBrandName);
|
||||
}
|
||||
if (detailReplacementQueryType === "productId") {
|
||||
if (queryType === "productId") {
|
||||
searchParams.set("channel", detailReplacementProductDetailChannel);
|
||||
} else {
|
||||
searchParams.set("strictQueryType", "true");
|
||||
}
|
||||
const response = await fetch(
|
||||
`/api/agent-workflow/reference-search?${searchParams.toString()}`,
|
||||
@ -5012,7 +5006,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
|
||||
updateDetailReplacementState({
|
||||
query: normalized,
|
||||
queryType: result.data.queryType || detailReplacementQueryType,
|
||||
queryType: result.data.queryType || queryType,
|
||||
productDetailChannel:
|
||||
result.data.channel || detailReplacementProductDetailChannel,
|
||||
candidates: result.data.candidates || [],
|
||||
@ -5036,8 +5030,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
detailReferenceSourceLabel,
|
||||
detailReferenceTarget,
|
||||
detailReplacementProductDetailChannel,
|
||||
detailReplacementQueryInput,
|
||||
detailReplacementQueryType,
|
||||
getCurrentWorkflowPrimarySpu,
|
||||
getCurrentWorkflowBrandName,
|
||||
updateDetailReplacementState,
|
||||
]);
|
||||
@ -6241,87 +6234,79 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
</div>
|
||||
|
||||
<div className="space-y-4 p-5">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{([
|
||||
["spu", "按SPU查询"],
|
||||
["sku", "按SKU查询"],
|
||||
["productId", "按商品ID查询"],
|
||||
] as Array<[AgentWorkflowReferenceQueryType, string]>).map(([queryType, label]) => (
|
||||
<button
|
||||
key={queryType}
|
||||
type="button"
|
||||
onClick={() => handleDetailReplacementQueryTypeChange(queryType)}
|
||||
className={cn(
|
||||
"rounded-full border px-3 py-1.5 text-xs transition-colors",
|
||||
detailReplacementQueryType === queryType
|
||||
? "border-emerald-400/45 bg-emerald-500/[0.12] text-emerald-200"
|
||||
: "border-white/10 bg-white/[0.03] text-white/58 hover:border-white/18 hover:text-white"
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
))}
|
||||
<input
|
||||
ref={detailReferenceUploadInputRef}
|
||||
type="file"
|
||||
accept="image/*"
|
||||
multiple
|
||||
className="hidden"
|
||||
onChange={handleDetailReferenceUploadChange}
|
||||
/>
|
||||
<div className="rounded-[24px] border border-white/10 bg-black/20 p-4">
|
||||
<div className="flex flex-col gap-4 xl:flex-row xl:items-center xl:justify-between">
|
||||
<div className="min-w-0">
|
||||
<div className="text-xs text-white/42">
|
||||
自动复用第一步主商品信息检索参考详情,不需要重复输入 SPU / SKU。
|
||||
</div>
|
||||
<div className="mt-2 flex flex-wrap gap-2">
|
||||
<span className="rounded-full border border-emerald-400/20 bg-emerald-500/[0.08] px-3 py-1 text-xs text-emerald-100">
|
||||
主 SPU / {normalizedWorkflowPrimarySpu || "未填写"}
|
||||
</span>
|
||||
<span className="rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs text-white/60">
|
||||
品牌 / {workflowBrandName || "未选择"}
|
||||
</span>
|
||||
<span className="rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-xs text-white/60">
|
||||
目标 / {detailReferenceSourceLabel}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2 sm:flex-row">
|
||||
<Select
|
||||
value={detailReplacementProductDetailChannel}
|
||||
onValueChange={(value) =>
|
||||
handleDetailReplacementProductDetailChannelChange(
|
||||
value as AgentWorkflowProductDetailChannel
|
||||
)
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="h-12 rounded-[22px] border-white/10 bg-black/20 text-sm text-white focus:border-emerald-400/30 sm:w-[150px]">
|
||||
<SelectValue placeholder="渠道" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{PRODUCT_DETAIL_CHANNEL_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => handleDetailReplacementSearch("productId")}
|
||||
disabled={detailReplacementSearchState.isLoading}
|
||||
className="h-12 rounded-[22px] bg-white/[0.04] px-5 text-sm text-white hover:bg-white/[0.08]"
|
||||
>
|
||||
{detailReplacementSearchState.isLoading ? (
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
) : null}
|
||||
市场ID查询详情
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => handleDetailReplacementSearch("spu")}
|
||||
disabled={detailReplacementSearchState.isLoading}
|
||||
className="h-12 rounded-[22px] bg-emerald-500 px-5 font-semibold text-sm text-black shadow-[0_0_24px_rgba(16,185,129,0.22)] hover:bg-emerald-400"
|
||||
>
|
||||
{detailReplacementSearchState.isLoading ? (
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
) : null}
|
||||
检索可用模版
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2 lg:flex-row">
|
||||
<input
|
||||
ref={detailReferenceUploadInputRef}
|
||||
type="file"
|
||||
accept="image/*"
|
||||
multiple
|
||||
className="hidden"
|
||||
onChange={handleDetailReferenceUploadChange}
|
||||
/>
|
||||
{detailReplacementQueryType === "productId" ? (
|
||||
<Select
|
||||
value={detailReplacementProductDetailChannel}
|
||||
onValueChange={(value) =>
|
||||
handleDetailReplacementProductDetailChannelChange(
|
||||
value as AgentWorkflowProductDetailChannel
|
||||
)
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="h-12 rounded-[22px] border-white/10 bg-black/20 text-sm text-white focus:border-emerald-400/30 lg:w-[150px]">
|
||||
<SelectValue placeholder="渠道" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{PRODUCT_DETAIL_CHANNEL_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
) : null}
|
||||
<Input
|
||||
value={detailReplacementQueryInput}
|
||||
onChange={(e) =>
|
||||
updateDetailReplacementState({
|
||||
query: e.target.value,
|
||||
})
|
||||
}
|
||||
placeholder={
|
||||
detailReplacementQueryType === "productId"
|
||||
? "输入商品ID,查询并拉取详情图片"
|
||||
: `输入 ${detailReplacementQueryType === "sku" ? "SKU" : "SPU"},查询任务整套中的${detailReferenceSourceLabel}参考图`
|
||||
}
|
||||
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-12 rounded-[22px] bg-white/[0.04] px-5 text-sm text-white hover:bg-white/[0.08]"
|
||||
>
|
||||
{detailReplacementSearchState.isLoading ? (
|
||||
<>
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
查询中
|
||||
</>
|
||||
) : (
|
||||
`查询${detailReferenceSourceLabel}`
|
||||
)}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
@ -6897,7 +6882,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
<div className="flex min-h-[220px] flex-col items-center justify-center rounded-[22px] border border-dashed border-white/12 bg-black/20 px-5 text-center">
|
||||
<div className="text-sm font-medium text-white/72">等待{detailReferenceSourceLabel}参考图</div>
|
||||
<div className="mt-2 text-xs leading-6 text-white/40">
|
||||
输入 SPU 或 SKU 后,这里会展示任务整套里的真实{detailReferenceSourceLabel}参考图。
|
||||
点击“检索可用模版”后,这里会展示当前品牌下主 SPU 对应的真实{detailReferenceSourceLabel}参考图。
|
||||
删除不需要的参考图后,列表会自动上移补位。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user