Files
client-web/src/modules/overseas-warehouse/utils/transferCartonPrinting.ts
T
2026-10-16 17:43:42 +08:00

28 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export interface PrintableCargoRow {
sku: string
name: string
expectedPackageCount?: number
generatedCartonMarks?: string[]
}
const escapeHtml = (value: string) => value.replace(/[&<>"']/g, char => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[char]!)
/** Generate labels in memory only. The later order request carries these same identities. */
export function prepareTransferCartonLabels(rows: PrintableCargoRow[], newMark: () => string = () => {
const bytes = crypto.getRandomValues(new Uint8Array(16))
return `BX-${Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('').toUpperCase()}`
}) {
const total = rows.reduce((sum, row) => sum + Number(row.expectedPackageCount || 0), 0)
if (!rows.length || rows.some(row => !Number.isSafeInteger(row.expectedPackageCount) || Number(row.expectedPackageCount) < 1) || total > 5000) {
throw new Error('请填写货物的预计箱数(正整数),单次最多打印 5000 箱')
}
let index = 0
const labels = rows.flatMap(row => {
const count = Number(row.expectedPackageCount)
const marks = row.generatedCartonMarks ||= []
while (marks.length < count) marks.push(newMark())
return marks.slice(0, count).map(mark => `<section class="label"><div class="title">仓储转运箱唛</div><div class="mark">${escapeHtml(mark)}</div><div>${++index} / ${total}</div><div>SKU:${escapeHtml(row.sku)}</div><div>${escapeHtml(row.name)}</div></section>`)
})
return `<!doctype html><html><head><meta charset="utf-8"><title>仓储转运箱唛</title><style>@page{size:100mm 100mm;margin:0}body{margin:0;font-family:Arial,sans-serif}.label{box-sizing:border-box;width:100mm;height:100mm;padding:10mm;break-after:page;display:flex;flex-direction:column;justify-content:center;gap:6mm;text-align:center;overflow-wrap:anywhere}.label:last-child{break-after:auto}.title{font-size:22px;font-weight:bold}.mark{font-size:23px;font-weight:bold}</style></head><body>${labels.join('')}</body></html>`
}