Files
BMS/bms-front/src/views/price/billing/payBill/index.vue
T
2026-11-13 18:26:21 +08:00

612 lines
29 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="app-container">
<el-form :inline="true" :model="query" class="mb8">
<el-form-item label="账单号">
<el-input v-model="query.billNo" clearable placeholder="账单号" style="width: 180px" />
</el-form-item>
<el-form-item label="供应商">
<el-input v-model="query.supplierName" clearable placeholder="供应商" style="width: 180px" />
</el-form-item>
<el-form-item label="状态">
<el-select v-model="query.status" clearable placeholder="全部" style="width: 140px">
<el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="loadList">查询</el-button>
<el-button type="primary" plain icon="Plus" @click="openCreate" v-hasPermi="['price:payBill:add']">生成账单</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="rows" border>
<el-table-column prop="billNo" label="账单号" min-width="170" />
<el-table-column prop="supplierName" label="供应商" min-width="140" show-overflow-tooltip />
<el-table-column prop="currency" label="币种" width="80" align="center" />
<el-table-column prop="orderCount" label="订单数" width="80" align="center" />
<el-table-column prop="totalAmount" label="我方金额" width="110" align="right" />
<el-table-column prop="paidAmount" label="已核销" width="100" align="right" />
<el-table-column prop="dueDate" label="到期日" width="120" />
<el-table-column label="来源" width="90" align="center">
<template #default="{ row }">{{ sourceText(row.sourceType) }}</template>
</el-table-column>
<el-table-column label="状态" width="90" align="center">
<template #default="{ row }">{{ statusText(row.status) }}</template>
</el-table-column>
<el-table-column prop="createTime" label="生成时间" width="170" />
<el-table-column label="操作" width="280" align="center" fixed="right">
<template #default="{ row }">
<el-button link type="primary" @click="openDetail(row)">查看</el-button>
<el-button v-if="row.status === 'DRAFT'" link type="primary" @click="submitRow(row)" v-hasPermi="['price:payBill:submit', 'price:payBill:confirm']">提交审核</el-button>
<el-button v-if="row.status === 'PENDING'" link type="primary" @click="approveRow(row)" v-hasPermi="['price:payBill:approve', 'price:payBill:confirm']">通过</el-button>
<el-button v-if="row.status === 'PENDING'" link type="warning" @click="openReject(row)" v-hasPermi="['price:payBill:approve', 'price:payBill:confirm']">驳回</el-button>
<el-button v-if="canRed(row)" link type="warning" @click="openRed(row)" v-hasPermi="['price:payBill:approve', 'price:payBill:confirm']">红字</el-button>
<el-button v-if="row.status === 'DRAFT' || row.status === 'PENDING'" link type="danger" @click="openVoid(row)" v-hasPermi="['price:payBill:void']">作废</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="query.pageNum" v-model:limit="query.pageSize" @pagination="loadList" />
<el-dialog v-model="createVisible" title="生成应付账单" width="1180px" append-to-body>
<el-form label-width="90px">
<el-form-item label="选出方式">
<el-radio-group v-model="command.sourceType">
<el-radio value="ORDER">订单号</el-radio>
<el-radio value="TIME">计费日</el-radio>
<el-radio value="LADING">提单</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="command.sourceType === 'ORDER'" label="订单号">
<el-input v-model="command.orderText" type="textarea" :rows="4" placeholder="可用逗号、空格或换行分隔" />
</el-form-item>
<el-form-item v-if="command.sourceType === 'TIME'" label="计费日" class="pay-bill-date">
<el-date-picker v-model="dateRange" type="daterange" value-format="YYYY-MM-DD" start-placeholder="开始" end-placeholder="结束" />
</el-form-item>
<el-form-item v-if="command.sourceType === 'LADING'" label="提单号">
<el-input v-model="command.ladingText" type="textarea" :rows="4" placeholder="多张提单可用逗号、空格或换行分隔" />
</el-form-item>
<el-form-item label="供应商" required>
<el-select v-model="command.supplierId" filterable placeholder="选择供应商" style="width: 280px">
<el-option v-for="item in suppliers" :key="item.supplierId" :label="item.supplierName" :value="item.supplierId" />
</el-select>
</el-form-item>
<el-form-item label="到期日">
<el-date-picker v-model="command.dueDate" type="date" value-format="YYYY-MM-DD" placeholder="不填则按供应商账期" style="width: 220px" />
</el-form-item>
</el-form>
<div class="mb8">
<el-button @click="runPreview">查询订单</el-button>
<span v-if="previewRows.length" class="preview-msg">查询到 {{ previewRows.length }} 票,件数 {{ piecesTotal }},可生成 {{ preview.orders.length }} 票</span>
<span v-if="preview.message" class="preview-msg">{{ preview.message }}</span>
</div>
<el-table :data="previewRows" border size="small" max-height="360" empty-text="先查询订单">
<el-table-column prop="orderNo" label="订单号" min-width="140" show-overflow-tooltip />
<el-table-column prop="trackingNo" label="运单号" min-width="130" show-overflow-tooltip />
<el-table-column prop="ladingNo" label="提单号" min-width="120" show-overflow-tooltip />
<el-table-column prop="supplierName" label="供应商" min-width="120" show-overflow-tooltip />
<el-table-column label="目的地" min-width="140" show-overflow-tooltip>
<template #default="{ row }">{{ destText(row) }}</template>
</el-table-column>
<el-table-column prop="pieces" label="件数" width="70" align="center" />
<el-table-column prop="chargeWeight" label="计费重" width="90" align="right" />
<el-table-column prop="channelName" label="渠道" min-width="120" show-overflow-tooltip />
<el-table-column prop="productName" label="产品" min-width="120" show-overflow-tooltip />
<el-table-column prop="feeText" label="费用" min-width="180" show-overflow-tooltip />
<el-table-column prop="currency" label="币种" width="70" align="center" />
<el-table-column prop="payTotal" label="应付总额" width="100" align="right" />
<el-table-column prop="bizDate" label="计费日" width="160" />
<el-table-column label="状态" width="170" show-overflow-tooltip>
<template #default="{ row }">{{ previewStatus(row) }}</template>
</el-table-column>
</el-table>
<template #footer>
<el-button @click="createVisible = false">取消</el-button>
<el-button type="primary" :loading="saving" @click="runGenerate">生成</el-button>
</template>
</el-dialog>
<el-drawer v-model="detailVisible" :title="detailTitle" size="78%">
<template v-if="detail">
<el-descriptions :column="3" border size="small" class="mb8">
<el-descriptions-item label="供应商">{{ detail.supplierName }}</el-descriptions-item>
<el-descriptions-item label="币种">{{ detail.currency }}</el-descriptions-item>
<el-descriptions-item label="状态">{{ statusText(detail.status) }}</el-descriptions-item>
<el-descriptions-item label="我方金额">{{ detail.totalAmount }}</el-descriptions-item>
<el-descriptions-item label="对方金额">{{ detail.supplierAmount }}</el-descriptions-item>
<el-descriptions-item label="已核销">{{ detail.paidAmount || 0 }}</el-descriptions-item>
<el-descriptions-item label="不含税">{{ detail.amountNet || 0 }}</el-descriptions-item>
<el-descriptions-item label="税额">{{ detail.taxAmount || 0 }}</el-descriptions-item>
<el-descriptions-item label="汇率">{{ detail.exchangeRate || 1 }}</el-descriptions-item>
<el-descriptions-item label="本位币">{{ detail.baseAmount || 0 }}</el-descriptions-item>
<el-descriptions-item label="到期日">{{ detail.dueDate || '-' }}</el-descriptions-item>
<el-descriptions-item label="订单数">{{ detail.orderCount }}</el-descriptions-item>
<el-descriptions-item label="单据">{{ detail.billKind === 'RED' ? '红字' : '蓝字' }}</el-descriptions-item>
<el-descriptions-item label="作废原因">{{ detail.voidReason || '-' }}</el-descriptions-item>
</el-descriptions>
<el-tabs>
<el-tab-pane label="费用">
<div class="mb8">
<el-button v-if="detail.status === 'DRAFT'" type="primary" @click="saveDiff" v-hasPermi="['price:payBill:add', 'price:payBill:submit']">保存对方金额</el-button>
<el-button v-if="detail.status === 'DRAFT'" @click="openFinance" v-hasPermi="['price:payBill:add', 'price:payBill:submit']">价税汇率</el-button>
<el-button @click="downloadStatement" v-hasPermi="['price:payBill:query']">导出对账单</el-button>
<el-upload v-if="detail.status === 'DRAFT'" class="inline-upload" :show-file-list="false" accept=".xlsx" :http-request="importSupplier" v-hasPermi="['price:payBill:add', 'price:payBill:submit']">
<el-button>导入对方金额</el-button>
</el-upload>
</div>
<el-table :data="detail.lines || []" border size="small" max-height="360">
<el-table-column prop="orderNo" label="订单号" min-width="130" />
<el-table-column prop="ladingNo" label="提单号" min-width="110" />
<el-table-column prop="feeName" label="费用" min-width="120" />
<el-table-column prop="amount" label="我方金额" width="100" align="right" />
<el-table-column label="对方金额" width="130">
<template #default="{ row }">
<el-input-number v-if="detail.status === 'DRAFT'" v-model="row.supplierAmount" :precision="4" :controls="false" style="width: 110px" />
<span v-else>{{ row.supplierAmount ?? '-' }}</span>
</template>
</el-table-column>
<el-table-column label="差异" width="90" align="center">
<template #default="{ row }">{{ diffText(row.diffStatus) }}</template>
</el-table-column>
<el-table-column label="处理" width="180" align="center">
<template #default="{ row }">
<template v-if="detail.status === 'DRAFT' && row.diffStatus === 'OPEN'">
<el-button link type="primary" @click="acceptDiff(row, 'OURS')">接受我方</el-button>
<el-button link type="primary" @click="acceptDiff(row, 'THEIRS')">接受对方</el-button>
</template>
<el-button v-if="detail.status === 'DRAFT'" link type="danger" @click="removeLine(row)">剔除</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="凭证">
<el-form v-if="detail.status !== 'VOID' && detail.status !== 'RED'" :inline="true" class="mb8">
<el-form-item label="类型">
<el-select v-model="fileForm.fileType" style="width: 120px">
<el-option label="发票" value="INVOICE" />
<el-option label="对账单" value="STATEMENT" />
<el-option label="费用通知" value="DEBIT" />
<el-option label="其他" value="OTHER" />
</el-select>
</el-form-item>
<el-form-item label="发票号">
<el-input v-model="fileForm.invoiceNo" style="width: 140px" />
</el-form-item>
<el-form-item label="价税合计">
<el-input-number v-model="fileForm.amount" :precision="2" :controls="false" style="width: 120px" />
</el-form-item>
<el-form-item label="税额">
<el-input-number v-model="fileForm.taxAmount" :precision="2" :controls="false" style="width: 110px" />
</el-form-item>
<el-form-item label="销方">
<el-input v-model="fileForm.sellerName" style="width: 140px" />
</el-form-item>
<el-form-item>
<el-upload :action="uploadAction" :headers="uploadHeaders" :show-file-list="false" :on-success="onFileUploaded">
<el-button type="primary" v-hasPermi="['price:payVoucher:add', 'price:payBill:add']">上传</el-button>
</el-upload>
</el-form-item>
</el-form>
<el-table :data="detail.files || []" border size="small">
<el-table-column label="类型" width="100">
<template #default="{ row }">{{ fileTypeText(row.fileType) }}</template>
</el-table-column>
<el-table-column prop="invoiceNo" label="发票号" width="140" />
<el-table-column prop="amount" label="价税合计" width="110" align="right" />
<el-table-column prop="taxAmount" label="税额" width="90" align="right" />
<el-table-column prop="matchedAmount" label="已勾稽" width="90" align="right" />
<el-table-column prop="fileName" label="文件" min-width="160" show-overflow-tooltip />
<el-table-column prop="createBy" label="上传人" width="100" />
<el-table-column prop="createTime" label="时间" width="170" />
<el-table-column label="操作" width="120" align="center">
<template #default="{ row }">
<el-link :href="row.fileUrl" target="_blank" type="primary">查看</el-link>
<el-button v-if="detail.status === 'DRAFT' || detail.status === 'PENDING'" link type="danger" @click="removeFile(row)" v-hasPermi="['price:payVoucher:remove', 'price:payBill:void']">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="审核">
<el-table :data="detail.approvals || []" border size="small">
<el-table-column prop="createTime" label="时间" width="170" />
<el-table-column prop="operatorName" label="操作人" width="100" />
<el-table-column label="动作" width="100">
<template #default="{ row }">{{ actionText(row.action) }}</template>
</el-table-column>
<el-table-column prop="opinion" label="意见" min-width="180" />
</el-table>
</el-tab-pane>
<el-tab-pane label="操作记录">
<el-table :data="detail.logs || []" border size="small">
<el-table-column prop="createTime" label="时间" width="170" />
<el-table-column prop="operatorName" label="操作人" width="100" />
<el-table-column label="动作" width="110">
<template #default="{ row }">{{ actionText(row.operationType) }}</template>
</el-table-column>
<el-table-column label="状态" width="160">
<template #default="{ row }">{{ statusText(row.fromStatus) }} → {{ statusText(row.toStatus) }}</template>
</el-table-column>
<el-table-column prop="amountBefore" label="改前" width="90" align="right" />
<el-table-column prop="amountAfter" label="改后" width="90" align="right" />
<el-table-column prop="operationDesc" label="说明" min-width="180" show-overflow-tooltip />
</el-table>
</el-tab-pane>
</el-tabs>
</template>
</el-drawer>
<el-dialog v-model="rejectVisible" title="驳回应付账单" width="460px" append-to-body>
<el-input v-model="rejectOpinion" type="textarea" :rows="3" placeholder="驳回意见" />
<template #footer>
<el-button @click="rejectVisible = false">取消</el-button>
<el-button type="warning" @click="runReject">确认驳回</el-button>
</template>
</el-dialog>
<el-dialog v-model="redVisible" title="应付红字" width="460px" append-to-body>
<el-input v-model="redReason" type="textarea" :rows="3" placeholder="红字原因" />
<template #footer>
<el-button @click="redVisible = false">取消</el-button>
<el-button type="warning" @click="runRed">生成红字</el-button>
</template>
</el-dialog>
<el-dialog v-model="financeVisible" title="价税与汇率" width="460px" append-to-body>
<el-form label-width="90px">
<el-form-item label="税率">
<el-input-number v-model="financeForm.taxRate" :min="0" :max="0.9999" :precision="4" :step="0.01" :controls="false" style="width: 180px" />
</el-form-item>
<el-form-item label="汇率">
<el-input-number v-model="financeForm.exchangeRate" :min="0.000001" :precision="6" :controls="false" style="width: 180px" />
</el-form-item>
<el-form-item label="汇率日期">
<el-date-picker v-model="financeForm.rateDate" type="date" value-format="YYYY-MM-DD" style="width: 180px" />
</el-form-item>
</el-form>
<div class="preview-msg">税率填小数,0.06 表示 6%。金额按价税合计拆成不含税和税额,再按汇率折人民币。</div>
<template #footer>
<el-button @click="financeVisible = false">取消</el-button>
<el-button type="primary" @click="saveFinance">保存</el-button>
</template>
</el-dialog>
<el-dialog v-model="voidVisible" title="作废应付账单" width="460px" append-to-body>
<el-input v-model="voidReason" type="textarea" :rows="3" placeholder="作废原因" />
<template #footer>
<el-button @click="voidVisible = false">取消</el-button>
<el-button type="danger" @click="runVoid">确认作废</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup name="PayBill">
import { getToken } from '@/utils/auth'
import useUserStore from '@/store/modules/user'
import { listSupplier } from '@/api/customersuppliermanagement/supplierinfo/supplier'
import { listPayBill, getPayBill, previewPayBill, generatePayBill, voidPayBill, submitPayBill, approvePayBill, rejectPayBill, savePayBillDiff, acceptPayBillDiff, removePayBillLine, savePayBillFile, deletePayBillFile, redPayBill, savePayFinance, exportPayStatement, importPaySupplier } from '@/api/price/payBill'
const { proxy } = getCurrentInstance()
const userStore = useUserStore()
const loading = ref(false)
const rows = ref([])
const total = ref(0)
const query = reactive({ pageNum: 1, pageSize: 10, billNo: '', supplierName: '', status: '' })
const statusOptions = [
{ label: '草稿', value: 'DRAFT' },
{ label: '待审核', value: 'PENDING' },
{ label: '已确认', value: 'CONFIRMED' },
{ label: '部分付款', value: 'PARTIAL' },
{ label: '已付清', value: 'PAID' },
{ label: '已红冲', value: 'RED' },
{ label: '已作废', value: 'VOID' }
]
const uploadAction = import.meta.env.VITE_APP_BASE_API + '/common/upload'
const uploadHeaders = { Authorization: 'Bearer ' + getToken() }
const fileForm = reactive({ fileType: 'INVOICE', invoiceNo: '', amount: null, taxAmount: 0, sellerName: '' })
const rejectVisible = ref(false)
const rejectOpinion = ref('')
const rejectId = ref(null)
const redVisible = ref(false)
const redReason = ref('')
const redId = ref(null)
const detailTitle = computed(() => detail.value?.billNo || '应付账单')
const createVisible = ref(false)
const saving = ref(false)
const suppliers = ref([])
const dateRange = ref([])
const command = reactive({ sourceType: 'ORDER', orderText: '', ladingText: '', supplierId: null, beginDate: '', endDate: '', dueDate: '' })
const financeVisible = ref(false)
const financeForm = reactive({ taxRate: 0, exchangeRate: 1, rateDate: '' })
const preview = reactive({ orders: [], occupied: [], missingNos: [], message: '' })
const detailVisible = ref(false)
const detail = ref(null)
const voidVisible = ref(false)
const voidReason = ref('')
const voidId = ref(null)
const previewRows = computed(() => [...(preview.orders || []), ...(preview.occupied || [])])
const piecesTotal = computed(() => previewRows.value.reduce((sum, item) => sum + (Number(item.pieces) || 0), 0))
function destText(row) {
const country = [row.countryName, row.countryCode].filter(Boolean).join(' ')
return [country, row.destPostcode].filter(Boolean).join(' / ') || '-'
}
function statusText(value) {
return statusOptions.find(item => item.value === value)?.label || value || '-'
}
function sourceText(value) {
return { ORDER: '订单号', TIME: '计费日', LADING: '提单' }[value] || value || '-'
}
function diffText(value) {
return { NONE: '-', OPEN: '待处理', ACCEPT_OURS: '接受我方', ACCEPT_THEIRS: '接受对方' }[value] || value || '-'
}
function fileTypeText(value) {
return { INVOICE: '发票', STATEMENT: '对账单', DEBIT: '费用通知', OTHER: '其他' }[value] || value || '-'
}
function actionText(value) {
return {
CREATE: '生成', SUBMIT: '提交审核', APPROVE: '审核通过', REJECT: '驳回', CONFIRM: '确认',
VOID: '作废', REMOVE: '剔除', DIFF: '登记差异', ACCEPT: '处理差异', FILE: '上传凭证',
FILE_DEL: '删除凭证', RED: '红字', PAY: '付款核销', TAX: '价税汇率', EXPORT: '导出对账单', REVERSE: '反核销'
}[value] || value || '-'
}
function previewStatus(row) {
if (row.unbilledCount > 0 && row.occupiedBillNo) return '部分可出 ' + row.occupiedBillNo
if (row.occupiedBillNo) return '已入账 ' + row.occupiedBillNo
return '可生成'
}
function canRed(row) {
return (row.status === 'CONFIRMED' || row.status === 'PARTIAL') && row.billKind !== 'RED' && !(Number(row.paidAmount) > 0)
}
function reloadDetail() {
if (!detail.value?.billId) return
getPayBill(detail.value.billId).then(res => { detail.value = res.data })
}
function loadList() {
loading.value = true
listPayBill(query).then(res => {
rows.value = res.rows || []
total.value = res.total || 0
}).finally(() => {
loading.value = false
})
}
function ensureSuppliers() {
if (!suppliers.value.length) {
listSupplier({ pageNum: 1, pageSize: 500 }).then(res => {
suppliers.value = res.rows || []
})
}
}
function openFinance() {
financeForm.taxRate = Number(detail.value.taxRate || 0)
financeForm.exchangeRate = Number(detail.value.exchangeRate || 1)
financeForm.rateDate = detail.value.rateDate || ''
financeVisible.value = true
}
function saveFinance() {
savePayFinance({ billId: detail.value.billId, taxRate: financeForm.taxRate, exchangeRate: financeForm.exchangeRate, rateDate: financeForm.rateDate }).then(() => {
proxy.$modal.msgSuccess('价税和汇率已保存')
financeVisible.value = false
reloadDetail()
})
}
function downloadStatement() {
exportPayStatement(detail.value.billId).then(data => {
const blob = new Blob([data])
const url = URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = (detail.value.billNo || '对账单') + '.xlsx'
link.click()
URL.revokeObjectURL(url)
})
}
function importSupplier(option) {
importPaySupplier(detail.value.billId, option.file).then(() => {
proxy.$modal.msgSuccess('对方金额已导入')
reloadDetail()
})
}
function openCreate() {
preview.orders = []
preview.occupied = []
preview.missingNos = []
preview.message = ''
createVisible.value = true
ensureSuppliers()
}
function buildCommand() {
const data = { ...command }
if (command.sourceType === 'TIME' && dateRange.value?.length === 2) {
data.beginDate = dateRange.value[0]
data.endDate = dateRange.value[1]
}
return data
}
function runPreview() {
previewPayBill(buildCommand()).then(res => {
const data = res.data || {}
preview.orders = data.orders || []
preview.occupied = data.occupied || []
preview.missingNos = data.missingNos || []
preview.message = data.message || ''
})
}
function runGenerate() {
saving.value = true
generatePayBill(buildCommand()).then(res => {
const desc = (res.data?.logs || []).find(item => item.operationType === 'CREATE')?.operationDesc || ''
if (desc.includes('未并入')) {
proxy.$modal.msgWarning(desc)
} else {
proxy.$modal.msgSuccess('应付账单已生成')
}
createVisible.value = false
loadList()
}).finally(() => {
saving.value = false
})
}
function openDetail(row) {
getPayBill(row.billId).then(res => {
detail.value = res.data
detailVisible.value = true
})
}
function submitRow(row) {
proxy.$modal.confirm('提交这张应付账单审核?有未处理差异时不能提交。').then(() => submitPayBill(row.billId)).then(() => {
proxy.$modal.msgSuccess('已提交审核')
loadList()
}).catch(() => {})
}
function approveRow(row) {
const limit = String(userStore.id) === '1' ? '' : ',审核人不能是提交人'
proxy.$modal.confirm('审核通过?蓝字需要发票价税合计、税额和账单一致' + limit + '。').then(() => approvePayBill(row.billId)).then(() => {
proxy.$modal.msgSuccess('已审核通过')
loadList()
if (detail.value?.billId === row.billId) reloadDetail()
}).catch(() => {})
}
function openReject(row) {
rejectId.value = row.billId
rejectOpinion.value = ''
rejectVisible.value = true
}
function runReject() {
if (!rejectOpinion.value.trim()) {
proxy.$modal.msgWarning('请填写驳回意见')
return
}
rejectPayBill({ billId: rejectId.value, opinion: rejectOpinion.value.trim() }).then(() => {
proxy.$modal.msgSuccess('已驳回')
rejectVisible.value = false
loadList()
})
}
function openRed(row) {
redId.value = row.billId
redReason.value = ''
redVisible.value = true
}
function runRed() {
redPayBill({ billId: redId.value, reason: redReason.value.trim() }).then(() => {
proxy.$modal.msgSuccess('红字草稿已生成,审核通过后原费用才可以再次出账')
redVisible.value = false
loadList()
})
}
function saveDiff() {
savePayBillDiff({ billId: detail.value.billId, lines: detail.value.lines }).then(() => {
proxy.$modal.msgSuccess('对方金额已保存')
reloadDetail()
})
}
function acceptDiff(row, handleType) {
const text = handleType === 'THEIRS' ? '接受对方金额?差额会另写一条对账调整,原来的计算金额不变。' : '接受我方金额?'
proxy.$modal.confirm(text).then(() => acceptPayBillDiff({ billId: detail.value.billId, lineId: row.lineId, handleType })).then(() => {
proxy.$modal.msgSuccess('差异已处理')
reloadDetail()
}).catch(() => {})
}
function removeLine(row) {
proxy.$modal.confirm('从这张草稿剔除这条费用?剔除后它可以进入别的账单。').then(() => removePayBillLine({ billId: detail.value.billId, lineId: row.lineId })).then(() => {
proxy.$modal.msgSuccess('已剔除')
reloadDetail()
loadList()
}).catch(() => {})
}
function onFileUploaded(res) {
if (res.code !== 200) {
proxy.$modal.msgError(res.msg || '上传失败')
return
}
savePayBillFile({
billId: detail.value.billId,
fileType: fileForm.fileType,
invoiceNo: fileForm.invoiceNo,
amount: fileForm.amount,
taxAmount: fileForm.taxAmount,
sellerName: fileForm.sellerName,
fileName: res.originalFilename || res.newFileName,
fileUrl: res.url || res.fileName
}).then(() => {
proxy.$modal.msgSuccess('凭证已上传')
fileForm.fileType = 'INVOICE'
fileForm.invoiceNo = ''
fileForm.amount = null
fileForm.taxAmount = 0
fileForm.sellerName = ''
reloadDetail()
})
}
function removeFile(row) {
proxy.$modal.confirm('删除这张凭证?').then(() => deletePayBillFile(row.fileId)).then(() => {
proxy.$modal.msgSuccess('已删除')
reloadDetail()
}).catch(() => {})
}
function openVoid(row) {
voidId.value = row.billId
voidReason.value = ''
voidVisible.value = true
}
function runVoid() {
if (!voidReason.value.trim()) {
proxy.$modal.msgWarning('请填写作废原因')
return
}
voidPayBill({ billId: voidId.value, voidReason: voidReason.value.trim() }).then(() => {
proxy.$modal.msgSuccess('已作废,历史账单仍可查看')
voidVisible.value = false
loadList()
})
}
loadList()
</script>
<style scoped>
.preview-msg { margin-left: 12px; color: #909399; }
.inline-upload { display: inline-block; margin: 0 8px; vertical-align: middle; }
.mb8 { margin-bottom: 8px; }
.pay-bill-date :deep(.el-date-editor) {
width: 280px !important;
max-width: 280px;
flex: 0 0 280px;
--el-date-editor-width: 280px;
}
</style>