211 lines
6.8 KiB
TypeScript
211 lines
6.8 KiB
TypeScript
import type { InventoryRecord } from '@/api/db/inventory'
|
||
import type { PlanDelivery, PlanLoad, PlanStopProduct } from '@/api/pl'
|
||
import { formatDate } from '@/utils/format'
|
||
import { isPlInternalCustomerName } from '@/utils/pl-internal-customer'
|
||
|
||
const SITE_INSTRUCTION = '说明:请打开链接上传现场附件并填写备注。'
|
||
|
||
export type SiteSummaryStopBlock = {
|
||
label: string
|
||
customerName?: string
|
||
businessType?: string
|
||
address?: string
|
||
productLines: string[]
|
||
}
|
||
|
||
export type SiteSummaryRecord = {
|
||
productName?: string
|
||
productText?: string
|
||
batchNo?: string
|
||
planNo?: string
|
||
siteUrl?: string
|
||
businessType?: string
|
||
siteFeedbackRemark?: string
|
||
siteFeedbackTime?: string
|
||
}
|
||
|
||
function formatSiteSummaryProductLine(record: SiteSummaryRecord) {
|
||
return record.productText || record.productName || '—'
|
||
}
|
||
|
||
function isSegmentSiteRecord(record: SiteSummaryRecord) {
|
||
return (record.businessType || '').includes('按段')
|
||
}
|
||
|
||
function formatStopProductLine(
|
||
product: PlanStopProduct,
|
||
getUnitLabel?: (unit: string) => string
|
||
) {
|
||
const name = (product.productName || '').trim() || '—'
|
||
const qty = product.planQty
|
||
const unitRaw = (product.unit || '').trim()
|
||
const unit = unitRaw
|
||
? (getUnitLabel ? getUnitLabel(unitRaw) || unitRaw : unitRaw)
|
||
: '吨'
|
||
if (qty == null) return name
|
||
return `${name} ${qty}${unit}`
|
||
}
|
||
|
||
/** 现场页/简述可见段:仅内部客户(山峡/云栋),与是否勾选生成地磅单无关。 */
|
||
function isSiteVisibleStop(customerName?: string | null) {
|
||
return isPlInternalCustomerName(customerName)
|
||
}
|
||
|
||
export function buildSiteStopBlocksFromPlan(
|
||
plan?: {
|
||
load?: PlanLoad | null
|
||
deliveries?: PlanDelivery[] | null
|
||
} | null,
|
||
getUnitLabel?: (unit: string) => string
|
||
): SiteSummaryStopBlock[] {
|
||
if (!plan) return []
|
||
const blocks: SiteSummaryStopBlock[] = []
|
||
const load = plan.load
|
||
if (load && isSiteVisibleStop(load.customerName)) {
|
||
blocks.push({
|
||
label: '装货',
|
||
customerName: load.customerName || undefined,
|
||
businessType: load.dibangDirection || undefined,
|
||
address: load.address || undefined,
|
||
productLines: (load.products || [])
|
||
.map((product) => formatStopProductLine(product, getUnitLabel))
|
||
.filter(Boolean)
|
||
})
|
||
}
|
||
for (const delivery of plan.deliveries || []) {
|
||
if (!isSiteVisibleStop(delivery.customerName)) continue
|
||
const seq = delivery.seq != null ? Number(delivery.seq) : 0
|
||
blocks.push({
|
||
label: seq > 0 ? `送货 #${seq}` : '送货',
|
||
customerName: delivery.customerName || undefined,
|
||
businessType: delivery.dibangDirection || undefined,
|
||
address: delivery.address || undefined,
|
||
productLines: (delivery.products || [])
|
||
.map((product) => formatStopProductLine(product, getUnitLabel))
|
||
.filter(Boolean)
|
||
})
|
||
}
|
||
return blocks
|
||
}
|
||
|
||
function appendSiteRecordCardLines(
|
||
lines: string[],
|
||
record: SiteSummaryRecord,
|
||
options: { showHeadline?: boolean }
|
||
) {
|
||
const headline = (record.productName || '').trim()
|
||
const productText = formatSiteSummaryProductLine(record)
|
||
if (options.showHeadline && headline) {
|
||
lines.push(headline)
|
||
}
|
||
if (record.businessType && record.businessType !== '—') {
|
||
lines.push(`业务类型:${record.businessType}`)
|
||
}
|
||
if (record.siteFeedbackTime && record.siteFeedbackTime !== '—') {
|
||
lines.push(`保存时间:${record.siteFeedbackTime}`)
|
||
}
|
||
if (record.batchNo) {
|
||
lines.push(`出入库单号:${record.batchNo}`)
|
||
}
|
||
if (productText && productText !== '—' && productText !== headline) {
|
||
lines.push(`产品:${productText}`)
|
||
}
|
||
if (record.siteFeedbackRemark && record.siteFeedbackRemark !== '—') {
|
||
lines.push(`现场备注:${record.siteFeedbackRemark}`)
|
||
}
|
||
lines.push(`现场链接:${record.siteUrl}`)
|
||
}
|
||
|
||
function formatSiteDibangDirectionLabel(direction?: string | null) {
|
||
const value = (direction || '').trim()
|
||
if (!value || value === 'none') return ''
|
||
if (value === 'outbound') return '出库'
|
||
if (value === 'inbound') return '入库'
|
||
return value
|
||
}
|
||
|
||
function appendStopBlockLines(lines: string[], stop: SiteSummaryStopBlock) {
|
||
const bizLabel = formatSiteDibangDirectionLabel(stop.businessType)
|
||
const biz = bizLabel ? `(${bizLabel})` : ''
|
||
lines.push(`【${stop.label} · ${stop.customerName || '—'}】${biz}`)
|
||
if (stop.address) {
|
||
lines.push(`地址:${stop.address}`)
|
||
}
|
||
if (stop.productLines.length) {
|
||
stop.productLines.forEach((line) => lines.push(`产品:${line}`))
|
||
} else {
|
||
lines.push('产品:—')
|
||
}
|
||
}
|
||
|
||
export function buildSiteSummaryFromInventoryLinks(options: {
|
||
planNo?: string
|
||
licensePlate?: string
|
||
pickupTime?: string
|
||
planDate?: string
|
||
records: SiteSummaryRecord[]
|
||
stopBlocks?: SiteSummaryStopBlock[]
|
||
}) {
|
||
const lines = ['【运输现场】']
|
||
const planNo = options.planNo || options.records[0]?.planNo
|
||
if (planNo) lines.push(`计划号:${planNo}`)
|
||
if (options.licensePlate) lines.push(`车牌:${options.licensePlate}`)
|
||
const time = formatDate(options.pickupTime) || options.planDate
|
||
if (time) lines.push(`时间:${time}`)
|
||
|
||
const validRecords = options.records.filter((item) => item.siteUrl)
|
||
if (!validRecords.length) {
|
||
lines.push('现场链接:—')
|
||
return lines.join('\n')
|
||
}
|
||
|
||
const stopBlocks = options.stopBlocks || []
|
||
const useSegmentLayout =
|
||
stopBlocks.length > 0 && validRecords.some((record) => isSegmentSiteRecord(record))
|
||
|
||
if (useSegmentLayout) {
|
||
lines.push('')
|
||
stopBlocks.forEach((stop, index) => {
|
||
if (index > 0) lines.push('')
|
||
appendStopBlockLines(lines, stop)
|
||
})
|
||
lines.push('')
|
||
const record = validRecords[0]
|
||
lines.push(`现场链接:${record.siteUrl}`)
|
||
} else if (validRecords.length === 1) {
|
||
lines.push('')
|
||
appendSiteRecordCardLines(lines, validRecords[0], { showHeadline: true })
|
||
} else {
|
||
lines.push('')
|
||
validRecords.forEach((record, index) => {
|
||
lines.push(`【${index + 1}】${formatSiteSummaryProductLine(record)}`)
|
||
appendSiteRecordCardLines(lines, record, { showHeadline: false })
|
||
if (index < validRecords.length - 1) lines.push('')
|
||
})
|
||
}
|
||
|
||
lines.push('')
|
||
lines.push(SITE_INSTRUCTION)
|
||
return lines.join('\n')
|
||
}
|
||
|
||
export function buildSiteSummaryFromInventory(record: InventoryRecord, siteUrl: string) {
|
||
const spec = record.specification?.trim()
|
||
const product = spec ? `${record.product}(${spec})` : record.product
|
||
const lines = [
|
||
'【出入库现场】',
|
||
`出入库单号:${record.batchNo || '—'}`,
|
||
`业务类型:${record.businessType}`,
|
||
`日期:${record.date || '—'}`,
|
||
`往来单位:${record.partnerCompany || '—'}`,
|
||
`产品:${product}`,
|
||
`数量(吨):${record.quantity ?? '—'}`,
|
||
`车牌:${record.vehicleNo || '—'}`
|
||
]
|
||
if (record.planNo) lines.push(`计划号:${record.planNo}`)
|
||
lines.push(`现场链接:${siteUrl}`)
|
||
lines.push('')
|
||
lines.push(SITE_INSTRUCTION)
|
||
return lines.join('\n')
|
||
}
|