import { createApiClient } from "../lib/apiClient"; import type { LabelElement, LabelTemplateCreateInput, LabelTemplateDto, LabelTemplateGetListInput, LabelTemplateProductDefaultDto, LabelTemplateUpdateInput, PagedResultDto, } from "../types/labelTemplate"; const api = createApiClient({ getToken: () => { try { return localStorage.getItem("access_token") ?? localStorage.getItem("token") ?? null; } catch { return null; } }, }); const PATH = "/label-template"; function normalizeTemplateCode(raw: unknown): string { const r = raw as Record | null | undefined; if (!r || typeof r !== "object") return ""; const id = r.id ?? r.templateCode ?? r.TemplateCode; return typeof id === "string" ? id.trim() : String(id ?? "").trim(); } /** 详情/列表里的 elements 兼容 PascalCase(如 InputKey) */ function normalizeTemplateElements(list: unknown): LabelElement[] { if (!Array.isArray(list)) return []; return list.map((raw) => { const e = raw as Record & { InputKey?: unknown; inputKey?: unknown; ElementName?: unknown; elementName?: unknown; LibraryCategory?: unknown; libraryCategory?: unknown; }; const ik = e.inputKey ?? e.InputKey; const nameRaw = e.elementName ?? e.ElementName; const lcRaw = e.libraryCategory ?? e.LibraryCategory; let libraryCategory: LabelElement["libraryCategory"]; if (typeof lcRaw === "string") { const t = lcRaw.trim(); if (t) libraryCategory = t; } return { ...(e as object), elementName: typeof nameRaw === "string" ? nameRaw.trim() : undefined, inputKey: typeof ik === "string" ? ik : e.inputKey ?? null, libraryCategory, config: (e.config && typeof e.config === "object" ? e.config : {}) as LabelElement["config"], } as LabelElement; }); } function normalizeDefaultValuesJson(raw: unknown): Record { if (raw == null || typeof raw !== "object" || Array.isArray(raw)) return {}; const out: Record = {}; for (const [k, v] of Object.entries(raw as Record)) { if (v == null) out[k] = ""; else if (typeof v === "string") out[k] = v; else if (typeof v === "number" || typeof v === "boolean") out[k] = String(v); else out[k] = JSON.stringify(v); } return out; } function normalizeTemplateProductDefaultsList(raw: unknown): LabelTemplateProductDefaultDto[] { if (!Array.isArray(raw)) return []; return raw.map((item, index) => { const o = item as Record; const dv = o.defaultValues ?? o.DefaultValues ?? o.defaultValuesJson ?? o.DefaultValuesJson; return { productId: String(o.productId ?? o.ProductId ?? "").trim(), labelTypeId: String(o.labelTypeId ?? o.LabelTypeId ?? "").trim(), defaultValues: normalizeDefaultValuesJson(dv), orderNum: Number(o.orderNum ?? o.OrderNum ?? index + 1) || index + 1, }; }); } function normalizeLabelTemplateDto(raw: unknown): LabelTemplateDto { const r = raw as Record; const ids = (Array.isArray(r.appliedLocationIds) ? r.appliedLocationIds : null) ?? (Array.isArray(r.AppliedLocationIds) ? r.AppliedLocationIds : null) ?? []; const appliedLocationIds = ids.map((x) => String(x)); const id = normalizeTemplateCode(raw); const templateNameVo = r.templateName ?? r.TemplateName; const templateCodeVo = r.templateCode ?? r.TemplateCode; const locationTextVo = r.locationText ?? r.LocationText; const sizeTextVo = r.sizeText ?? r.SizeText; const ccRaw = r.contentsCount ?? r.ContentsCount; const contentsCountVo = typeof ccRaw === "number" ? ccRaw : undefined; const lastEditedVo = r.lastEdited ?? r.LastEdited; const nameFromList = (typeof r.name === "string" && r.name.trim() ? r.name : null) ?? (typeof templateNameVo === "string" && String(templateNameVo).trim() ? String(templateNameVo) : null); return { ...(r as object), id, name: nameFromList ?? (r.name as LabelTemplateDto["name"]), templateName: (typeof templateNameVo === "string" ? templateNameVo : null) ?? (r.templateName as string | null), templateCode: (typeof templateCodeVo === "string" ? templateCodeVo : null) ?? (r.templateCode as string | null), locationText: (typeof locationTextVo === "string" ? locationTextVo : null) ?? (r.locationText as string | null), sizeText: (typeof sizeTextVo === "string" ? sizeTextVo : null) ?? (r.sizeText as string | null), contentsCount: contentsCountVo ?? (r.contentsCount as number | null), lastEdited: (typeof lastEditedVo === "string" ? lastEditedVo : null) ?? (r.lastEdited as string | null), appliedLocationIds, elements: normalizeTemplateElements(r.elements), templateProductDefaults: normalizeTemplateProductDefaultsList( r.templateProductDefaults ?? r.TemplateProductDefaults, ), } as LabelTemplateDto; } export async function getLabelTemplates(input: LabelTemplateGetListInput, signal?: AbortSignal): Promise> { const res = await api.requestJson>({ path: PATH, method: "GET", query: { SkipCount: input.skipCount, MaxResultCount: input.maxResultCount, Sorting: input.sorting, Keyword: input.keyword, LocationId: input.locationId, LabelType: input.labelType, State: input.state, }, signal, }); const items = (res.items ?? []).map((x) => normalizeLabelTemplateDto(x)); return { ...res, items }; } export async function getLabelTemplate(templateCode: string, signal?: AbortSignal): Promise { const raw = await api.requestJson({ path: `${PATH}/${encodeURIComponent(templateCode)}`, method: "GET", signal, }); return normalizeLabelTemplateDto(raw); } export async function createLabelTemplate(input: LabelTemplateCreateInput): Promise { const created = await api.requestJson({ path: PATH, method: "POST", body: { id: input.id, name: input.name, labelType: input.labelType, unit: input.unit, width: input.width, height: input.height, appliedLocation: input.appliedLocation, showRuler: input.showRuler ?? true, showGrid: input.showGrid ?? true, state: input.state ?? true, elements: input.elements, appliedLocationIds: input.appliedLocationIds ?? [], }, }); return normalizeLabelTemplateDto(created); } export async function updateLabelTemplate(templateCode: string, input: LabelTemplateUpdateInput): Promise { const body: Record = { id: input.id, name: input.name, labelType: input.labelType, unit: input.unit, width: input.width, height: input.height, appliedLocation: input.appliedLocation, showRuler: input.showRuler ?? true, showGrid: input.showGrid ?? true, state: input.state ?? true, elements: input.elements, appliedLocationIds: input.appliedLocationIds ?? [], }; if (input.templateProductDefaults !== undefined) { body.templateProductDefaults = input.templateProductDefaults.map((row, i) => ({ productId: row.productId, labelTypeId: row.labelTypeId, defaultValues: row.defaultValues, orderNum: row.orderNum ?? i + 1, })); } const updated = await api.requestJson({ path: `${PATH}/${encodeURIComponent(templateCode)}`, method: "PUT", body, }); return normalizeLabelTemplateDto(updated); } export async function deleteLabelTemplate(templateCode: string): Promise { await api.requestJson({ path: `${PATH}/${encodeURIComponent(templateCode)}`, method: "DELETE", }); }