feat: 新增发票冲销明细公共组件与独立页面路由
This commit is contained in:
@@ -0,0 +1,145 @@
|
|||||||
|
<template>
|
||||||
|
<div class="invoice-write-off-table">
|
||||||
|
<el-table v-loading="loading" :data="rows" border>
|
||||||
|
<el-table-column type="index" label="序号" width="64" fixed="left" align="center" />
|
||||||
|
<el-table-column prop="arrivalAddress" label="到货地址" min-width="150" align="center" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">{{ row.manualFlag === 1 ? '—' : displayValue(row.arrivalAddress) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="actualDepartureTime" label="实际发货时间" width="150" align="center">
|
||||||
|
<template #default="{ row }">{{ row.manualFlag === 1 ? '—' : formatDateTime(row.actualDepartureTime) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="completionTime" label="实际完成时间" width="150" align="center">
|
||||||
|
<template #default="{ row }">{{ row.manualFlag === 1 ? '—' : formatDateTime(row.completionTime) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="transportType" label="运输类型" width="100" align="center">
|
||||||
|
<template #default="{ row }">{{ row.manualFlag === 1 ? '—' : displayValue(row.transportType) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="cargoName" label="货物名称" min-width="110" align="center" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">{{ row.manualFlag === 1 ? '—' : displayValue(row.cargoName) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="cargoType" label="货物类型" min-width="110" align="center" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">{{ row.manualFlag === 1 ? '—' : displayValue(row.cargoType) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="transportQuantity" label="运输总量" width="110" align="center">
|
||||||
|
<template #default="{ row }">{{ row.manualFlag === 1 ? '—' : displayValue(row.transportQuantity) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="mileage" label="里程 (KM)" width="100" align="center">
|
||||||
|
<template #default="{ row }">{{ row.manualFlag === 1 ? '—' : displayValue(row.mileage) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="batchNo" label="批次号" width="100" align="center" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">{{ row.manualFlag === 1 ? '—' : displayValue(row.batchNo) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="invoiceNo" label="发票号" min-width="160" align="center" show-overflow-tooltip />
|
||||||
|
<!-- 按费用项目动态分组列头,每组三列:结算金额/未开票费用/本次开票金额 -->
|
||||||
|
<el-table-column v-for="group in feeItemGroups" :key="group.name" :label="group.name" align="center">
|
||||||
|
<el-table-column :label="'结算金额'" width="110" align="center">
|
||||||
|
<template #default="{ row }">{{ formatMoney(row.settlementAmounts[group.name]) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="'未开票费用'" width="110" align="center">
|
||||||
|
<template #default="{ row }">{{ formatMoney(row.beforeRemainAmounts[group.name]) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="'本次开票金额'" width="120" align="center">
|
||||||
|
<template #default="{ row }">{{ formatMoney(row.writeOffAmounts[group.name]) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div v-if="!loading && !rows.length" class="invoice-write-off-table__empty">暂无冲销明细</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import request from '@/axios';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发票冲销明细公共表格(开票申请/收票登记/付款申请通用)
|
||||||
|
* 数据源:/blade-transport/invoice-write-off/list?bizType=&bizId=
|
||||||
|
* 行按运单完成时间升序(先完成的运单先冲销),手动添加费用无运输信息显示"—"
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'InvoiceWriteOffTable',
|
||||||
|
props: {
|
||||||
|
// invoice_apply-开票申请 receipt-收票登记 payment_receipt-付款申请生成的收票单
|
||||||
|
bizType: { type: String, required: true },
|
||||||
|
bizId: { type: [String, Number], default: null },
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
rows: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
feeItemGroups() {
|
||||||
|
const names = [];
|
||||||
|
this.rows.forEach(row => {
|
||||||
|
if (row.feeItemName && !names.includes(row.feeItemName)) names.push(row.feeItemName);
|
||||||
|
});
|
||||||
|
return names.map(name => ({ name }));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
bizId: {
|
||||||
|
immediate: true,
|
||||||
|
handler(value) {
|
||||||
|
if (value) this.load();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
load() {
|
||||||
|
this.loading = true;
|
||||||
|
request({
|
||||||
|
url: '/blade-transport/invoice-write-off/list',
|
||||||
|
method: 'get',
|
||||||
|
params: { bizType: this.bizType, bizId: this.bizId },
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
const list = res.data.data || [];
|
||||||
|
// 同一运单同一费用项目可能被多张发票分段冲抵(跨发票拆分),按运单+费用项目归并展示
|
||||||
|
const merged = new Map();
|
||||||
|
list.forEach(row => {
|
||||||
|
const key = `${row.waybillId || row.summaryFeeId || ''}|${row.feeItemName}`;
|
||||||
|
if (!merged.has(key)) {
|
||||||
|
merged.set(key, {
|
||||||
|
...row,
|
||||||
|
settlementAmounts: { [row.feeItemName]: row.settlementAmount },
|
||||||
|
beforeRemainAmounts: { [row.feeItemName]: row.beforeRemainAmount },
|
||||||
|
writeOffAmounts: { [row.feeItemName]: row.writeOffAmount },
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const target = merged.get(key);
|
||||||
|
target.writeOffAmounts[row.feeItemName] = Number(target.writeOffAmounts[row.feeItemName] || 0) + Number(row.writeOffAmount || 0);
|
||||||
|
// 未开票费用取首段冲抵前余额,发票号追加展示
|
||||||
|
if (!String(target.invoiceNo).includes(row.invoiceNo)) {
|
||||||
|
target.invoiceNo = `${target.invoiceNo},${row.invoiceNo}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.rows = [...merged.values()];
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
displayValue(value) {
|
||||||
|
return value === null || value === undefined || value === '' ? '-' : value;
|
||||||
|
},
|
||||||
|
formatDateTime(value) {
|
||||||
|
if (!value) return '-';
|
||||||
|
return this.$dayjs(value).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
},
|
||||||
|
formatMoney(value) {
|
||||||
|
return Number(value || 0).toFixed(2);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.invoice-write-off-table__empty {
|
||||||
|
padding: 24px 0;
|
||||||
|
text-align: center;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -77,6 +77,19 @@ export default [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// 发票冲销明细独立页(不挂菜单,供开票申请/收票登记/付款申请页面跳转引用)
|
||||||
|
path: '/payment/invoice-write-off',
|
||||||
|
component: Layout,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
name: '发票冲销明细',
|
||||||
|
meta: { keepAlive: false, activeMenu: '/payment/invoice-application' },
|
||||||
|
component: loadView(() => import('@/views/payment/invoice-write-off.vue')),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/payment/payment-application/form',
|
path: '/payment/payment-application/form',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<basic-container>
|
||||||
|
<section-card title="发票冲销明细">
|
||||||
|
<invoice-write-off-table :biz-type="bizType" :biz-id="bizId" />
|
||||||
|
</section-card>
|
||||||
|
</basic-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import InvoiceWriteOffTable from '@/components/invoice-write-off-table/main.vue';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发票冲销明细独立页(不挂菜单,供其他页面 $router 跳转引用)
|
||||||
|
* 用法:$router.push({ path: '/payment/invoice-write-off', query: { bizType: 'invoice_apply', bizId: id } })
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'InvoiceWriteOff',
|
||||||
|
components: { InvoiceWriteOffTable },
|
||||||
|
computed: {
|
||||||
|
bizType() {
|
||||||
|
return String(this.$route.query.bizType || 'invoice_apply');
|
||||||
|
},
|
||||||
|
bizId() {
|
||||||
|
return this.$route.query.bizId || null;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user