| | |
| | | import QRCode from "qrcode"; |
| | | |
| | | const PRINT_TITLE = "销售发货单"; |
| | | |
| | | const escapeHtml = (value) => |
| | |
| | | const items = groups.flatMap((group) => |
| | | (Array.isArray(group?.items) ? group.items : []).map((item) => ({ |
| | | ...item, |
| | | productDescription: group?.productName || item?.productDescription || "", |
| | | // 优先使用明细自身产品名,避免分组名称覆盖导致“一个产品名挂多种明细” |
| | | productDescription: |
| | | item?.productDescription || item?.productName || group?.productName || "", |
| | | salesContractNo: group?.salesContractNo || item?.salesContractNo || "", |
| | | widthHeight: item?.widthHeight || "", |
| | | })) |
| | |
| | | }) |
| | | .join(""); |
| | | |
| | | export const printSalesDeliveryNote = (rawData, selectedRow = {}) => { |
| | | export const printSalesDeliveryNote = async (rawData, selectedRow = {}, ledgerIds = null) => { |
| | | const data = normalizeInvoiceData(rawData, selectedRow); |
| | | const allItems = Array.isArray(data.items) ? data.items : []; |
| | | const pageSize = 18; |
| | | const itemPages = splitItemsByPage(allItems, pageSize); |
| | | const totalPages = itemPages.length; |
| | | |
| | | const ids = |
| | | Array.isArray(ledgerIds) && ledgerIds.length > 0 |
| | | ? ledgerIds |
| | | : selectedRow?.id !== undefined && selectedRow?.id !== null && selectedRow?.id !== "" |
| | | ? [selectedRow.id] |
| | | : []; |
| | | const shipmentRef = String( |
| | | data.shipmentNo || data.deliveryNo || data.externalOrderNo || selectedRow?.expressNumber || "" |
| | | ).trim(); |
| | | const qrPayload = JSON.stringify({ |
| | | type: "FH", |
| | | shipmentNo: shipmentRef, |
| | | ledgerIds: ids, |
| | | }); |
| | | let qrDataUrl = ""; |
| | | try { |
| | | qrDataUrl = await QRCode.toDataURL(qrPayload, { width: 160, margin: 1 }); |
| | | } catch { |
| | | qrDataUrl = ""; |
| | | } |
| | | |
| | | const printWindow = window.open("", "_blank", "width=1200,height=900"); |
| | | if (!printWindow) { |
| | |
| | | font-size: 12px; |
| | | margin-right: 8mm; |
| | | margin-bottom: 1px; |
| | | position: relative; |
| | | top: 6mm; |
| | | } |
| | | .head-mid { |
| | | display: grid; |
| | | grid-template-columns: 1fr auto 1fr; |
| | | align-items: center; |
| | | margin-bottom: 2px; |
| | | margin-top: 6mm; |
| | | margin-bottom: 0; |
| | | position: relative; |
| | | } |
| | | .head-mid-left { font-size: 13px; text-align: left; } |
| | | .head-mid-title { font-size: 20px; font-weight: 700; text-align: center; } |
| | | .head-mid-title-wrap { grid-column: 2; } |
| | | .head-mid-title { font-size: 20px; font-weight: 700; text-align: center; line-height: 1; } |
| | | .head-qr { |
| | | width: 18mm; |
| | | height: 18mm; |
| | | object-fit: contain; |
| | | display: block; |
| | | position: absolute; |
| | | left: calc(50% + 30mm); |
| | | top: calc(50% - 4mm); |
| | | transform: translateY(-50%); |
| | | } |
| | | .head-mid-right { font-size: 13px; text-align: right; padding-right: 8mm; } |
| | | table { width: 100%; border-collapse: collapse; table-layout: fixed; border: 1px solid #222; } |
| | | table { width: 100%; margin-top: 3mm; border-collapse: collapse; table-layout: fixed; border: 1px solid #222; } |
| | | td, th { border: 1px solid #222; padding: 2px 4px; font-size: 13px; text-align: center; vertical-align: middle; } |
| | | .left { text-align: left; } |
| | | .group-title td { font-weight: 700; } |
| | |
| | | </div> |
| | | <div class="head-mid"> |
| | | <div class="head-mid-left">对方单号: ${escapeHtml(data.deliveryNo || data.shippingNo || selectedRow.expressNumber || "")}</div> |
| | | <div class="head-mid-title-wrap"> |
| | | <div class="head-mid-title">销售发货单</div> |
| | | </div> |
| | | ${qrDataUrl ? `<img class="head-qr" src="${qrDataUrl}" alt="二维码" />` : ""} |
| | | <div class="head-mid-right">发货单号: ${escapeHtml(data.shipmentNo || data.deliveryNo || "")}</div> |
| | | </div> |
| | | <table> |