1.1.14 合同激活添加预计回款金额显示并自动赋值

dev
yinq 2 weeks ago
parent 7ab3c08ae7
commit 0403e0ba20

@ -268,7 +268,12 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="预计回款时间" width="220" align="center"> <el-table-column label="预计回款金额(元)" width="220" align="center">
<template #default="scope">
<el-input :model-value="formatRepaymentAmount(scope.row.repaymentAmount)" disabled />
</template>
</el-table-column>
<el-table-column label="预计回款日期" width="220" align="center">
<template #default="scope"> <template #default="scope">
<el-date-picker <el-date-picker
v-model="scope.row.repaymentTime" v-model="scope.row.repaymentTime"
@ -851,6 +856,8 @@ const data = reactive<{ form: ProjectInfoFormEx; rules: any }>({
}); });
const { form, rules } = toRefs(data); const { form, rules } = toRefs(data);
const REPAYMENT_RATE_TOTAL = 100;
const REPAYMENT_RATE_EPSILON = 0.01;
/** 是否禁用表单(查看/审批模式) */ /** 是否禁用表单(查看/审批模式) */
const isFormDisabled = computed(() => routeParams.value.type === 'view' || routeParams.value.type === 'approval'); const isFormDisabled = computed(() => routeParams.value.type === 'view' || routeParams.value.type === 'approval');
@ -906,10 +913,20 @@ function normalizePeopleId(value: string | string[] | number | undefined): strin
return Array.isArray(value) ? value.join(',') : value; return Array.isArray(value) ? value.join(',') : value;
} }
/** 校验回款比例之和是否为 100% */
function isRepaymentRateTotalValid(): boolean {
const totalRate = planStageList.value.reduce((sum, item) => sum + toNumber(item.repaymentRate), 0);
return Math.abs(totalRate - REPAYMENT_RATE_TOTAL) < REPAYMENT_RATE_EPSILON;
}
/** 提交按钮:暂存走 save/update正式提交走 submitContractOrderAndFlowStart关联项目一并提交 */ /** 提交按钮:暂存走 save/update正式提交走 submitContractOrderAndFlowStart关联项目一并提交 */
const submitForm = (status: string, mode: boolean) => { const submitForm = (status: string, mode: boolean) => {
projectInfoFormRef.value?.validate(async (valid: boolean) => { projectInfoFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return; if (!valid) return;
if (!isRepaymentRateTotalValid()) {
proxy?.$modal.msgWarning('回款信息预计回款比例之和必须为100%');
return;
}
if (!projectList.value?.length) { if (!projectList.value?.length) {
proxy?.$modal.msgWarning('合同订单需新建项目或者关联已有项目!'); proxy?.$modal.msgWarning('合同订单需新建项目或者关联已有项目!');
return; return;
@ -967,6 +984,25 @@ const loadSelectOptions = async () => {
await Promise.all([getUserList(), getDeptInfoListSelect(), getPaymentStageList(), getCustomerInfoListSelect()]); await Promise.all([getUserList(), getDeptInfoListSelect(), getPaymentStageList(), getCustomerInfoListSelect()]);
}; };
/** 日期格式化为 YYYY-MM-DD */
const formatDateToYmd = (date: Date): string => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
/** 计算预计回款日期:默认当天;若 paymentDeadline/payment_deadline 有值则当天 + 天数 */
const getDefaultRepaymentDate = (paymentMethod?: Record<string, any>): string => {
const deadline = paymentMethod?.paymentDeadline;
const days = toNumber(deadline);
const target = new Date();
if (days > 0) {
target.setDate(target.getDate() + Math.trunc(days));
}
return formatDateToYmd(target);
};
/** 根据路由 contractId 加载合同信息并回填表单;有项目则加载主项目+阶段+关联项目,无则从合同带出 */ /** 根据路由 contractId 加载合同信息并回填表单;有项目则加载主项目+阶段+关联项目,无则从合同带出 */
const loadContractInfo = async () => { const loadContractInfo = async () => {
isFromContentChange.value = false; isFromContentChange.value = false;
@ -1030,7 +1066,7 @@ const loadContractInfo = async () => {
collectionStage: stage.paymentStageId, collectionStage: stage.paymentStageId,
repaymentRate: pm.paymentPercentage ?? undefined, repaymentRate: pm.paymentPercentage ?? undefined,
repaymentAmount: undefined, repaymentAmount: undefined,
repaymentTime: undefined, repaymentTime: getDefaultRepaymentDate(pm),
delayDay: undefined, delayDay: undefined,
receivableDate: undefined, receivableDate: undefined,
reasonsExplanation: '', reasonsExplanation: '',
@ -1118,6 +1154,42 @@ const approvalVerifyOpen = async () => {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
const planStageList = ref<ErpProjectPlanStageForm[]>([]); const planStageList = ref<ErpProjectPlanStageForm[]>([]);
/** 将任意值转为数字;非法值返回 0 */
const toNumber = (value: unknown): number => {
const n = Number(value);
return Number.isFinite(n) ? n : 0;
};
/** 保留两位小数并避免浮点误差 */
const calcRepaymentAmount = (totalAmount: unknown, repaymentRate: unknown): number => {
const amount = toNumber(totalAmount);
const rate = toNumber(repaymentRate);
return Math.round(((amount * rate) / 100) * 100) / 100;
};
/** 表格展示格式化 */
const formatRepaymentAmount = (value: unknown): string => {
if (value === undefined || value === null || value === '') return '';
const n = Number(value);
return Number.isFinite(n) ? n.toFixed(2) : '';
};
/** 根据合同总价和预计回款比例,实时刷新每行预计回款金额 */
const recalculateRepaymentAmounts = () => {
const totalAmount = form.value.amount;
planStageList.value.forEach((item) => {
item.repaymentAmount = calcRepaymentAmount(totalAmount, item.repaymentRate) as any;
});
};
watch(
[() => form.value.amount, () => planStageList.value.map((item) => item.repaymentRate)],
() => {
recalculateRepaymentAmounts();
},
{ deep: true }
);
const getPlanStageList = async () => { const getPlanStageList = async () => {
if (!form.value.projectId) { if (!form.value.projectId) {
planStageList.value = []; planStageList.value = [];
@ -1145,6 +1217,7 @@ const getPlanStageList = async () => {
sortOrder: item.sortOrder || planStageList.value.length + 1, sortOrder: item.sortOrder || planStageList.value.length + 1,
activeFlag: item.activeFlag || '1' activeFlag: item.activeFlag || '1'
})); }));
recalculateRepaymentAmounts();
} catch (error) { } catch (error) {
console.error('查询项目阶段计划失败:', error); console.error('查询项目阶段计划失败:', error);
planStageList.value = []; planStageList.value = [];

Loading…
Cancel
Save