From ea7142e7ec94d4896c8d0c9af85656edb24e32e1 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期二, 21 四月 2026 15:48:33 +0800
Subject: [PATCH] 保养项目
---
src/views/salesManagement/salesLedger/components/salesDeliveryPrint.js | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 162 insertions(+), 17 deletions(-)
diff --git a/src/views/salesManagement/salesLedger/components/salesDeliveryPrint.js b/src/views/salesManagement/salesLedger/components/salesDeliveryPrint.js
index e23fd53..f50a2b6 100644
--- a/src/views/salesManagement/salesLedger/components/salesDeliveryPrint.js
+++ b/src/views/salesManagement/salesLedger/components/salesDeliveryPrint.js
@@ -1,3 +1,5 @@
+import QRCode from "qrcode";
+
const PRINT_TITLE = "閿�鍞彂璐у崟";
const escapeHtml = (value) =>
@@ -28,6 +30,84 @@
const getOrderNo = (data, row, item) =>
item?.salesContractNo || item?.orderNo || data?.salesContractNo || row?.salesContractNo || "";
+const PRODUCT_NAME_FIELD_KEYS = [
+ "productDescription",
+ "productName",
+ "name",
+ "title",
+ "goodsName",
+ "materialName",
+ "glassName",
+];
+
+const PRODUCT_NAME_LIST_FIELD_KEYS = [
+ "productDescriptionList",
+ "productNameList",
+ "productDescriptions",
+ "productNames",
+ "nameList",
+ "goodsNameList",
+ "detailProductNames",
+ "productInfoList",
+];
+
+const SPECIFICATION_FIELD_KEYS = ["specificationModel", "specification", "model", "spec"];
+
+const normalizeNameList = (value) => {
+ if (Array.isArray(value)) {
+ return value
+ .flatMap((item) => normalizeNameList(item))
+ .map((item) => String(item).trim())
+ .filter(Boolean);
+ }
+ if (value && typeof value === "object") {
+ const objectListNames = PRODUCT_NAME_LIST_FIELD_KEYS.flatMap((key) => normalizeNameList(value?.[key]));
+ if (objectListNames.length) return objectListNames;
+ return PRODUCT_NAME_FIELD_KEYS.flatMap((key) => normalizeNameList(value?.[key]));
+ }
+ if (typeof value === "string") {
+ const text = value.trim();
+ if (!text) return [];
+ const parts = text
+ .split(/[,\n锛屻�侊紱;]/)
+ .map((item) => item.trim())
+ .filter(Boolean);
+ return parts.length > 1 ? parts : [text];
+ }
+ if (value === null || value === undefined) return [];
+ const text = String(value).trim();
+ return text ? [text] : [];
+};
+
+const extractNameListByKeys = (source, keys) => {
+ if (!source || typeof source !== "object") return [];
+ return keys.flatMap((key) => normalizeNameList(source?.[key]));
+};
+
+const resolveProductName = (item, fallbackNames, index) => {
+ const itemNames = [
+ ...extractNameListByKeys(item, PRODUCT_NAME_LIST_FIELD_KEYS),
+ ...extractNameListByKeys(item, PRODUCT_NAME_FIELD_KEYS),
+ ];
+ if (itemNames.length > 1) {
+ return itemNames[index] || itemNames[0] || "";
+ }
+ return itemNames[0] || fallbackNames[index] || fallbackNames[0] || "";
+};
+
+const resolveSpecificationModel = (...sources) => {
+ for (const source of sources) {
+ if (!source || typeof source !== "object") continue;
+ for (const key of SPECIFICATION_FIELD_KEYS) {
+ const value = source?.[key];
+ if (value !== undefined && value !== null && String(value).trim()) {
+ return String(value).trim();
+ }
+ }
+ }
+ return "";
+};
+
const splitItemsByPage = (items, pageSize) => {
const list = Array.isArray(items) ? items : [];
if (list.length === 0) return [[]];
@@ -40,17 +120,38 @@
const normalizeInvoiceData = (raw, selectedRow) => {
const data = raw ?? {};
- const groups = Array.isArray(data.groups) ? data.groups : [];
- if (!groups.length) return data;
+ const groups = Array.isArray(data.groups)
+ ? data.groups
+ : Array.isArray(data.groupList)
+ ? data.groupList
+ : [];
+ const dataLevelNames = [
+ ...extractNameListByKeys(data, PRODUCT_NAME_LIST_FIELD_KEYS),
+ ...extractNameListByKeys(data, PRODUCT_NAME_FIELD_KEYS),
+ ];
- const items = groups.flatMap((group) =>
- (Array.isArray(group?.items) ? group.items : []).map((item) => ({
- ...item,
- productDescription: group?.productName || item?.productDescription || "",
- salesContractNo: group?.salesContractNo || item?.salesContractNo || "",
- widthHeight: item?.widthHeight || "",
- }))
- );
+ const items = groups.length
+ ? groups.flatMap((group) => {
+ const groupItems = Array.isArray(group?.items) ? group.items : [];
+ const groupNames = [
+ ...extractNameListByKeys(group, PRODUCT_NAME_LIST_FIELD_KEYS),
+ ...extractNameListByKeys(group, PRODUCT_NAME_FIELD_KEYS),
+ ];
+ return groupItems.map((item, index) => ({
+ ...item,
+ // 浼樺厛浣跨敤鏄庣粏鑷韩浜у搧鍚嶏紝鍏煎鈥滃悕绉版暟缁�/鍒嗛殧瀛楃涓测�濈殑鎺ュ彛鏍煎紡
+ productDescription: resolveProductName(item, groupNames, index),
+ specificationModel: resolveSpecificationModel(item, group, data),
+ salesContractNo: group?.salesContractNo || item?.salesContractNo || "",
+ widthHeight: item?.widthHeight || "",
+ }));
+ })
+ : (Array.isArray(data.items) ? data.items : []).map((item, index) => ({
+ ...item,
+ productDescription: resolveProductName(item, dataLevelNames, index),
+ specificationModel: resolveSpecificationModel(item, data, selectedRow),
+ widthHeight: item?.widthHeight || "",
+ }));
return {
...data,
@@ -70,10 +171,15 @@
const list = Array.isArray(items) ? items : [];
const map = new Map();
list.forEach((item) => {
- const key = `${item?.productDescription || ""}__${getOrderNo(data, row, item)}`;
+ const key = `${item?.productDescription || ""}__${item?.specificationModel || ""}__${getOrderNo(
+ data,
+ row,
+ item
+ )}`;
if (!map.has(key)) {
map.set(key, {
productName: item?.productDescription || "",
+ specificationModel: item?.specificationModel || "",
orderNo: getOrderNo(data, row, item),
items: [],
});
@@ -105,12 +211,33 @@
})
.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) {
@@ -146,17 +273,32 @@
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; }
@@ -185,7 +327,10 @@
</div>
<div class="head-mid">
<div class="head-mid-left">瀵规柟鍗曞彿: ${escapeHtml(data.deliveryNo || data.shippingNo || selectedRow.expressNumber || "")}</div>
- <div class="head-mid-title">閿�鍞彂璐у崟</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>
@@ -216,7 +361,7 @@
serial += group.items.length;
return `
<tr class="group-title">
- <td colspan="5" class="left">浜у搧鍚嶇О: ${escapeHtml(group.productName)}</td>
+ <td colspan="5" class="left">浜у搧鍚嶇О: ${escapeHtml(group.productName)}${group.specificationModel ? `銆�瑙勬牸鍨嬪彿: ${escapeHtml(group.specificationModel)}` : ""}</td>
<td colspan="2" class="left">璁㈠崟缂栧彿: ${escapeHtml(group.orderNo)}</td>
</tr>
${rows}
--
Gitblit v1.9.3