This commit is contained in:
2026-10-20 23:34:11 +08:00
parent f155976f52
commit 13e4aa56ec
321 changed files with 6756 additions and 2110 deletions
@@ -1,6 +1,7 @@
<script setup lang="ts">
import InlineHelp from '@/shared/components/InlineHelp.vue'
import '@/styles/adminDensity.css'
import '@/styles/adminWorkbench.css'
import { computed, onMounted, onBeforeUnmount, reactive, ref, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getFinancePaymentVoucher, downloadFinancePaymentVoucher } from '@/modules/finance'
@@ -165,7 +166,7 @@ onMounted(load)
</script>
<template>
<div class="last-leg-fees admin-density">
<div class="last-leg-fees admin-density admin-workbench">
<header class="last-leg-fees__header"><div><h2>{{ title }}<InlineHelp title="费用统计说明"><p>按真实货柜展示港口、堆存、修箱、吊机和码头拖车费用,金额按币种分别列示。</p></InlineHelp></h2></div><el-button v-if="canEdit" type="primary" :disabled="!containerNo || customers.length === 0" @click="openCreate">新增费用</el-button></header>
<el-alert v-if="canView && !canEdit && !canReview" type="info" :closable="false" title="当前账号仅有海外段费用查看权限。" />
<el-alert v-if="!containerNo" type="warning" :closable="false" title="当前货柜尚未补录真实集装箱号,暂不能新增尾程费用。" />
@@ -184,21 +185,21 @@ onMounted(load)
<el-table-column label="作废确认" min-width="130"><template #default="{ row }">{{ voidLabels[row.voidStatus] || '—' }}</template></el-table-column>
<el-table-column prop="reviewReason" label="审核说明" min-width="180" show-overflow-tooltip><template #default="{ row }">{{ row.reviewReason || '—' }}</template></el-table-column>
</el-table>
<AppDialog class="admin-density-dialog" v-model="dialogOpen" :title="containerDialogTitle(editing ? '调整尾程费用' : '新增尾程费用', props)" width="min(920px, calc(100vw - 28px))" fullscreenable confirm-text="保存" :confirm-loading="actionLoading" :confirm-disabled="voucherUploading" @confirm="save">
<AppDialog class="admin-density-dialog admin-workbench is-dialog" v-model="dialogOpen" :title="containerDialogTitle(editing ? '调整尾程费用' : '新增尾程费用', props)" width="min(920px, calc(100vw - 28px))" fullscreenable confirm-text="保存" :confirm-loading="actionLoading" :confirm-disabled="voucherUploading" @confirm="save">
<section class="density-dialog-section" data-tone="work">
<el-form class="density-form" label-position="left">
<table class="density-table density-table--editable fee-editor-table" aria-label="尾程费用填写"><tbody>
<div class="workbench-evidence"><table class="density-table density-table--editable fee-editor-table" aria-label="尾程费用填写"><tbody>
<tr><td><el-form-item label-position="left" label-width="110px" label="客户" required><span v-if="editing">{{ customerName(form.customerId) || editing.customerName || '—' }}</span><el-select v-else v-model="form.customerId" :disabled="voucherUploading" placeholder="请选择柜内客户"><el-option v-for="customer in customers" :key="customer.customerId" :label="customer.customerName || '未命名客户'" :value="customer.customerId" /></el-select></el-form-item></td><td><el-form-item label-position="left" label-width="110px" label="费用项目" required><el-select v-model="form.feeItemCode"><el-option v-for="item in feeItems" :key="item.value" :label="item.label" :value="item.value" /></el-select></el-form-item></td></tr>
<tr><td><el-form-item label-position="left" label-width="110px" label="费用方向" required><el-select v-model="form.direction"><el-option label="应收" value="RECEIVABLE" /><el-option label="应付" value="PAYABLE" /></el-select></el-form-item></td><td><el-form-item label-position="left" label-width="110px" label="业务日期" required><el-date-picker v-model="form.businessDate" type="date" value-format="YYYY-MM-DD" /></el-form-item></td></tr>
<tr><td :colspan="form.direction === 'PAYABLE' ? 1 : 2"><el-form-item label-position="left" label-width="110px" label="金额(CNY)" required><el-input-number v-model="form.amount" :min="0.01" :precision="2" :step="10" placeholder="请输入费用金额" /></el-form-item></td><td v-if="form.direction === 'PAYABLE'"><el-form-item label-position="left" label-width="110px" label="供应商" required><el-select v-model="form.supplierId" filterable placeholder="请选择有效供应商"><el-option v-for="supplier in suppliers" :key="supplier.id" :label="supplier.supplierName" :value="supplier.id" /></el-select></el-form-item></td></tr>
<tr v-if="form.direction === 'PAYABLE'"><td :colspan="form.settlementMode === 'DIRECT_PAID' ? 1 : 2"><el-form-item label-position="left" label-width="110px" label="结算方式" required><el-select v-model="form.settlementMode"><el-option label="账期结算" value="ON_ACCOUNT" /><el-option label="直接已付" value="DIRECT_PAID" /></el-select></el-form-item></td><td v-if="form.settlementMode === 'DIRECT_PAID'"><el-form-item label-position="left" label-width="110px" label="付款时间" required><el-date-picker v-model="form.paidAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" /></el-form-item></td></tr>
<tr v-if="form.direction === 'PAYABLE' && form.settlementMode === 'DIRECT_PAID'"><td><el-form-item label-position="left" label-width="110px" label="付款方式" required><el-select v-model="form.paymentMethod"><el-option label="线上支付" value="ONLINE" /><el-option label="银行转账" value="BANK_TRANSFER" /><el-option label="现金" value="CASH" /><el-option label="其他" value="OTHER" /></el-select></el-form-item></td><td><el-form-item label-position="left" label-width="110px" label="付款流水号"><el-input v-model="form.paymentReferenceNo" maxlength="128" /></el-form-item></td></tr>
<tr v-if="form.direction === 'PAYABLE' && form.settlementMode === 'DIRECT_PAID'"><td :colspan="2"><el-form-item label-position="left" label-width="110px" label="付款凭证"><div class="voucher-list"><input ref="voucherInput" type="file" accept="image/*" hidden @change="uploadVoucher" /><el-button :loading="voucherUploading" :disabled="!form.customerId || actionLoading" @click="voucherInput?.click()">{{ form.paymentVoucherFileIds.length ? '重新上传凭证' : '上传付款凭证' }}</el-button><div v-for="(fileId, index) in form.paymentVoucherFileIds" :key="fileId" class="voucher-item"><el-button link type="primary" @click="previewVoucher(form.customerId, fileId)">{{ voucherNames[fileId] || `付款凭证 ${index + 1}` }}</el-button><el-button link type="danger" :disabled="voucherUploading || actionLoading" @click="form.paymentVoucherFileIds = form.paymentVoucherFileIds.filter((id) => id !== fileId)">移除</el-button></div></div></el-form-item></td></tr>
</tbody></table>
</tbody></table></div>
</el-form>
</section>
</AppDialog>
<AppDialog class="admin-density-dialog last-leg-voucher-dialog" v-model="previewOpen" :title="containerDialogTitle('付款凭证', props)" :fullscreenable="Boolean(previewUrl) && previewIsImage" width="min(900px, calc(100vw - 28px))" :show-confirm="false" cancel-text="关闭" append-to-body>
<AppDialog class="admin-density-dialog last-leg-voucher-dialog admin-workbench is-dialog" v-model="previewOpen" :title="containerDialogTitle('付款凭证', props)" :fullscreenable="Boolean(previewUrl) && previewIsImage" width="min(900px, calc(100vw - 28px))" :show-confirm="false" cancel-text="关闭" append-to-body>
<p v-if="previewLoading">正在读取付款凭证…</p>
<div v-else-if="previewError"><el-alert type="error" :closable="false" :title="previewError.message" /><ApiErrorMeta :details="previewError" /></div>
<div v-else-if="previewUrl" class="density-dialog-section voucher-preview" data-tone="source"><p class="density-dialog-note">{{ previewName }}</p><img v-if="previewIsImage" :src="previewUrl" :alt="previewName" /><p v-else>此文件暂不支持预览,请下载后查看。</p><a :href="previewUrl" :download="previewName">下载付款凭证</a></div>