feat(pl): 按单据类型限制打印项并调整送(提)货单布局
按入库/出库/直销限制可打印单据;送(提)货单信息区改为一行布局,物料表增加单据编号列,并修正条款列宽与类型多选不换行。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
1e2e8ab0fc
commit
70bdd820ce
4 files changed
+367
-191
No files matched your search
@@ -273,24 +273,38 @@
|
||||
>
|
||||
<el-icon><CopyDocument /></el-icon>复制磅单二维码
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="showInboundSlipPrint"
|
||||
@click="handlePrintInboundSlip"
|
||||
<el-dropdown
|
||||
v-if="showSlipPrint"
|
||||
trigger="click"
|
||||
@command="handlePrintSlip"
|
||||
>
|
||||
<el-icon><Printer /></el-icon>入库单
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="showDeliverySlipPrint"
|
||||
@click="handlePrintDeliverySlip"
|
||||
>
|
||||
<el-icon><Printer /></el-icon>送(提)货单
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="showSubpackSlipPrint"
|
||||
@click="handlePrintSubpackSlip"
|
||||
>
|
||||
<el-icon><Printer /></el-icon>分装单
|
||||
</el-button>
|
||||
<el-button>
|
||||
<el-icon><Printer /></el-icon>打印单据
|
||||
<el-icon class="el-icon--right"><ArrowDown /></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
command="inbound"
|
||||
:disabled="!canPrintSlipCommand(plan.planType, 'inbound')"
|
||||
>
|
||||
入库单
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
command="delivery"
|
||||
:disabled="!canPrintSlipCommand(plan.planType, 'delivery')"
|
||||
>
|
||||
送(提)货单
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
command="subpack"
|
||||
:disabled="!canPrintSlipCommand(plan.planType, 'subpack')"
|
||||
>
|
||||
分装单
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button @click="innerVisible = false">
|
||||
@@ -306,7 +320,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Check, Close, CopyDocument, Printer, View } from '@element-plus/icons-vue'
|
||||
import { ArrowDown, Check, Close, CopyDocument, Printer, View } from '@element-plus/icons-vue'
|
||||
import {
|
||||
carrierApi,
|
||||
planApi,
|
||||
@@ -336,7 +350,7 @@ import { useDictStore } from '@/store/modules/dict'
|
||||
import { isTonProductUnit } from '@/utils/crm-product-display'
|
||||
import { formatDate } from '@/utils/format'
|
||||
import { pickBxData, pickBxList } from '@/utils/http/bx'
|
||||
import { formatPlVehiclePlateDisplay } from '@/utils/pl-display'
|
||||
import { canPrintSlipCommand, formatPlVehiclePlateDisplay, type PlPrintSlipCommand } from '@/utils/pl-display'
|
||||
|
||||
const dictStore = useDictStore()
|
||||
|
||||
@@ -427,9 +441,7 @@ const dialogTitle = computed(() => {
|
||||
|
||||
const isRearrange = computed(() => plan.value.transportStatus === 'arranged')
|
||||
/** 安排成功后始终展示打印入口,与运输计划列表工具栏一致,便于现场立即开单 */
|
||||
const showInboundSlipPrint = computed(() => arrangeSuccess.value)
|
||||
const showDeliverySlipPrint = computed(() => arrangeSuccess.value)
|
||||
const showSubpackSlipPrint = computed(() => arrangeSuccess.value)
|
||||
const showSlipPrint = computed(() => arrangeSuccess.value)
|
||||
|
||||
function getUnitLabel(unit: string) {
|
||||
return dictStore.getLabel('crm_product_unit', unit) || unit
|
||||
@@ -787,31 +799,28 @@ async function handleSubmit() {
|
||||
}
|
||||
}
|
||||
|
||||
function handlePrintInboundSlip() {
|
||||
function handlePrintSlip(command: string) {
|
||||
const planId = plan.value.id
|
||||
if (!planId) {
|
||||
ElMessage.warning('计划信息无效')
|
||||
return
|
||||
}
|
||||
inboundSlipPrintRef.value?.open(planId)
|
||||
}
|
||||
|
||||
function handlePrintDeliverySlip() {
|
||||
const planId = plan.value.id
|
||||
if (!planId) {
|
||||
ElMessage.warning('计划信息无效')
|
||||
const slipCommand = command as PlPrintSlipCommand
|
||||
if (!canPrintSlipCommand(plan.value.planType, slipCommand)) {
|
||||
ElMessage.warning('当前单据类型不支持打印该单据')
|
||||
return
|
||||
}
|
||||
deliverySlipPrintRef.value?.open(planId)
|
||||
}
|
||||
|
||||
function handlePrintSubpackSlip() {
|
||||
const planId = plan.value.id
|
||||
if (!planId) {
|
||||
ElMessage.warning('计划信息无效')
|
||||
if (slipCommand === 'inbound') {
|
||||
inboundSlipPrintRef.value?.open(planId)
|
||||
return
|
||||
}
|
||||
subpackSlipPrintRef.value?.open(planId)
|
||||
if (slipCommand === 'delivery') {
|
||||
deliverySlipPrintRef.value?.open(planId)
|
||||
return
|
||||
}
|
||||
if (slipCommand === 'subpack') {
|
||||
subpackSlipPrintRef.value?.open(planId)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -29,17 +29,18 @@ const INFO_COLGROUP = `<colgroup>
|
||||
<col span="7" style="width:14.28%;" />
|
||||
</colgroup>`
|
||||
/**
|
||||
* 物料表列宽:加宽编号/名称,收窄规格/单位;前 5 列合计供条款区使用。
|
||||
* 物料编号 / 物料名称 / 规格 / 单位 / 数量 / 产品规格 / 实收数量
|
||||
* 物料表列宽:单据编号 + 加宽编号/名称,收窄规格/单位;前 5 列合计供条款区使用。
|
||||
* 单据编号 / 物料编号 / 物料名称 / 规格 / 单位 / 数量 / 产品规格 / 实收数量
|
||||
*/
|
||||
const PRODUCT_COLGROUP = `<colgroup>
|
||||
<col style="width:18%;" />
|
||||
<col style="width:24%;" />
|
||||
<col style="width:14%;" />
|
||||
<col style="width:14%;" />
|
||||
<col style="width:20%;" />
|
||||
<col style="width:8%;" />
|
||||
<col style="width:6%;" />
|
||||
<col style="width:12%;" />
|
||||
<col style="width:16%;" />
|
||||
<col style="width:16%;" />
|
||||
<col style="width:10%;" />
|
||||
<col style="width:14%;" />
|
||||
<col style="width:14%;" />
|
||||
</colgroup>`
|
||||
|
||||
/** 物料网格 padding(编辑器预览) */
|
||||
@@ -87,9 +88,9 @@ const INFO_VALUE_INLINE_LEFT = `flex:1;min-width:0;box-sizing:border-box;border-
|
||||
const INFO_VALUE_INLINE_CENTER = `flex:1;min-width:0;box-sizing:border-box;border-bottom:${INFO_UNDERLINE} !important;padding:0 2px 2px;text-align:center;min-height:1.3em;`
|
||||
const INFO_CELL_LEFT = `${NO_BORDER}text-align:left;`
|
||||
const INFO_CELL_RIGHT = `${NO_BORDER}text-align:left;`
|
||||
const INFO_GAP_BEFORE_PRODUCT = 24
|
||||
const INFO_GAP_BEFORE_PRODUCT = 12
|
||||
const GAP_BEFORE_PRODUCT_CELL = `border:none !important;padding:0 !important;line-height:0 !important;font-size:0 !important;background:transparent !important;height:${INFO_GAP_BEFORE_PRODUCT}px !important;min-height:${INFO_GAP_BEFORE_PRODUCT}px !important;`
|
||||
const INFO_GAP_BEFORE_SIGN = 24
|
||||
const INFO_GAP_BEFORE_SIGN = 12
|
||||
const GAP_BEFORE_SIGN_CELL = `border:none !important;padding:0 !important;line-height:0 !important;font-size:0 !important;background:transparent !important;height:${INFO_GAP_BEFORE_SIGN}px !important;min-height:${INFO_GAP_BEFORE_SIGN}px !important;`
|
||||
const SIDE_LABELS_COL_WIDTH = 36
|
||||
|
||||
@@ -99,7 +100,7 @@ function buildDeliverySlipSignItem(label: string, valueContent: string, minWidth
|
||||
|
||||
function buildDeliverySlipSignRowHtml(): string {
|
||||
return `<tr class="delivery-slip-sign-row">
|
||||
<td colspan="7" class="delivery-slip-sign-row-cell" style="border:none !important;padding:${TABLE_ROW_PADDING};text-align:center;${FONT_SIGN}background:transparent !important;">
|
||||
<td colspan="8" class="delivery-slip-sign-row-cell" style="border:none !important;padding:${TABLE_ROW_PADDING};text-align:center;${FONT_SIGN}background:transparent !important;">
|
||||
<div class="delivery-slip-sign-inner">
|
||||
${buildDeliverySlipSignItem('仓库:', ' ', '80px')}
|
||||
${buildDeliverySlipSignItem('审核:', ' ', '80px')}
|
||||
@@ -165,15 +166,22 @@ function formatDeliverySlipProductGridCellContent(content: string): string {
|
||||
return plain || ' '
|
||||
}
|
||||
|
||||
function buildProductRows(products: PlanProduct[] = [], ctx?: DeliverySlipRenderContext): string {
|
||||
function buildProductRows(
|
||||
products: PlanProduct[] = [],
|
||||
planNo = '',
|
||||
ctx?: DeliverySlipRenderContext
|
||||
): string {
|
||||
if (!products.length) {
|
||||
return `<tr><td class="delivery-slip-product-cell" colspan="7" style="${PRODUCT_CELL}">暂无产品信息</td></tr>`
|
||||
return `<tr><td class="delivery-slip-product-cell" colspan="8" style="${PRODUCT_CELL}">暂无产品信息</td></tr>`
|
||||
}
|
||||
|
||||
const planNoText = formatDeliverySlipProductGridCellContent(planNo)
|
||||
|
||||
const dataRows = products
|
||||
.map((product) => {
|
||||
const qty = product.outboundQty ?? product.outboundEstimateQty ?? product.quantity ?? ''
|
||||
return `<tr>
|
||||
<td class="delivery-slip-product-cell delivery-slip-product-grid-cell" style="${PRODUCT_GRID_CELL}">${planNoText}</td>
|
||||
<td class="delivery-slip-product-cell delivery-slip-product-grid-cell" style="${PRODUCT_GRID_CELL}">${formatDeliverySlipProductGridCellContent(resolveSlipProductCode(product, ctx))}</td>
|
||||
<td class="delivery-slip-product-cell delivery-slip-product-grid-cell" style="${PRODUCT_GRID_CELL}">${formatDeliverySlipProductGridCellContent(product.productName || '')}</td>
|
||||
<td class="delivery-slip-product-cell delivery-slip-product-grid-cell" style="${PRODUCT_GRID_CELL}">${formatDeliverySlipProductGridCellContent(product.model || '')}</td>
|
||||
@@ -220,13 +228,14 @@ export const DELIVERY_SLIP_PRINT_CSS = `
|
||||
flex: 1 !important;
|
||||
min-width: 0 !important;
|
||||
display: flex !important;
|
||||
flex-wrap: wrap !important;
|
||||
flex-wrap: nowrap !important;
|
||||
justify-content: flex-start !important;
|
||||
align-items: center !important;
|
||||
gap: 14px 18px !important;
|
||||
gap: 10px 12px !important;
|
||||
box-sizing: border-box !important;
|
||||
font-size: 20px !important;
|
||||
line-height: 1.35 !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.delivery-slip-doc .delivery-slip-type-check-item {
|
||||
display: inline-flex !important;
|
||||
@@ -577,17 +586,44 @@ const SIDE_LABEL_CELL = `border:none !important;padding:0 !important;vertical-al
|
||||
|
||||
const DELIVERY_SLIP_TYPE_CHECK_WRAP_STYLE = `${INFO_ROW}margin-top:-8px;margin-bottom:20px;`
|
||||
const DELIVERY_SLIP_TYPE_CHECK_INNER_STYLE =
|
||||
'flex:1;min-width:0;display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:center;gap:14px 18px;box-sizing:border-box;font-size:20px;line-height:1.35;'
|
||||
'flex:1;min-width:0;display:flex;flex-wrap:nowrap;justify-content:flex-start;align-items:center;gap:10px 12px;box-sizing:border-box;font-size:20px;line-height:1.35;white-space:nowrap;'
|
||||
|
||||
function buildDeliverySlipTypeCheckboxesHtml(): string {
|
||||
const item = (label: string) =>
|
||||
`<label class="delivery-slip-type-check-item" contenteditable="false"><input type="checkbox" class="delivery-slip-type-check-input" />${label}</label>`
|
||||
return `<div class="delivery-slip-info-row delivery-slip-type-check-wrap" style="${DELIVERY_SLIP_TYPE_CHECK_WRAP_STYLE}">
|
||||
<span class="delivery-slip-info-label delivery-slip-type-check-spacer" style="${INFO_LABEL}visibility:hidden;">单据编号:</span>
|
||||
<span class="delivery-slip-info-label delivery-slip-type-check-spacer" style="${INFO_LABEL}visibility:hidden;">日 期:</span>
|
||||
<div class="delivery-slip-type-check-row" style="${DELIVERY_SLIP_TYPE_CHECK_INNER_STYLE}">${item('自提')}${item('出库')}${item('直销')}</div>
|
||||
</div>`
|
||||
}
|
||||
|
||||
function buildDeliverySlipInfoTableHtml(): string {
|
||||
return `<table class="delivery-slip-info-table" style="width:100%;border-collapse:collapse;table-layout:fixed;border:none !important;">
|
||||
${INFO_COLGROUP}
|
||||
<tr>
|
||||
<td colspan="2" style="${INFO_CELL_LEFT}">
|
||||
<div class="delivery-slip-info-row" style="${INFO_ROW}">
|
||||
<span class="delivery-slip-info-label" style="${INFO_LABEL}">收货单位:</span>
|
||||
<span class="delivery-slip-info-value-left" style="${INFO_VALUE_INLINE_LEFT}">{{receivingUnit}} </span>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan="2" style="${INFO_CELL_LEFT}">
|
||||
<div class="delivery-slip-info-row" style="${INFO_ROW}">
|
||||
<span class="delivery-slip-info-label" style="${INFO_LABEL}">收货联系方式:</span>
|
||||
<span class="delivery-slip-info-value-left" style="${INFO_VALUE_INLINE_LEFT}">{{receiveContact}} </span>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan="3" style="${INFO_CELL_RIGHT}">
|
||||
${buildDeliverySlipTypeCheckboxesHtml()}
|
||||
<div class="delivery-slip-info-row" style="${INFO_ROW}">
|
||||
<span class="delivery-slip-info-label" style="${INFO_LABEL}">日 期:</span>
|
||||
<span class="delivery-slip-info-value-center" style="${INFO_VALUE_INLINE_CENTER}">{{planDateChinese}} </span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>`
|
||||
}
|
||||
|
||||
function buildDeliverySlipTermsHtml(): string {
|
||||
return `<div class="delivery-slip-terms-text" style="${TERMS_TEXT_STYLE}">
|
||||
1.本送货单如购销双方未签订合同,视为有效;<br />
|
||||
@@ -622,38 +658,7 @@ export function generateDeliverySlipTemplate(_plan?: Plan): string {
|
||||
<tr>
|
||||
<td class="delivery-slip-main-col" style="vertical-align:top;padding-right:6px;border:none !important;background:transparent !important;">
|
||||
<!-- 1. 基本信息(独立表,不可拖宽高) -->
|
||||
<table class="delivery-slip-info-table" style="width:100%;border-collapse:collapse;table-layout:fixed;border:none !important;">
|
||||
${INFO_COLGROUP}
|
||||
<tr>
|
||||
<td colspan="4" style="${INFO_CELL_LEFT}">
|
||||
<div class="delivery-slip-info-row" style="${INFO_ROW}">
|
||||
<span class="delivery-slip-info-label" style="${INFO_LABEL}">收货单位:</span>
|
||||
<span class="delivery-slip-info-value-left" style="${INFO_VALUE_INLINE_LEFT}">{{receivingUnit}} </span>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan="3" style="${INFO_CELL_RIGHT}">
|
||||
${buildDeliverySlipTypeCheckboxesHtml()}
|
||||
<div class="delivery-slip-info-row" style="${INFO_ROW}">
|
||||
<span class="delivery-slip-info-label" style="${INFO_LABEL}">单据编号:</span>
|
||||
<span class="delivery-slip-info-value-center" style="${INFO_VALUE_INLINE_CENTER}">{{planNo}} </span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4" style="${INFO_CELL_LEFT}">
|
||||
<div class="delivery-slip-info-row" style="${INFO_ROW}">
|
||||
<span class="delivery-slip-info-label" style="${INFO_LABEL}">收货联系方式:</span>
|
||||
<span class="delivery-slip-info-value-left" style="${INFO_VALUE_INLINE_LEFT}">{{receiveContact}} </span>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan="3" style="${INFO_CELL_RIGHT}">
|
||||
<div class="delivery-slip-info-row" style="${INFO_ROW}">
|
||||
<span class="delivery-slip-info-label" style="${INFO_LABEL}">日 期:</span>
|
||||
<span class="delivery-slip-info-value-center" style="${INFO_VALUE_INLINE_CENTER}">{{planDateChinese}} </span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
${buildDeliverySlipInfoTableHtml()}
|
||||
|
||||
<div class="delivery-slip-section-gap delivery-slip-gap-before-product" style="${GAP_BEFORE_PRODUCT_CELL}"> </div>
|
||||
|
||||
@@ -661,6 +666,7 @@ export function generateDeliverySlipTemplate(_plan?: Plan): string {
|
||||
<table class="delivery-slip-product-table" style="width:100%;border-collapse:collapse;table-layout:fixed;border:none !important;">
|
||||
${PRODUCT_COLGROUP}
|
||||
<tr class="delivery-slip-product-header">
|
||||
<th class="delivery-slip-product-cell delivery-slip-product-grid-cell" style="${PRODUCT_TH}">单据编号</th>
|
||||
<th class="delivery-slip-product-cell delivery-slip-product-grid-cell" style="${PRODUCT_TH}">物料编号</th>
|
||||
<th class="delivery-slip-product-cell delivery-slip-product-grid-cell" style="${PRODUCT_TH}">物料名称</th>
|
||||
<th class="delivery-slip-product-cell delivery-slip-product-grid-cell" style="${PRODUCT_TH}">规格</th>
|
||||
@@ -671,7 +677,7 @@ export function generateDeliverySlipTemplate(_plan?: Plan): string {
|
||||
</tr>
|
||||
{{productTable}}
|
||||
<tr>
|
||||
<td colspan="7" class="delivery-slip-product-cell" style="${PRODUCT_TABLE_CELL_LEFT}">
|
||||
<td colspan="8" class="delivery-slip-product-cell" style="${PRODUCT_TABLE_CELL_LEFT}">
|
||||
备注:{{remark}}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -679,7 +685,7 @@ export function generateDeliverySlipTemplate(_plan?: Plan): string {
|
||||
<td colspan="5" class="delivery-slip-product-cell delivery-slip-terms-cell" style="${PRODUCT_TERMS_CELL_LEFT}">
|
||||
${buildDeliverySlipTermsHtml()}
|
||||
</td>
|
||||
<td colspan="2" class="delivery-slip-product-cell" style="${PRODUCT_TABLE_CELL_LEFT}">
|
||||
<td colspan="3" class="delivery-slip-product-cell" style="${PRODUCT_TABLE_CELL_LEFT}">
|
||||
${SEAL_BLOCK}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -781,7 +787,7 @@ function patchDeliverySlipProductGridCellAttrs(attrs: string): string {
|
||||
function normalizeDeliverySlipProductGridCell(html: string): string {
|
||||
if (!html.includes('delivery-slip-doc') || !html.includes('delivery-slip-product-cell')) return html
|
||||
|
||||
let result = html.replace(/<tr([^>]*)>\s*(<th[\s\S]*?<\/th>\s*){7}\s*<\/tr>/g, (rowMatch) => {
|
||||
let result = html.replace(/<tr([^>]*)>\s*(<th[\s\S]*?<\/th>\s*){8}\s*<\/tr>/g, (rowMatch) => {
|
||||
if (!rowMatch.includes('物料编号') || rowMatch.includes('colspan')) return rowMatch
|
||||
let row = rowMatch.includes('delivery-slip-product-header')
|
||||
? rowMatch
|
||||
@@ -791,7 +797,7 @@ function normalizeDeliverySlipProductGridCell(html: string): string {
|
||||
})
|
||||
})
|
||||
|
||||
result = result.replace(/<tr([^>]*)>\s*(<td(?![^>]*colspan)[^>]*>[\s\S]*?<\/td>\s*){7}\s*<\/tr>/g, (rowMatch) => {
|
||||
result = result.replace(/<tr([^>]*)>\s*(<td(?![^>]*colspan)[^>]*>[\s\S]*?<\/td>\s*){8}\s*<\/tr>/g, (rowMatch) => {
|
||||
if (
|
||||
rowMatch.includes('备注') ||
|
||||
rowMatch.includes('1.本送货单') ||
|
||||
@@ -1120,9 +1126,10 @@ function normalizeDeliverySlipProductTableFooter(html: string): string {
|
||||
|
||||
let result = html
|
||||
|
||||
result = result.replace(/<td([^>]*colspan="7"[^>]*)>(\s*)备注:/g, (_match, attrs, space) => {
|
||||
result = result.replace(/<td([^>]*colspan="[78]"[^>]*)>(\s*)备注:/g, (_match, attrs, space) => {
|
||||
const withSpan = String(attrs).replace(/colspan="[78]"/, 'colspan="8"')
|
||||
const patched = patchProductFooterCellAttrs(
|
||||
attrs,
|
||||
withSpan,
|
||||
'delivery-slip-product-cell',
|
||||
PRODUCT_TABLE_CELL_LEFT
|
||||
)
|
||||
@@ -1130,9 +1137,9 @@ function normalizeDeliverySlipProductTableFooter(html: string): string {
|
||||
})
|
||||
|
||||
result = result.replace(
|
||||
/<td([^>]*colspan="[45]"[^>]*)>\s*(<div class="delivery-slip-terms-text"|\s*1\.本送货单)/g,
|
||||
/<td([^>]*colspan="[456]"[^>]*)>\s*(<div class="delivery-slip-terms-text"|\s*1\.本送货单)/g,
|
||||
(_match, attrs, contentStart) => {
|
||||
const withSpan = String(attrs).replace(/colspan="[45]"/, 'colspan="5"')
|
||||
const withSpan = String(attrs).replace(/colspan="[456]"/, 'colspan="5"')
|
||||
const patched = patchProductFooterCellAttrs(
|
||||
withSpan,
|
||||
'delivery-slip-product-cell delivery-slip-terms-cell',
|
||||
@@ -1145,7 +1152,7 @@ function normalizeDeliverySlipProductTableFooter(html: string): string {
|
||||
result = result.replace(
|
||||
/<td([^>]*colspan="[23]"[^>]*)>\s*<div class="delivery-slip-seal-block"/g,
|
||||
(_match, attrs) => {
|
||||
const withSpan = String(attrs).replace(/colspan="[23]"/, 'colspan="2"')
|
||||
const withSpan = String(attrs).replace(/colspan="[23]"/, 'colspan="3"')
|
||||
const patched = patchProductFooterCellAttrs(withSpan, 'delivery-slip-product-cell', PRODUCT_TABLE_CELL_LEFT)
|
||||
return `<td${patched}>\n <div class="delivery-slip-seal-block"`
|
||||
}
|
||||
@@ -1176,7 +1183,7 @@ function normalizeDeliverySlipTermsCell(html: string): string {
|
||||
}
|
||||
|
||||
let result = html.replace(
|
||||
/<td colspan="[45]"([^>]*)>\s*<div class="delivery-slip-terms-text"/g,
|
||||
/<td colspan="[456]"([^>]*)>\s*<div class="delivery-slip-terms-text"/g,
|
||||
(match, attrs) => {
|
||||
if (attrs.includes('delivery-slip-terms-cell') && attrs.includes('border:0.3px solid #000') && /colspan="5"/.test(match)) {
|
||||
return match
|
||||
@@ -1227,10 +1234,15 @@ function normalizeDeliverySlipTermsText(html: string): string {
|
||||
|
||||
/** 刷新已有间距行的 inline 样式(TinyMCE 保存后可能丢失) */
|
||||
function refreshDeliverySlipGapBeforeProduct(html: string): string {
|
||||
return html.replace(
|
||||
/<tr class="delivery-slip-gap-before-product">[\s\S]*?<\/tr>/,
|
||||
`<tr class="delivery-slip-gap-before-product">\n <td colspan="7" class="delivery-slip-gap-before-product-cell" style="${GAP_BEFORE_PRODUCT_CELL}"> </td>\n </tr>`
|
||||
)
|
||||
return html
|
||||
.replace(
|
||||
/<tr class="delivery-slip-gap-before-product">[\s\S]*?<\/tr>/,
|
||||
`<tr class="delivery-slip-gap-before-product">\n <td colspan="8" class="delivery-slip-gap-before-product-cell" style="${GAP_BEFORE_PRODUCT_CELL}"> </td>\n </tr>`
|
||||
)
|
||||
.replace(
|
||||
/<div class="delivery-slip-section-gap delivery-slip-gap-before-product"[^>]*>[\s\S]*?<\/div>/,
|
||||
`<div class="delivery-slip-section-gap delivery-slip-gap-before-product" style="${GAP_BEFORE_PRODUCT_CELL}"> </div>`
|
||||
)
|
||||
}
|
||||
|
||||
/** 在收货联系方式行与物料表之间插入间距行(兼容已保存模板) */
|
||||
@@ -1243,32 +1255,42 @@ function normalizeDeliverySlipGapBeforeProduct(html: string): string {
|
||||
return refreshDeliverySlipGapBeforeProduct(html)
|
||||
}
|
||||
|
||||
const gapRow = `<tr class="delivery-slip-gap-before-product"><td colspan="7" class="delivery-slip-gap-before-product-cell" style="${GAP_BEFORE_PRODUCT_CELL}"> </td></tr>\n `
|
||||
const gapRow = `<tr class="delivery-slip-gap-before-product"><td colspan="8" class="delivery-slip-gap-before-product-cell" style="${GAP_BEFORE_PRODUCT_CELL}"> </td></tr>\n `
|
||||
const productHeader = `(?:单据编号|物料编号)`
|
||||
|
||||
const withComment = html.replace(
|
||||
/(<span class="delivery-slip-info-label"[^>]*>日(?: )?期:<\/span>[\s\S]*?<\/tr>\s*)(<!--\s*中:产品明细表[\s\S]*?<tr>\s*<th[^>]*>物料编号)/,
|
||||
new RegExp(
|
||||
`(收货联系方式:[\\s\\S]*?<\\/tr>\\s*)(<!--\\s*中:产品明细表[\\s\\S]*?<tr[\\s\\S]*?<th[^>]*>${productHeader})`
|
||||
),
|
||||
`$1${gapRow}$2`
|
||||
)
|
||||
if (withComment !== html) return withComment
|
||||
|
||||
const withHeader = html.replace(
|
||||
/(<span class="delivery-slip-info-label"[^>]*>日(?: )?期:<\/span>[\s\S]*?<\/tr>\s*)(<tr>\s*<th[^>]*>物料编号)/,
|
||||
new RegExp(`(收货联系方式:[\\s\\S]*?<\\/tr>\\s*)(<tr[\\s\\S]*?<th[^>]*>${productHeader})`),
|
||||
`$1${gapRow}$2`
|
||||
)
|
||||
if (withHeader !== html) return withHeader
|
||||
|
||||
return html.replace(
|
||||
/(收货联系方式:[\s\S]*?<\/tr>\s*)(<!--\s*中:产品明细表[\s\S]*?<tr>\s*<th[^>]*>物料编号|<tr>\s*<th[^>]*>物料编号)/,
|
||||
new RegExp(
|
||||
`(<span class="delivery-slip-info-label"[^>]*>日(?: )?期:<\\/span>[\\s\\S]*?<\\/tr>\\s*)(<!--\\s*中:产品明细表[\\s\\S]*?<tr[\\s\\S]*?<th[^>]*>${productHeader}|<tr[\\s\\S]*?<th[^>]*>${productHeader})`
|
||||
),
|
||||
`$1${gapRow}$2`
|
||||
)
|
||||
}
|
||||
|
||||
/** 刷新签字区上方间距行 inline 样式 */
|
||||
function refreshDeliverySlipGapBeforeSign(html: string): string {
|
||||
return html.replace(
|
||||
/<tr class="delivery-slip-gap-before-sign">[\s\S]*?<\/tr>/,
|
||||
`<tr class="delivery-slip-gap-before-sign">\n <td colspan="7" class="delivery-slip-gap-before-sign-cell" style="${GAP_BEFORE_SIGN_CELL}"> </td>\n </tr>`
|
||||
)
|
||||
return html
|
||||
.replace(
|
||||
/<tr class="delivery-slip-gap-before-sign">[\s\S]*?<\/tr>/,
|
||||
`<tr class="delivery-slip-gap-before-sign">\n <td colspan="8" class="delivery-slip-gap-before-sign-cell" style="${GAP_BEFORE_SIGN_CELL}"> </td>\n </tr>`
|
||||
)
|
||||
.replace(
|
||||
/<div class="delivery-slip-section-gap delivery-slip-gap-before-sign"[^>]*>[\s\S]*?<\/div>/,
|
||||
`<div class="delivery-slip-section-gap delivery-slip-gap-before-sign" style="${GAP_BEFORE_SIGN_CELL}"> </div>`
|
||||
)
|
||||
}
|
||||
|
||||
/** 在物料表与签字区之间插入间距行(兼容已保存模板) */
|
||||
@@ -1279,16 +1301,16 @@ function normalizeDeliverySlipGapBeforeSign(html: string): string {
|
||||
return refreshDeliverySlipGapBeforeSign(html)
|
||||
}
|
||||
|
||||
const gapRow = `<tr class="delivery-slip-gap-before-sign"><td colspan="7" class="delivery-slip-gap-before-sign-cell" style="${GAP_BEFORE_SIGN_CELL}"> </td></tr>\n\n `
|
||||
const gapRow = `<tr class="delivery-slip-gap-before-sign"><td colspan="8" class="delivery-slip-gap-before-sign-cell" style="${GAP_BEFORE_SIGN_CELL}"> </td></tr>\n\n `
|
||||
|
||||
const withComment = html.replace(
|
||||
/(<\/tr>\s*)(<!--\s*下:签字区[\s\S]*?<tr>\s*<td colspan="7"[^>]*>\s*仓库:)/,
|
||||
/(<\/tr>\s*)(<!--\s*下:签字区[\s\S]*?<tr>\s*<td colspan="[78]"[^>]*>\s*仓库:)/,
|
||||
`$1${gapRow}$2`
|
||||
)
|
||||
if (withComment !== html) return withComment
|
||||
|
||||
return html.replace(
|
||||
/(delivery-slip-seal-block[\s\S]*?<\/tr>\s*)(<tr>\s*<td colspan="7"[^>]*>\s*仓库:)/,
|
||||
/(delivery-slip-seal-block[\s\S]*?<\/tr>\s*)(<tr>\s*<td colspan="[78]"[^>]*>\s*仓库:)/,
|
||||
`$1${gapRow}$2`
|
||||
)
|
||||
}
|
||||
@@ -1323,7 +1345,7 @@ function normalizeDeliverySlipSignRow(html: string): string {
|
||||
if (!html.includes('delivery-slip-doc') || !html.includes('仓库:')) return html
|
||||
|
||||
let result = html.replace(
|
||||
/<tr([^>]*)>\s*<td colspan="7"([^>]*)>([\s\S]*?仓库:[\s\S]*?司机\/送货人\(附车牌\)[^<]*[\s\S]*?)<\/td>\s*<\/tr>/g,
|
||||
/<tr([^>]*)>\s*<td colspan="[78]"([^>]*)>([\s\S]*?仓库:[\s\S]*?司机\/送货人\(附车牌\)[^<]*[\s\S]*?)<\/td>\s*<\/tr>/g,
|
||||
(match, trAttrs, tdAttrs, content) => {
|
||||
if (!content.includes('delivery-slip-sign-value') || content.includes('delivery-slip-sign-inner')) {
|
||||
return match
|
||||
@@ -1355,7 +1377,7 @@ function normalizeDeliverySlipSignRow(html: string): string {
|
||||
nextTdAttrs = `${nextTdAttrs} class="delivery-slip-sign-row-cell"`
|
||||
}
|
||||
|
||||
return `<tr${trClassAttr}>\n <td colspan="7"${nextTdAttrs}>\n <div class="delivery-slip-sign-inner">${wrappedContent.trim()}</div>\n </td>\n </tr>`
|
||||
return `<tr${trClassAttr}>\n <td colspan="8"${nextTdAttrs}>\n <div class="delivery-slip-sign-inner">${wrappedContent.trim()}</div>\n </td>\n </tr>`
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1367,6 +1389,89 @@ function normalizeDeliverySlipSignRow(html: string): string {
|
||||
return normalizeDeliverySlipSignLabelMarkup(result)
|
||||
}
|
||||
|
||||
/** 信息区:收货单位 / 收货联系方式 / 日期 同一行(兼容旧多行布局) */
|
||||
function normalizeDeliverySlipInfoLayout(html: string): string {
|
||||
if (!html.includes('delivery-slip-info-table')) return html
|
||||
|
||||
const infoMatch = html.match(/<table class="delivery-slip-info-table"[^>]*>[\s\S]*?<\/table>/i)
|
||||
if (!infoMatch) return html
|
||||
|
||||
const infoHtml = infoMatch[0]
|
||||
const rowCount = (infoHtml.match(/<tr[\s>]/g) || []).length
|
||||
const hasPlanNoInInfo = infoHtml.includes('单据编号:')
|
||||
const dateColWideEnough = /<td[^>]*colspan="3"[^>]*>[\s\S]*?日(?: )?期:/.test(infoHtml)
|
||||
const oneRowThreeFields =
|
||||
rowCount === 1 &&
|
||||
infoHtml.includes('收货单位:') &&
|
||||
infoHtml.includes('收货联系方式:') &&
|
||||
/日(?: )?期:/.test(infoHtml) &&
|
||||
!hasPlanNoInInfo &&
|
||||
dateColWideEnough
|
||||
|
||||
if (oneRowThreeFields) return html
|
||||
|
||||
return html.replace(infoMatch[0], buildDeliverySlipInfoTableHtml())
|
||||
}
|
||||
|
||||
/** 物料表:表头补「单据编号」列,并把旧 7 列数据行升为 8 列(兼容已保存模板) */
|
||||
function normalizeDeliverySlipProductPlanNoColumn(html: string): string {
|
||||
if (!html.includes('delivery-slip-product-table')) return html
|
||||
|
||||
let result = html
|
||||
|
||||
if (!/>单据编号<\/th>/.test(result)) {
|
||||
result = result.replace(
|
||||
/(<tr[^>]*class="[^"]*delivery-slip-product-header[^"]*"[^>]*>\s*)(<th[^>]*>物料编号<\/th>)/,
|
||||
`$1<th class="delivery-slip-product-cell delivery-slip-product-grid-cell" style="${PRODUCT_TH}">单据编号</th>\n $2`
|
||||
)
|
||||
result = result.replace(
|
||||
/(<tr>\s*)(<th[^>]*>物料编号<\/th>)/,
|
||||
`$1<th class="delivery-slip-product-cell delivery-slip-product-grid-cell" style="${PRODUCT_TH}">单据编号</th>\n $2`
|
||||
)
|
||||
}
|
||||
|
||||
// 旧 7 列明细行:在首格前插入单据编号占位
|
||||
result = result.replace(
|
||||
/<tr([^>]*)>\s*((?:<td(?![^>]*colspan)[^>]*>[\s\S]*?<\/td>\s*){7})<\/tr>/g,
|
||||
(rowMatch, trAttrs, cells) => {
|
||||
if (
|
||||
rowMatch.includes('备注') ||
|
||||
rowMatch.includes('1.本送货单') ||
|
||||
rowMatch.includes('仓库:') ||
|
||||
rowMatch.includes('暂无产品信息') ||
|
||||
rowMatch.includes('单据编号')
|
||||
) {
|
||||
return rowMatch
|
||||
}
|
||||
return `<tr${trAttrs}>\n <td class="delivery-slip-product-cell delivery-slip-product-grid-cell" style="${PRODUCT_GRID_CELL}">{{planNo}}</td>\n ${cells}</tr>`
|
||||
}
|
||||
)
|
||||
|
||||
// 仅升级物料表内备注等跨列,条款区保持 5 列、印章区 3 列
|
||||
result = result.replace(
|
||||
/(<table class="delivery-slip-product-table"[^>]*>)([\s\S]*?)(<\/table>)/i,
|
||||
(_m, open, inner, close) => {
|
||||
let nextInner = String(inner).replace(/colspan="7"/g, 'colspan="8"')
|
||||
nextInner = nextInner.replace(
|
||||
/(<td[^>]*colspan=")6("[^>]*>\s*(?:<div class="delivery-slip-terms-text"|[\s]*1\.本送货单))/g,
|
||||
'$15$2'
|
||||
)
|
||||
nextInner = nextInner.replace(
|
||||
/(<td[^>]*colspan=")2("[^>]*>\s*<div class="delivery-slip-seal-block")/g,
|
||||
'$13$2'
|
||||
)
|
||||
return `${open}${nextInner}${close}`
|
||||
}
|
||||
)
|
||||
|
||||
result = result.replace(
|
||||
/(<table class="delivery-slip-sign-table"[^>]*>)([\s\S]*?)(<\/table>)/i,
|
||||
(_m, open, inner, close) => `${open}${String(inner).replace(/colspan="7"/g, 'colspan="8"')}${close}`
|
||||
)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 旧版一体 layout-table / 曾拆出的 footer-table → 信息表 + 物料表(含备注条款) + 签字表。
|
||||
*/
|
||||
@@ -1398,6 +1503,7 @@ function migrateDeliverySlipSplitTables(html: string): string {
|
||||
(_full, inner: string) => {
|
||||
const headerMatch =
|
||||
inner.match(/<tr[^>]*class="[^"]*delivery-slip-product-header[^"]*"[\s\S]*?<\/tr>/i) ||
|
||||
inner.match(/<tr>\s*<th[^>]*>单据编号[\s\S]*?<\/tr>/i) ||
|
||||
inner.match(/<tr>\s*<th[^>]*>物料编号[\s\S]*?<\/tr>/i)
|
||||
if (!headerMatch) return _full
|
||||
|
||||
@@ -1510,6 +1616,8 @@ function normalizeDeliverySlipDocLayout(html: string): string {
|
||||
|
||||
if (result.includes('delivery-slip-doc')) {
|
||||
result = result.replace(/<style type="text\/css">[\s\S]*?<\/style>/, DELIVERY_SLIP_STYLE_BLOCK)
|
||||
result = normalizeDeliverySlipInfoLayout(result)
|
||||
result = normalizeDeliverySlipProductPlanNoColumn(result)
|
||||
result = normalizeDeliverySlipSignLabelMarkup(result)
|
||||
result = normalizeDeliverySlipProductGridCell(result)
|
||||
result = normalizeDeliverySlipProductTableFooter(result)
|
||||
@@ -1529,7 +1637,7 @@ function refreshDeliverySlipTypeCheckRowStyle(html: string): string {
|
||||
result = result.replace(
|
||||
/<div class="delivery-slip-type-check-row"[^>]*>([\s\S]*?)<\/div>/,
|
||||
(_match, inner) =>
|
||||
`<div class="delivery-slip-info-row delivery-slip-type-check-wrap" style="${DELIVERY_SLIP_TYPE_CHECK_WRAP_STYLE}"><span class="delivery-slip-info-label delivery-slip-type-check-spacer" style="${INFO_LABEL}visibility:hidden;">单据编号:</span><div class="delivery-slip-type-check-row" style="${DELIVERY_SLIP_TYPE_CHECK_INNER_STYLE}">${inner}</div></div>`
|
||||
`<div class="delivery-slip-info-row delivery-slip-type-check-wrap" style="${DELIVERY_SLIP_TYPE_CHECK_WRAP_STYLE}"><span class="delivery-slip-info-label delivery-slip-type-check-spacer" style="${INFO_LABEL}visibility:hidden;">日 期:</span><div class="delivery-slip-type-check-row" style="${DELIVERY_SLIP_TYPE_CHECK_INNER_STYLE}">${inner}</div></div>`
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1537,6 +1645,10 @@ function refreshDeliverySlipTypeCheckRowStyle(html: string): string {
|
||||
/<div class="delivery-slip-info-row delivery-slip-type-check-wrap"[^>]*>/g,
|
||||
`<div class="delivery-slip-info-row delivery-slip-type-check-wrap" style="${DELIVERY_SLIP_TYPE_CHECK_WRAP_STYLE}">`
|
||||
)
|
||||
result = result.replace(
|
||||
/<span class="delivery-slip-info-label delivery-slip-type-check-spacer"[^>]*>[\s\S]*?<\/span>/g,
|
||||
`<span class="delivery-slip-info-label delivery-slip-type-check-spacer" style="${INFO_LABEL}visibility:hidden;">日 期:</span>`
|
||||
)
|
||||
result = result.replace(
|
||||
/<div class="delivery-slip-type-check-row"[^>]*>/g,
|
||||
`<div class="delivery-slip-type-check-row" style="${DELIVERY_SLIP_TYPE_CHECK_INNER_STYLE}">`
|
||||
@@ -1557,12 +1669,26 @@ function normalizeDeliverySlipTypeCheckRow(html: string): string {
|
||||
const checkRowHtml = buildDeliverySlipTypeCheckboxesHtml()
|
||||
|
||||
const withClass = result.replace(
|
||||
/(<td colspan="3"[^>]*style="[^"]*"[^>]*>\s*)(<div class="delivery-slip-info-row"[^>]*>\s*<span class="delivery-slip-info-label"[^>]*>单据编号:)/,
|
||||
/(<td colspan="3"[^>]*style="[^"]*"[^>]*>\s*)(<div class="delivery-slip-info-row"[^>]*>\s*<span class="delivery-slip-info-label"[^>]*>日(?: )?期:)/,
|
||||
`$1${checkRowHtml}\n $2`
|
||||
)
|
||||
if (withClass !== result) {
|
||||
result = withClass
|
||||
} else {
|
||||
result = result.replace(
|
||||
/(<td colspan="3"[^>]*>\s*)(<div class="delivery-slip-info-row"[^>]*>\s*<span class="delivery-slip-info-label"[^>]*>日(?: )?期:)/,
|
||||
`$1${checkRowHtml}\n $2`
|
||||
)
|
||||
}
|
||||
// 兼容旧模板:日期在 colspan=2 单元格时仍插多选
|
||||
if (!result.includes('delivery-slip-type-check-row')) {
|
||||
result = result.replace(
|
||||
/(<td colspan="2"[^>]*>\s*)(<div class="delivery-slip-info-row"[^>]*>\s*<span class="delivery-slip-info-label"[^>]*>日(?: )?期:)/,
|
||||
`$1${checkRowHtml}\n $2`
|
||||
)
|
||||
}
|
||||
// 兼容更旧模板:单据编号位置仍插多选,随后由 infoLayout 迁移
|
||||
if (!result.includes('delivery-slip-type-check-row')) {
|
||||
result = result.replace(
|
||||
/(<td colspan="3"[^>]*>\s*)(<div class="delivery-slip-info-row"[^>]*>\s*<span class="delivery-slip-info-label"[^>]*>单据编号:)/,
|
||||
`$1${checkRowHtml}\n $2`
|
||||
@@ -1673,7 +1799,7 @@ export function replaceDeliverySlipPlaceholders(
|
||||
'{{receiveContact}}': '',
|
||||
'{{driverInfo}}': '',
|
||||
'{{planDateChinese}}': formatPlanDateChinese(plan.planDate),
|
||||
'{{productTable}}': buildProductRows(plan.products, ctx),
|
||||
'{{productTable}}': buildProductRows(plan.products, plan.planNo || '', ctx),
|
||||
'{{remark}}': plan.remark || '',
|
||||
'{{companyAddress}}': DELIVERY_SLIP_DEFAULTS.companyAddress,
|
||||
'{{companyPhone}}': DELIVERY_SLIP_DEFAULTS.companyPhone,
|
||||
@@ -1691,8 +1817,12 @@ export function replaceDeliverySlipPlaceholders(
|
||||
normalizeDeliverySlipProductTableFooter(
|
||||
normalizeDeliverySlipProductColWidths(
|
||||
normalizeDeliverySlipProductGridCell(
|
||||
normalizeDeliverySlipGapBeforeProduct(
|
||||
normalizeDeliverySlipTypeCheckRow(normalizeDeliverySlipSideLabelsPlaceholder(htmlContent))
|
||||
normalizeDeliverySlipProductPlanNoColumn(
|
||||
normalizeDeliverySlipInfoLayout(
|
||||
normalizeDeliverySlipGapBeforeProduct(
|
||||
normalizeDeliverySlipTypeCheckRow(normalizeDeliverySlipSideLabelsPlaceholder(htmlContent))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1732,7 +1862,7 @@ export function restoreDeliverySlipPlaceholders(template: string, plan: Plan): s
|
||||
|
||||
// 产品明细行还原为占位符(表头「实收数量」之后、页脚「备注」之前;兼容分表与旧一体表)
|
||||
result = result.replace(
|
||||
/(<th[^>]*>实收数量<\/th>\s*<\/tr>\s*)([\s\S]*?)(\s*<tr>\s*<td colspan="7"[^>]*>\s*备注:)/,
|
||||
/(<th[^>]*>实收数量<\/th>\s*<\/tr>\s*)([\s\S]*?)(\s*<tr>\s*<td colspan="[78]"[^>]*>\s*备注:)/,
|
||||
'$1{{productTable}}$3'
|
||||
)
|
||||
|
||||
|
||||
@@ -184,6 +184,25 @@ export function getPlPlanTypeLabel(type?: string) {
|
||||
return type ? map[type] || type : '—'
|
||||
}
|
||||
|
||||
/** 打印单据下拉项:入库单 / 送(提)货单 / 分装单 */
|
||||
export type PlPrintSlipCommand = 'inbound' | 'delivery' | 'subpack'
|
||||
|
||||
/**
|
||||
* 按运输计划单据类型返回可打印的单据命令。
|
||||
* - inbound:仅入库单
|
||||
* - outbound:送(提)货单、分装单
|
||||
* - direct / 其他:不可打印
|
||||
*/
|
||||
export function getPrintableSlipCommands(planType?: string): PlPrintSlipCommand[] {
|
||||
if (planType === 'inbound') return ['inbound']
|
||||
if (planType === 'outbound') return ['delivery', 'subpack']
|
||||
return []
|
||||
}
|
||||
|
||||
export function canPrintSlipCommand(planType: string | undefined, command: PlPrintSlipCommand) {
|
||||
return getPrintableSlipCommands(planType).includes(command)
|
||||
}
|
||||
|
||||
export type PlPlanTypeTab = 'all' | 'inbound' | 'outbound' | 'direct'
|
||||
|
||||
export const PL_PLAN_TYPE_TABS: { label: string; name: PlPlanTypeTab }[] = [
|
||||
|
||||
@@ -88,64 +88,70 @@
|
||||
<el-icon><Plus /></el-icon>新增计划
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="selectedPlan && canEditPlan(selectedPlan)"
|
||||
class="btn-ghost"
|
||||
:disabled="selectedRows.length !== 1"
|
||||
:disabled="!selectedPlan || !canEditPlan(selectedPlan)"
|
||||
@click="handleToolbarEdit"
|
||||
>
|
||||
<el-icon><Edit /></el-icon>编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="selectedPlan && canArrangeTransport(selectedPlan)"
|
||||
class="btn-ghost"
|
||||
:disabled="selectedRows.length !== 1"
|
||||
:disabled="!selectedPlan || !canArrangeTransport(selectedPlan)"
|
||||
@click="handleToolbarArrange"
|
||||
>
|
||||
<el-icon><Van /></el-icon>{{ arrangeTransportLabel(selectedPlan) }}
|
||||
<el-icon><Van /></el-icon>
|
||||
{{ selectedPlan ? arrangeTransportLabel(selectedPlan) : '安排运输' }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="btn-ghost"
|
||||
:disabled="selectedRows.length !== 1"
|
||||
@click="handleToolbarPrintInboundSlip"
|
||||
<el-dropdown
|
||||
trigger="click"
|
||||
:disabled="!selectedPlan"
|
||||
@command="handleToolbarPrintSlip"
|
||||
>
|
||||
<el-icon><Printer /></el-icon>入库单
|
||||
</el-button>
|
||||
<el-button class="btn-ghost" :disabled="!selectedPlan">
|
||||
<el-icon><Printer /></el-icon>打印单据
|
||||
<el-icon class="el-icon--right"><ArrowDown /></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
command="inbound"
|
||||
:disabled="!canPrintSlipCommand(selectedPlan?.planType, 'inbound')"
|
||||
>
|
||||
入库单
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
command="delivery"
|
||||
:disabled="!canPrintSlipCommand(selectedPlan?.planType, 'delivery')"
|
||||
>
|
||||
送(提)货单
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
command="subpack"
|
||||
:disabled="!canPrintSlipCommand(selectedPlan?.planType, 'subpack')"
|
||||
>
|
||||
分装单
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<el-button
|
||||
class="btn-ghost"
|
||||
:disabled="selectedRows.length !== 1"
|
||||
@click="handleToolbarPrintDeliverySlip"
|
||||
>
|
||||
<el-icon><Printer /></el-icon>送(提)货单
|
||||
</el-button>
|
||||
<el-button
|
||||
class="btn-ghost"
|
||||
:disabled="selectedRows.length !== 1"
|
||||
@click="handleToolbarPrintSubpackSlip"
|
||||
>
|
||||
<el-icon><Printer /></el-icon>分装单
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="selectedPlan && canVoidPlan(selectedPlan)"
|
||||
class="btn-ghost"
|
||||
type="danger"
|
||||
:disabled="selectedRows.length !== 1"
|
||||
:disabled="!selectedPlan || !canVoidPlan(selectedPlan)"
|
||||
:loading="voidLoading"
|
||||
@click="handleToolbarVoid"
|
||||
>
|
||||
<el-icon><CircleClose /></el-icon>作废
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="selectedPlan && canDeletePlan(selectedPlan)"
|
||||
class="btn-ghost"
|
||||
type="danger"
|
||||
:disabled="
|
||||
selectedRows.length !== 1 || !canDeleteByCreator(selectedPlan)
|
||||
"
|
||||
:title="
|
||||
selectedRows.length === 1
|
||||
? getDeletePlanDisabledTitle(selectedPlan)
|
||||
: ''
|
||||
!selectedPlan ||
|
||||
!canDeletePlan(selectedPlan) ||
|
||||
!canDeleteByCreator(selectedPlan)
|
||||
"
|
||||
:title="selectedPlan ? getDeletePlanDisabledTitle(selectedPlan) : ''"
|
||||
:loading="deleteLoading"
|
||||
@click="handleToolbarDelete"
|
||||
>
|
||||
@@ -338,24 +344,34 @@
|
||||
>
|
||||
<el-icon><Van /></el-icon>{{ arrangeTransportLabel(viewingPlan) }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="btn-ghost"
|
||||
@click="handlePrintInboundSlip(viewingPlan)"
|
||||
>
|
||||
<el-icon><Printer /></el-icon>入库单
|
||||
</el-button>
|
||||
<el-button
|
||||
class="btn-ghost"
|
||||
@click="handlePrintDeliverySlip(viewingPlan)"
|
||||
>
|
||||
<el-icon><Printer /></el-icon>送(提)货单
|
||||
</el-button>
|
||||
<el-button
|
||||
class="btn-ghost"
|
||||
@click="handlePrintSubpackSlip(viewingPlan)"
|
||||
>
|
||||
<el-icon><Printer /></el-icon>分装单
|
||||
</el-button>
|
||||
<el-dropdown trigger="click" @command="handleViewPrintSlipCommand">
|
||||
<el-button class="btn-ghost">
|
||||
<el-icon><Printer /></el-icon>打印单据
|
||||
<el-icon class="el-icon--right"><ArrowDown /></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
command="inbound"
|
||||
:disabled="!canPrintSlipCommand(viewingPlan?.planType, 'inbound')"
|
||||
>
|
||||
入库单
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
command="delivery"
|
||||
:disabled="!canPrintSlipCommand(viewingPlan?.planType, 'delivery')"
|
||||
>
|
||||
送(提)货单
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
command="subpack"
|
||||
:disabled="!canPrintSlipCommand(viewingPlan?.planType, 'subpack')"
|
||||
>
|
||||
分装单
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<el-button
|
||||
v-if="canVoidPlan(viewingPlan)"
|
||||
class="btn-ghost"
|
||||
@@ -393,6 +409,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ArrowDown,
|
||||
CircleClose,
|
||||
Delete,
|
||||
Edit,
|
||||
@@ -420,10 +437,12 @@ import { useDbInstantSearch } from '@/composables/useDbInstantSearch'
|
||||
import { useListDateShortcut } from '@/composables/useListDateShortcut'
|
||||
import { canDeleteByCreator, CREATOR_DELETE_TIP } from '@/utils/creator-delete'
|
||||
import {
|
||||
canPrintSlipCommand,
|
||||
formatPlVehiclePlateDisplay,
|
||||
normalizePlPersonnelSummaryDisplay,
|
||||
plPlanTypeTabToFilter,
|
||||
type PlPlanTypeTab
|
||||
type PlPlanTypeTab,
|
||||
type PlPrintSlipCommand
|
||||
} from '@/utils/pl-display'
|
||||
import { syncViewRowFromFlatList } from '@/utils/view-dialog-refresh'
|
||||
const route = useRoute()
|
||||
@@ -726,31 +745,30 @@ function handleArrange(row: Plan) {
|
||||
arrangeDialogVisible.value = true
|
||||
}
|
||||
|
||||
function handlePrintInboundSlip(row: Plan) {
|
||||
inboundSlipPrintRef.value?.open(row.id)
|
||||
}
|
||||
|
||||
function handlePrintDeliverySlip(row: Plan) {
|
||||
deliverySlipPrintRef.value?.open(row.id)
|
||||
}
|
||||
|
||||
function handlePrintSubpackSlip(row: Plan) {
|
||||
function handlePrintSlip(command: PlPrintSlipCommand, row: Plan) {
|
||||
if (!canPrintSlipCommand(row.planType, command)) {
|
||||
ElMessage.warning('当前单据类型不支持打印该单据')
|
||||
return
|
||||
}
|
||||
if (command === 'inbound') {
|
||||
inboundSlipPrintRef.value?.open(row.id)
|
||||
return
|
||||
}
|
||||
if (command === 'delivery') {
|
||||
deliverySlipPrintRef.value?.open(row.id)
|
||||
return
|
||||
}
|
||||
subpackSlipPrintRef.value?.open(row.id)
|
||||
}
|
||||
|
||||
function handleToolbarPrintInboundSlip() {
|
||||
if (selectedRows.value.length !== 1) return
|
||||
handlePrintInboundSlip(selectedRows.value[0])
|
||||
function handleViewPrintSlipCommand(command: string) {
|
||||
if (!viewingPlan.value) return
|
||||
handlePrintSlip(command as PlPrintSlipCommand, viewingPlan.value)
|
||||
}
|
||||
|
||||
function handleToolbarPrintDeliverySlip() {
|
||||
function handleToolbarPrintSlip(command: string) {
|
||||
if (selectedRows.value.length !== 1) return
|
||||
handlePrintDeliverySlip(selectedRows.value[0])
|
||||
}
|
||||
|
||||
function handleToolbarPrintSubpackSlip() {
|
||||
if (selectedRows.value.length !== 1) return
|
||||
handlePrintSubpackSlip(selectedRows.value[0])
|
||||
handlePrintSlip(command as PlPrintSlipCommand, selectedRows.value[0])
|
||||
}
|
||||
|
||||
function handleToolbarEdit() {
|
||||
|
||||
Reference in new issue
Block a user