Files
client-web/src/modules/overseas-warehouse/utils/transferCartonPrinting.ts
T

28 lines
2.0 KiB
TypeScript
Raw Normal View History

2026-10-16 17:43:42 +08:00
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>`
}