/** * 司机运输计划单「复制发群」纯文本(不含附件) * 规格:docs/superpowers/specs/2026-10-13-mini-pl-driver-plan-copy-product-lines-design.md * (头信息/区块/边界继承 2026-10-12 enrich 设计) */ const DASH = '—' const FIELD_GAP = ' ' function stopTypeOf(stop) { return String(stop?.stopType || stop?.stop_type || '').trim() } function customerNameOf(stop) { const name = String(stop?.customerName || stop?.customer_name || '').trim() return name || DASH } function textOrDash(value) { const s = String(value ?? '').trim() return s || DASH } 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 formatProductLines(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}`, `- 计划数量:${planPart}`, `- 实际数量:${actualPart}` ] } /** * 追加「送货信息:」或「装货信息:」区块。 * 无站点 → 标题下单独一行 — * 有站点无产品 → 客户名:下一行 - — */ 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) => { formatProductLines(product).forEach((line) => lines.push(line)) }) }) } /** * @param {object} page driverPlanApi.get 详情(可含 copySeqNo) * @returns {string} */ export function buildDriverPlanCopyText(page = {}) { const stops = Array.isArray(page?.stops) ? page.stops : [] const loadStops = stops.filter((s) => stopTypeOf(s) === 'load') const deliveryStops = stops.filter((s) => stopTypeOf(s) === 'delivery') const rawSeq = page?.copySeqNo ?? page?.copy_seq_no const seqText = rawSeq != null && rawSeq !== '' ? String(rawSeq) : DASH const lines = [ `序号:${seqText}`, `计划编号:${textOrDash(page?.planNo ?? page?.plan_no)}`, `车辆:${textOrDash(page?.licensePlate ?? page?.license_plate)}` ] appendInfoSection(lines, '送货信息:', deliveryStops) appendInfoSection(lines, '装货信息:', loadStops) return lines.join('\n') } /** 复制到剪贴板;成功返回 true */ export function copyDriverPlanToClipboard(page) { const text = buildDriverPlanCopyText(page) if (!text) { uni.showToast({ title: '暂无可复制内容', icon: 'none' }) return Promise.resolve(false) } return new Promise((resolve) => { uni.setClipboardData({ data: text, success: () => { uni.showToast({ title: '已复制', icon: 'success' }) resolve(true) }, fail: () => { uni.showToast({ title: '复制失败', icon: 'none' }) resolve(false) } }) }) }