diff --git a/miniprogram/utils/plDriverPlanCopy.js b/miniprogram/utils/plDriverPlanCopy.js index bd888410b..edd342646 100644 --- a/miniprogram/utils/plDriverPlanCopy.js +++ b/miniprogram/utils/plDriverPlanCopy.js @@ -1,8 +1,10 @@ /** * 司机运输计划单「复制发群」纯文本(不含附件) + * 规格:docs/superpowers/specs/2026-10-12-mini-pl-driver-plan-copy-text-enrich-design.md */ const DASH = '—' +const FIELD_GAP = ' ' function stopTypeOf(stop) { return String(stop?.stopType || stop?.stop_type || '').trim() @@ -13,33 +15,77 @@ function customerNameOf(stop) { return name || DASH } -function formatActualQtyLine(partyLabel, product) { - const unit = String(product?.unit || '').trim() - const raw = product?.actualQty ?? product?.actual_qty - let qtyPart = DASH - if (raw != null && raw !== '') { - qtyPart = String(raw) - if (unit) qtyPart = `${qtyPart} ${unit}` - } - return `${partyLabel}:${qtyPart}` +function textOrDash(value) { + const s = String(value ?? '').trim() + return s || DASH } -function appendQtySection(lines, title, qtyLines) { - lines.push(title) - if (!qtyLines.length) { - lines.push(DASH) - } else { - lines.push(...qtyLines) - } +function formatQtyWithUnit(raw, unit) { + if (raw == null || raw === '') return DASH + const qty = String(raw).trim() + if (!qty) return DASH + const u = String(unit || '').trim() + return u ? `${qty} ${u}` : qty +} + +function planQtyOf(product) { + if (product?.planQty != null && product.planQty !== '') return product.planQty + if (product?.plan_qty != null && product.plan_qty !== '') return product.plan_qty + if (product?.quantity != null && product.quantity !== '') return product.quantity + return null +} + +function actualQtyOf(product) { + if (product?.actualQty != null && product.actualQty !== '') return product.actualQty + if (product?.actual_qty != null && product.actual_qty !== '') return product.actual_qty + return null +} + +/** 产品紧凑行:- 名称 型号 包装 计划数量:… 实际数量:… */ +function formatProductLine(product) { + const name = textOrDash(product?.productName ?? product?.product_name) + const model = textOrDash(product?.model) + const pack = textOrDash(product?.packageSpec ?? product?.package_spec) + const unit = product?.unit + const planPart = formatQtyWithUnit(planQtyOf(product), unit) + const actualPart = formatQtyWithUnit(actualQtyOf(product), unit) + return ( + `- ${name}${FIELD_GAP}${model}${FIELD_GAP}${pack}` + + `${FIELD_GAP}计划数量:${planPart}${FIELD_GAP}实际数量:${actualPart}` + ) } /** - * @param {object} page driverPlanApi.get 详情 + * 追加「送货信息:」或「装货信息:」区块。 + * 无站点 → 标题下单独一行 — + * 有站点无产品 → 客户名:下一行 - — + */ +function appendInfoSection(lines, title, stops) { + lines.push(title) + if (!stops.length) { + lines.push(DASH) + return + } + stops.forEach((stop) => { + lines.push(`${customerNameOf(stop)}:`) + const products = Array.isArray(stop?.products) ? stop.products : [] + if (!products.length) { + lines.push(`- ${DASH}`) + return + } + products.forEach((product) => { + lines.push(formatProductLine(product)) + }) + }) +} + +/** + * @param {object} page driverPlanApi.get 详情(可含 copySeqNo) * @returns {string} */ export function buildDriverPlanCopyText(page = {}) { const stops = Array.isArray(page?.stops) ? page.stops : [] - const loadStop = stops.find((s) => stopTypeOf(s) === 'load') + const loadStops = stops.filter((s) => stopTypeOf(s) === 'load') const deliveryStops = stops.filter((s) => stopTypeOf(s) === 'delivery') const rawSeq = page?.copySeqNo ?? page?.copy_seq_no @@ -47,35 +93,12 @@ export function buildDriverPlanCopyText(page = {}) { const lines = [ `序号:${seqText}`, - `计划编号:${String(page?.planNo || page?.plan_no || '').trim() || DASH}`, - `装货方:${loadStop ? customerNameOf(loadStop) : DASH}` + `计划编号:${textOrDash(page?.planNo ?? page?.plan_no)}`, + `车辆:${textOrDash(page?.licensePlate ?? page?.license_plate)}` ] - if (!deliveryStops.length) { - lines.push(`送货方#1:${DASH}`) - } else { - deliveryStops.forEach((stop, index) => { - lines.push(`送货方#${index + 1}:${customerNameOf(stop)}`) - }) - } - - const loadQtyLines = [] - if (loadStop) { - const products = Array.isArray(loadStop.products) ? loadStop.products : [] - products.forEach((product) => { - loadQtyLines.push(formatActualQtyLine('装货方', product)) - }) - } - appendQtySection(lines, '实际装货量:', loadQtyLines) - - const deliveryQtyLines = [] - deliveryStops.forEach((stop, index) => { - const products = Array.isArray(stop?.products) ? stop.products : [] - products.forEach((product) => { - deliveryQtyLines.push(formatActualQtyLine(`送货方#${index + 1}`, product)) - }) - }) - appendQtySection(lines, '实际送货量:', deliveryQtyLines) + appendInfoSection(lines, '送货信息:', deliveryStops) + appendInfoSection(lines, '装货信息:', loadStops) return lines.join('\n') }