|
|
|
@@ -15,7 +15,8 @@ export interface JobOrderListItem { |
|
|
|
lotNo: string | null; |
|
|
|
defaultShelfLifeDays?: number | null; |
|
|
|
useMinus18?: boolean | null; |
|
|
|
expiryDate?: string | null; |
|
|
|
/** ISO `yyyy-MM-dd`, or Jackson date array `[yyyy,M,d]`. */ |
|
|
|
expiryDate?: string | number[] | null; |
|
|
|
bagPrintedQty?: number; |
|
|
|
labelPrintedQty?: number; |
|
|
|
laserPrintedQty?: number; |
|
|
|
@@ -114,6 +115,39 @@ export async function fetchLaserBag2Settings(): Promise<LaserBag2Settings> { |
|
|
|
return res.json() as Promise<LaserBag2Settings>; |
|
|
|
} |
|
|
|
|
|
|
|
/** List API may return LocalDate as `"2026-08-27"` or `[2026,8,27]` (@EnableWebMvc raw Jackson). */ |
|
|
|
export function expiryDateForLaserSend(value: unknown): string | null { |
|
|
|
if (value == null || value === "") return null; |
|
|
|
if (typeof value === "string") { |
|
|
|
const s = value.trim(); |
|
|
|
if (!s) return null; |
|
|
|
if (/^\d{4}-\d{2}-\d{2}/.test(s)) return s.slice(0, 10); |
|
|
|
return s; |
|
|
|
} |
|
|
|
if (Array.isArray(value) && value.length >= 3) { |
|
|
|
const y = Number(value[0]); |
|
|
|
const m = Number(value[1]); |
|
|
|
const d = Number(value[2]); |
|
|
|
if (!Number.isFinite(y) || !Number.isFinite(m) || !Number.isFinite(d) || y < 1 || m < 1 || d < 1) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
return `${y}-${String(m).padStart(2, "0")}-${String(d).padStart(2, "0")}`; |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
function messageFromLaserSendBody(data: Record<string, unknown>, status: number): string { |
|
|
|
const message = typeof data.message === "string" ? data.message.trim() : ""; |
|
|
|
if (message) return message; |
|
|
|
const detail = typeof data.detail === "string" ? data.detail.trim() : ""; |
|
|
|
if (detail) return detail; |
|
|
|
const error = typeof data.error === "string" ? data.error.trim() : ""; |
|
|
|
if (error) return error; |
|
|
|
const traceId = typeof data.traceId === "string" ? data.traceId.trim() : ""; |
|
|
|
if (traceId) return `送出失敗(traceId ${traceId})`; |
|
|
|
return `送出失敗(HTTP ${status})`; |
|
|
|
} |
|
|
|
|
|
|
|
export async function sendLaserBag2Job(body: LaserBag2SendRequest): Promise<LaserBag2SendResponse> { |
|
|
|
const url = `${NEXT_PUBLIC_API_URL}/plastic/print-laser-bag2`; |
|
|
|
const res = await clientAuthFetch(url, { |
|
|
|
@@ -121,11 +155,29 @@ export async function sendLaserBag2Job(body: LaserBag2SendRequest): Promise<Lase |
|
|
|
headers: { "Content-Type": "application/json" }, |
|
|
|
body: JSON.stringify(body), |
|
|
|
}); |
|
|
|
const data = (await res.json()) as LaserBag2SendResponse; |
|
|
|
if (!res.ok) { |
|
|
|
return data; |
|
|
|
let data: Record<string, unknown> = {}; |
|
|
|
try { |
|
|
|
const text = await res.text(); |
|
|
|
data = text ? (JSON.parse(text) as Record<string, unknown>) : {}; |
|
|
|
} catch { |
|
|
|
return { success: false, message: `送出失敗(HTTP ${res.status},無法解析回應)` }; |
|
|
|
} |
|
|
|
return data; |
|
|
|
if (!res.ok || data.success === false) { |
|
|
|
return { |
|
|
|
success: false, |
|
|
|
message: messageFromLaserSendBody(data, res.status), |
|
|
|
payloadSent: typeof data.payloadSent === "string" ? data.payloadSent : null, |
|
|
|
printerAck: typeof data.printerAck === "string" ? data.printerAck : null, |
|
|
|
receiveAcknowledged: Boolean(data.receiveAcknowledged), |
|
|
|
}; |
|
|
|
} |
|
|
|
return { |
|
|
|
success: true, |
|
|
|
message: typeof data.message === "string" && data.message.trim() ? data.message : "已送出", |
|
|
|
payloadSent: typeof data.payloadSent === "string" ? data.payloadSent : null, |
|
|
|
printerAck: typeof data.printerAck === "string" ? data.printerAck : null, |
|
|
|
receiveAcknowledged: Boolean(data.receiveAcknowledged), |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
export interface PrinterStatusRequest { |
|
|
|
|