|
|
|
|
@ -249,20 +249,61 @@
|
|
|
|
|
<!-- 回款信息 Tab -->
|
|
|
|
|
<el-tab-pane label="回款信息" name="payment">
|
|
|
|
|
<div v-loading="loadingPayment" class="tab-content">
|
|
|
|
|
<el-table :data="planStageList" border stripe size="default" class="data-table">
|
|
|
|
|
<div class="section-header">
|
|
|
|
|
<div class="header-left">
|
|
|
|
|
<i class="el-icon-coin section-icon"></i>
|
|
|
|
|
<span class="section-title">回款信息</span>
|
|
|
|
|
<el-tag v-if="planStageList.length > 0" type="info" size="small" class="count-tag"> {{ planStageList.length }} 条 </el-tag>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="header-actions">
|
|
|
|
|
<el-button size="default" icon="Refresh" @click="loadPlanStageList">刷新</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<el-table
|
|
|
|
|
:data="planStageList"
|
|
|
|
|
border
|
|
|
|
|
stripe
|
|
|
|
|
size="default"
|
|
|
|
|
class="data-table"
|
|
|
|
|
:header-cell-style="{ textAlign: 'center' }"
|
|
|
|
|
:cell-style="{ textAlign: 'center' }"
|
|
|
|
|
>
|
|
|
|
|
<el-table-column label="序号" type="index" width="60" align="center" />
|
|
|
|
|
<el-table-column label="回款阶段" width="220" align="center">
|
|
|
|
|
<el-table-column label="回款阶段" min-width="160" align="center" show-overflow-tooltip>
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
{{ scope.row.paymentStageName || getPaymentStageName(scope.row.paymentStageId) }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="预计回款比例(%)" width="160" align="center" prop="repaymentRate" />
|
|
|
|
|
<el-table-column label="预计回款时间" width="150" align="center">
|
|
|
|
|
<el-table-column label="合同阶段比例(%)" width="140" align="center">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<span>{{ parseTime(scope.row.repaymentTime, '{y}-{m}-{d}') || '-' }}</span>
|
|
|
|
|
{{ formatStagePercent(scope.row.repaymentRate) }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="合同阶段金额(元)" width="150" align="center">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
{{ scope.row.repaymentAmount != null ? formatNumber(scope.row.repaymentAmount) : '-' }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="实际回款金额(元)" width="150" align="center">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
{{ scope.row.actualRepaymentAmount != null ? formatNumber(scope.row.actualRepaymentAmount) : '-' }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="实际回款比例(%)" width="140" align="center">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
{{ displayPlanStageActualRepaymentRate(scope.row) }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="确认状态" width="120" align="center">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<dict-tag :options="collection_confirm_status" :value="scope.row.collectionConfirmStatus || '0'" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="确认日期" width="120" align="center">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<span>{{ parseTime(scope.row.collectionConfirmTime, '{y}-{m}-{d}') || '-' }}</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="备注" min-width="200" prop="remark" show-overflow-tooltip />
|
|
|
|
|
</el-table>
|
|
|
|
|
<el-empty v-if="!loadingPayment && planStageList.length === 0" description="暂无回款信息" class="empty-state" />
|
|
|
|
|
</div>
|
|
|
|
|
@ -380,7 +421,8 @@ const {
|
|
|
|
|
wf_business_status,
|
|
|
|
|
invoice_status,
|
|
|
|
|
invoice_category,
|
|
|
|
|
early_flag
|
|
|
|
|
early_flag,
|
|
|
|
|
collection_confirm_status
|
|
|
|
|
} = toRefs<any>(
|
|
|
|
|
proxy?.useDict(
|
|
|
|
|
'business_direction',
|
|
|
|
|
@ -397,7 +439,8 @@ const {
|
|
|
|
|
'wf_business_status',
|
|
|
|
|
'invoice_status',
|
|
|
|
|
'invoice_category',
|
|
|
|
|
'early_flag'
|
|
|
|
|
'early_flag',
|
|
|
|
|
'collection_confirm_status'
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
@ -449,6 +492,34 @@ const formatAmount = (num?: number | string | null) => {
|
|
|
|
|
return value.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 合同阶段比例等百分比展示 */
|
|
|
|
|
const formatStagePercent = (val: number | string | null | undefined) => {
|
|
|
|
|
if (val === null || val === undefined || val === '') {
|
|
|
|
|
return '-';
|
|
|
|
|
}
|
|
|
|
|
const n = Number(val);
|
|
|
|
|
if (!Number.isFinite(n)) {
|
|
|
|
|
return '-';
|
|
|
|
|
}
|
|
|
|
|
return n;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 优先展示后端 actualRepaymentRate;若无则用实际回款金额 / 合同总价推算(与合同回款确认逻辑一致)
|
|
|
|
|
*/
|
|
|
|
|
const displayPlanStageActualRepaymentRate = (row: ErpProjectPlanStageForm) => {
|
|
|
|
|
const stored = row.actualRepaymentRate;
|
|
|
|
|
if (stored != null && Number.isFinite(Number(stored))) {
|
|
|
|
|
return Number(stored);
|
|
|
|
|
}
|
|
|
|
|
const actual = Number(row.actualRepaymentAmount ?? 0);
|
|
|
|
|
const total = Number(contractInfo.value?.totalPrice ?? 0);
|
|
|
|
|
if (!Number.isFinite(total) || total <= 0) {
|
|
|
|
|
return '-';
|
|
|
|
|
}
|
|
|
|
|
return Math.round((actual / total) * 10000) / 100;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 返回 */
|
|
|
|
|
const handleBack = () => {
|
|
|
|
|
proxy?.$tab.closePage(route);
|
|
|
|
|
|