feat: 开票付款申请发票冲销改底部弹窗展示并选结算单带出项目利润率
This commit is contained in:
@@ -0,0 +1,123 @@
|
|||||||
|
<template>
|
||||||
|
<teleport to="body">
|
||||||
|
<transition name="el-fade-in-linear">
|
||||||
|
<section v-if="modelValue" class="bottom-detail-panel" aria-label="详情面板">
|
||||||
|
<header class="bottom-detail-panel__header">
|
||||||
|
<h3>{{ title }}</h3>
|
||||||
|
<el-tooltip content="关闭" placement="top">
|
||||||
|
<el-button :icon="Close" text aria-label="关闭详情面板" @click="close" />
|
||||||
|
</el-tooltip>
|
||||||
|
</header>
|
||||||
|
<div class="bottom-detail-panel__body">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
<footer class="bottom-detail-panel__footer">
|
||||||
|
<el-button @click="close">关闭</el-button>
|
||||||
|
</footer>
|
||||||
|
</section>
|
||||||
|
</transition>
|
||||||
|
</teleport>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Close } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 底部弹出详情面板(表单页通用)
|
||||||
|
* 固定于视口底部并避让侧边栏,交互对齐应收/应付明细页点「单据号」弹出的单据详情面板
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'BottomDetailPanel',
|
||||||
|
props: {
|
||||||
|
modelValue: { type: Boolean, default: false },
|
||||||
|
title: { type: String, default: '详情' },
|
||||||
|
},
|
||||||
|
emits: ['update:modelValue'],
|
||||||
|
data() {
|
||||||
|
return { Close };
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// 表单页多被 keep-alive 缓存,切换菜单时组件不销毁,需监听路由收起 teleport 到 body 的面板
|
||||||
|
$route() {
|
||||||
|
this.close();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close() {
|
||||||
|
this.$emit('update:modelValue', false);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.bottom-detail-panel {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 100;
|
||||||
|
bottom: 0;
|
||||||
|
left: $sidebar_width;
|
||||||
|
width: calc(100% - #{$sidebar_width});
|
||||||
|
max-height: min(60vh, 560px);
|
||||||
|
border-top: 1px solid #eff1f7;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.avue--collapse) .bottom-detail-panel {
|
||||||
|
left: $sidebar_collapse;
|
||||||
|
width: calc(100% - #{$sidebar_collapse});
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.avue-layout--horizontal) .bottom-detail-panel {
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-detail-panel__header {
|
||||||
|
display: flex;
|
||||||
|
min-height: 48px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 20px;
|
||||||
|
border-bottom: 1px solid #eff1f7;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 12px;
|
||||||
|
border-left: 4px solid #409eff;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-detail-panel__body {
|
||||||
|
max-height: calc(min(60vh, 560px) - 106px);
|
||||||
|
padding: 16px 20px;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
:deep(.el-table) {
|
||||||
|
--el-table-border-color: #eff1f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-table__row:nth-child(even) td.el-table__cell) {
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-detail-panel__footer {
|
||||||
|
display: flex;
|
||||||
|
min-height: 57px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 0 20px;
|
||||||
|
border-top: 1px solid #eff1f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 992px) {
|
||||||
|
.bottom-detail-panel {
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -43,7 +43,6 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<div v-if="!loading && !rows.length" class="invoice-write-off-table__empty">暂无冲销明细</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -134,12 +133,3 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.invoice-write-off-table__empty {
|
|
||||||
padding: 24px 0;
|
|
||||||
text-align: center;
|
|
||||||
color: #909399;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@
|
|||||||
<el-input
|
<el-input
|
||||||
:model-value="profitRatePercent"
|
:model-value="profitRatePercent"
|
||||||
:disabled="readonly"
|
:disabled="readonly"
|
||||||
placeholder="选结算单后自动带出,可修改"
|
placeholder="选结算单带出,可修改"
|
||||||
@input="handleProfitRateInput"
|
@input="handleProfitRateInput"
|
||||||
>
|
>
|
||||||
<template #append>%</template>
|
<template #append>%</template>
|
||||||
@@ -363,6 +363,11 @@
|
|||||||
</section-card>
|
</section-card>
|
||||||
|
|
||||||
<section-card title="开票明细">
|
<section-card title="开票明细">
|
||||||
|
<template #extra>
|
||||||
|
<el-button v-if="recordId" type="primary" @click="writeOffPanelVisible = true"
|
||||||
|
>发票冲销</el-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
<el-table
|
<el-table
|
||||||
ref="detailTable"
|
ref="detailTable"
|
||||||
:data="detailRows"
|
:data="detailRows"
|
||||||
@@ -412,9 +417,9 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</section-card>
|
</section-card>
|
||||||
|
|
||||||
<section-card v-if="recordId" title="发票冲销明细">
|
<bottom-detail-panel v-model="writeOffPanelVisible" title="发票冲销明细">
|
||||||
<invoice-write-off-table biz-type="invoice_apply" :biz-id="recordId" />
|
<invoice-write-off-table biz-type="invoice_apply" :biz-id="recordId" />
|
||||||
</section-card>
|
</bottom-detail-panel>
|
||||||
|
|
||||||
<section-card title="附件信息">
|
<section-card title="附件信息">
|
||||||
<vehicle-attachment-table v-model="form.attachments" :readonly="readonly" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="readonly" />
|
||||||
@@ -519,10 +524,12 @@ import * as api from '@/api/payment/invoiceApplication';
|
|||||||
import { getAll as getInvoiceItems } from '@/api/base/invoice-item';
|
import { getAll as getInvoiceItems } from '@/api/base/invoice-item';
|
||||||
import { getList as getWaybillList } from '@/api/business/waybill-manage';
|
import { getList as getWaybillList } from '@/api/business/waybill-manage';
|
||||||
import { getList as getReceivablePayableDetailList } from '@/api/settlement/receivable-payable-detail';
|
import { getList as getReceivablePayableDetailList } from '@/api/settlement/receivable-payable-detail';
|
||||||
|
import { getDetail as getProjectApplyDetail } from '@/api/business/project-apply';
|
||||||
import { getDictionary } from '@/api/system/dictbiz';
|
import { getDictionary } from '@/api/system/dictbiz';
|
||||||
import { invoiceApplicationDetailColumns } from '@/option/payment/invoiceApplication';
|
import { invoiceApplicationDetailColumns } from '@/option/payment/invoiceApplication';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import InvoiceWriteOffTable from '@/components/invoice-write-off-table/main.vue';
|
import InvoiceWriteOffTable from '@/components/invoice-write-off-table/main.vue';
|
||||||
|
import BottomDetailPanel from '@/components/bottom-detail-panel/main.vue';
|
||||||
import { getMkPublicDetail } from '@/api/mk-process';
|
import { getMkPublicDetail } from '@/api/mk-process';
|
||||||
import { loadMkEnabled, submitMkApprovalFlow } from '@/utils/mk-approval';
|
import { loadMkEnabled, submitMkApprovalFlow } from '@/utils/mk-approval';
|
||||||
|
|
||||||
@@ -579,12 +586,14 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
VehicleAttachmentTable,
|
VehicleAttachmentTable,
|
||||||
InvoiceWriteOffTable,
|
InvoiceWriteOffTable,
|
||||||
|
BottomDetailPanel,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: emptyForm(),
|
form: emptyForm(),
|
||||||
detailRows: [],
|
detailRows: [],
|
||||||
selectedDetailIds: [],
|
selectedDetailIds: [],
|
||||||
|
writeOffPanelVisible: false,
|
||||||
receiverInvoiceOptions: [],
|
receiverInvoiceOptions: [],
|
||||||
contactOptions: [],
|
contactOptions: [],
|
||||||
departmentEmailOptions: [],
|
departmentEmailOptions: [],
|
||||||
@@ -978,11 +987,27 @@ export default {
|
|||||||
allocatedInvoiceAmount: 0,
|
allocatedInvoiceAmount: 0,
|
||||||
}));
|
}));
|
||||||
this.form.projectName = first.projectName;
|
this.form.projectName = first.projectName;
|
||||||
|
this.form.projectId = first.projectId;
|
||||||
this.form.deptName = first.deptName;
|
this.form.deptName = first.deptName;
|
||||||
this.form.issuerName = first.issuerName;
|
this.form.issuerName = first.issuerName;
|
||||||
this.form.undertakingDeptName = first.deptName;
|
this.form.undertakingDeptName = first.deptName;
|
||||||
this.settlementDialog.visible = false;
|
this.settlementDialog.visible = false;
|
||||||
await Promise.all([this.loadSettlementDetails(), this.loadReceiverInformation()]);
|
await Promise.all([
|
||||||
|
this.loadSettlementDetails(),
|
||||||
|
this.loadReceiverInformation(),
|
||||||
|
this.loadProjectProfitRate(),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
// 项目利润率:选结算单后带出项目立项利润率(百分数转小数存 form),已手填时不覆盖
|
||||||
|
async loadProjectProfitRate() {
|
||||||
|
if (!this.form.projectId || Number(this.form.profitRate) > 0) return;
|
||||||
|
try {
|
||||||
|
const data = this.unwrapData(await getProjectApplyDetail(this.form.projectId));
|
||||||
|
const rate = Number(data?.profitRate);
|
||||||
|
if (Number.isFinite(rate) && rate > 0) this.form.profitRate = rate / 100;
|
||||||
|
} catch {
|
||||||
|
// 带出失败不阻断选单,保存时后端仍会兜底取项目立项利润率
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async loadSettlementDetails(resetSelection = true) {
|
async loadSettlementDetails(resetSelection = true) {
|
||||||
this.detailRows =
|
this.detailRows =
|
||||||
|
|||||||
@@ -290,6 +290,11 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</section-card>
|
</section-card>
|
||||||
<section-card v-if="showInvoiceSection" title="发票信息">
|
<section-card v-if="showInvoiceSection" title="发票信息">
|
||||||
|
<template #extra>
|
||||||
|
<el-button v-if="recordId" type="primary" @click="writeOffPanelVisible = true"
|
||||||
|
>发票冲销</el-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
<el-table :data="form.invoices" border>
|
<el-table :data="form.invoices" border>
|
||||||
<el-table-column type="index" label="序号" width="70" />
|
<el-table-column type="index" label="序号" width="70" />
|
||||||
<el-table-column prop="settlementNo" label="结算单号" min-width="120">
|
<el-table-column prop="settlementNo" label="结算单号" min-width="120">
|
||||||
@@ -350,9 +355,9 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</section-card>
|
</section-card>
|
||||||
<section-card v-if="recordId" title="发票冲销明细">
|
<bottom-detail-panel v-model="writeOffPanelVisible" title="发票冲销明细">
|
||||||
<invoice-write-off-table biz-type="payment_receipt" :biz-id="recordId" />
|
<invoice-write-off-table biz-type="payment_receipt" :biz-id="recordId" />
|
||||||
</section-card>
|
</bottom-detail-panel>
|
||||||
<section-card title="付款记录">
|
<section-card title="付款记录">
|
||||||
<el-table :data="paymentRecords" border
|
<el-table :data="paymentRecords" border
|
||||||
><el-table-column type="index" label="序号" width="70" /><el-table-column
|
><el-table-column type="index" label="序号" width="70" /><el-table-column
|
||||||
@@ -764,6 +769,7 @@ import {
|
|||||||
} from '@/utils/kingdee-attachment';
|
} from '@/utils/kingdee-attachment';
|
||||||
import PdfPreview from '@/components/pdf-preview/main.vue';
|
import PdfPreview from '@/components/pdf-preview/main.vue';
|
||||||
import InvoiceWriteOffTable from '@/components/invoice-write-off-table/main.vue';
|
import InvoiceWriteOffTable from '@/components/invoice-write-off-table/main.vue';
|
||||||
|
import BottomDetailPanel from '@/components/bottom-detail-panel/main.vue';
|
||||||
|
|
||||||
const attachmentViewerPlugins = [
|
const attachmentViewerPlugins = [
|
||||||
imagePlugin(),
|
imagePlugin(),
|
||||||
@@ -841,12 +847,14 @@ export default {
|
|||||||
OpenFileViewer,
|
OpenFileViewer,
|
||||||
PdfPreview,
|
PdfPreview,
|
||||||
InvoiceWriteOffTable,
|
InvoiceWriteOffTable,
|
||||||
|
BottomDetailPanel,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: emptyForm(),
|
form: emptyForm(),
|
||||||
amountSyncing: false,
|
amountSyncing: false,
|
||||||
transferPayload: null,
|
transferPayload: null,
|
||||||
|
writeOffPanelVisible: false,
|
||||||
// 金蝶侧发票附件查看/下载进行中(行组级 loading 守卫)
|
// 金蝶侧发票附件查看/下载进行中(行组级 loading 守卫)
|
||||||
kingdeeAttachmentBusy: false,
|
kingdeeAttachmentBusy: false,
|
||||||
referenceRows: [],
|
referenceRows: [],
|
||||||
|
|||||||
Reference in New Issue
Block a user