132 lines
4.6 KiB
TypeScript
132 lines
4.6 KiB
TypeScript
import type {
|
|
AgentDetailReplacementReferenceItem,
|
|
AgentModeReferenceCandidate,
|
|
AgentModeWorkspaceState,
|
|
AgentWorkflowMaterialQueryType,
|
|
} from "@/types/agent";
|
|
|
|
export function createEmptyAgentModeWorkspaceState(): AgentModeWorkspaceState {
|
|
return {
|
|
detailReplacement: {
|
|
query: "",
|
|
queryType: "spu",
|
|
candidates: [],
|
|
selectedCandidateId: null,
|
|
references: [],
|
|
},
|
|
skuReplacement: {
|
|
query: "",
|
|
queryType: "sku",
|
|
candidates: [],
|
|
selectedCandidateId: null,
|
|
references: [],
|
|
},
|
|
};
|
|
}
|
|
|
|
function normalizeReferenceItems(value: unknown): AgentDetailReplacementReferenceItem[] {
|
|
if (!Array.isArray(value)) return [];
|
|
return value
|
|
.map((item, index) => {
|
|
const raw =
|
|
item && typeof item === "object" && !Array.isArray(item)
|
|
? (item as Record<string, unknown>)
|
|
: {};
|
|
const id = String(raw.id || "").trim() || `reference-${index + 1}`;
|
|
const label = String(raw.label || "").trim() || `参考图 ${index + 1}`;
|
|
const imageUrl = String(raw.imageUrl || "").trim() || null;
|
|
return {
|
|
id,
|
|
label,
|
|
imageUrl,
|
|
candidateId: String(raw.candidateId || "").trim() || null,
|
|
sortOrder: Number.isFinite(Number(raw.sortOrder))
|
|
? Math.max(0, Math.min(999, Math.round(Number(raw.sortOrder))))
|
|
: index,
|
|
assignedProductIndex: Number.isFinite(Number(raw.assignedProductIndex))
|
|
? Math.max(0, Math.min(9, Math.round(Number(raw.assignedProductIndex))))
|
|
: null,
|
|
};
|
|
})
|
|
.filter((item) => Boolean(item.id));
|
|
}
|
|
|
|
function normalizeQueryType(value: unknown, fallback: AgentWorkflowMaterialQueryType) {
|
|
return value === "sku" || value === "spu" ? value : fallback;
|
|
}
|
|
|
|
function normalizeCandidate(value: unknown, index: number): AgentModeReferenceCandidate | null {
|
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
return null;
|
|
}
|
|
|
|
const raw = value as Record<string, unknown>;
|
|
const normalizeUrlList = (input: unknown) =>
|
|
Array.isArray(input)
|
|
? Array.from(
|
|
new Set(
|
|
input
|
|
.map((item) => String(item || "").trim())
|
|
.filter((item) => /^https?:\/\//i.test(item))
|
|
)
|
|
).slice(0, 64)
|
|
: [];
|
|
|
|
const id = String(raw.id || "").trim() || `candidate-${index + 1}`;
|
|
|
|
return {
|
|
id,
|
|
materialId: String(raw.materialId || "").trim() || null,
|
|
taskNo: String(raw.taskNo || "").trim() || null,
|
|
productModel: String(raw.productModel || "").trim() || null,
|
|
categoryName: String(raw.categoryName || "").trim() || null,
|
|
shopName: String(raw.shopName || "").trim() || null,
|
|
sceneName: String(raw.sceneName || "").trim() || null,
|
|
uploadedAt: String(raw.uploadedAt || "").trim() || null,
|
|
isFullSet: raw.isFullSet !== false,
|
|
mainImageUrls: normalizeUrlList(raw.mainImageUrls),
|
|
skuImageUrls: normalizeUrlList(raw.skuImageUrls),
|
|
detailImageUrls: normalizeUrlList(raw.detailImageUrls),
|
|
allImageUrls: normalizeUrlList(raw.allImageUrls),
|
|
};
|
|
}
|
|
|
|
function normalizeCandidates(value: unknown): AgentModeReferenceCandidate[] {
|
|
if (!Array.isArray(value)) return [];
|
|
return value
|
|
.map((item, index) => normalizeCandidate(item, index))
|
|
.filter((item): item is AgentModeReferenceCandidate => Boolean(item));
|
|
}
|
|
|
|
export function normalizeAgentModeWorkspaceState(value: unknown): AgentModeWorkspaceState {
|
|
const raw =
|
|
value && typeof value === "object" && !Array.isArray(value)
|
|
? (value as Record<string, unknown>)
|
|
: {};
|
|
const detailRaw =
|
|
raw.detailReplacement && typeof raw.detailReplacement === "object" && !Array.isArray(raw.detailReplacement)
|
|
? (raw.detailReplacement as Record<string, unknown>)
|
|
: {};
|
|
const skuRaw =
|
|
raw.skuReplacement && typeof raw.skuReplacement === "object" && !Array.isArray(raw.skuReplacement)
|
|
? (raw.skuReplacement as Record<string, unknown>)
|
|
: {};
|
|
|
|
return {
|
|
detailReplacement: {
|
|
query: String(detailRaw.query || detailRaw.spuQuery || "").trim(),
|
|
queryType: normalizeQueryType(detailRaw.queryType, "spu"),
|
|
candidates: normalizeCandidates(detailRaw.candidates),
|
|
selectedCandidateId: String(detailRaw.selectedCandidateId || "").trim() || null,
|
|
references: normalizeReferenceItems(detailRaw.references),
|
|
},
|
|
skuReplacement: {
|
|
query: String(skuRaw.query || skuRaw.spuQuery || "").trim(),
|
|
queryType: normalizeQueryType(skuRaw.queryType, "sku"),
|
|
candidates: normalizeCandidates(skuRaw.candidates),
|
|
selectedCandidateId: String(skuRaw.selectedCandidateId || "").trim() || null,
|
|
references: normalizeReferenceItems(skuRaw.references),
|
|
},
|
|
};
|
|
}
|