| | |
| | | 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 [[]]; |
| | |
| | | |
| | | 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: |
| | | item?.productDescription || item?.productName || group?.productName || "", |
| | | 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, |
| | |
| | | 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: [], |
| | | }); |
| | |
| | | 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} |