1.1.49 分款审核页面、分款流程优化。

dev
yinq 3 weeks ago
parent e7cdde97f6
commit 86a7e88551

@ -74,11 +74,6 @@ export interface FinAccountInstallmentVO {
*/
managerNickNames?: string;
/**
*
*/
canAllocate?: boolean;
}
export interface FinAccountInstallmentForm extends BaseEntity {
@ -147,11 +142,6 @@ export interface FinAccountInstallmentForm extends BaseEntity {
*/
managerNickNames?: string;
/**
*
*/
canAllocate?: boolean;
/** 流程编码 */
flowCode?: string;
@ -163,20 +153,10 @@ export interface FinAccountInstallmentForm extends BaseEntity {
}
/** 派发给客户经理(含流程启动参数,前端组装) */
/** 派发给客户经理 */
export interface FinAccountInstallmentDispatchForm {
accountInstallmentIds: Array<string | number>;
managerUserIds: Array<string | number>;
/** 流程编码 FKSH */
flowCode?: string;
/** 流程变量 */
variables?: Record<string, any>;
/** 各回款流程业务扩展businessId=回款主键) */
flowBizList?: Array<{
businessId?: string;
businessCode?: string;
businessTitle?: string;
}>;
}
export interface FinAccountInstallmentQuery extends PageQuery {

@ -17,11 +17,10 @@
<template #header>
<div class="flex items-center justify-between">
<div style="text-align: left; font-weight: bold; font-size: 24px">{{ pageTitle }}</div>
<el-button v-if="canAllocate" type="primary" @click="handleAddDetail">
<el-button v-if="canEditDetail" type="primary" @click="handleAddDetail">
<el-icon class="mr-1"><Plus /></el-icon>
新增分款
</el-button>
<el-tag v-else-if="routeParams.type === 'allocate'" type="info">{{ allocateHintText }}</el-tag>
</div>
</template>
@ -71,7 +70,7 @@
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
<el-table-column v-if="canAllocate" label="操作" align="center" width="100" fixed="right">
<el-table-column v-if="canEditDetail" label="操作" align="center" width="100" fixed="right">
<template #default="{ row }">
<el-button link type="primary" size="small" @click="handleEditDetail(row)"></el-button>
<el-button link type="danger" size="small" @click="handleDeleteDetail(row)"></el-button>
@ -80,7 +79,7 @@
</el-table>
<el-empty
v-if="!detailLoading && !detailList.length"
:description="canAllocate ? '暂无分款明细,请点击新增分款添加' : '暂无分款明细'"
:description="canEditDetail ? '暂无分款明细,请点击新增分款添加' : '暂无分款明细'"
class="mt-3"
/>
</el-card>
@ -197,12 +196,6 @@ const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
const taskVariables = ref<Record<string, any>>({});
const FLOW_STATUS = { DRAFT: 'draft', WAITING: 'waiting', FINISH: 'finish', BACK: 'back', CANCEL: 'cancel' };
const INSTALLMENT_STATUS = { NOT_ALLOCATED: '0', DISPATCHED: '1', COMPLETE: '2' };
const isFlowEditable = (flowStatus?: string) =>
!flowStatus || flowStatus === FLOW_STATUS.DRAFT || flowStatus === FLOW_STATUS.BACK || flowStatus === FLOW_STATUS.CANCEL;
const initFormData: FinAccountInstallmentForm = {
accountInstallmentId: undefined,
installmentCode: undefined,
@ -216,7 +209,6 @@ const initFormData: FinAccountInstallmentForm = {
accountManagerIds: undefined,
managerUserIds: [],
managerNickNames: undefined,
canAllocate: undefined
};
const form = ref<FinAccountInstallmentForm>({ ...initFormData });
@ -228,20 +220,8 @@ const pageTitle = computed(() => {
return '客户分款';
});
/** 客户经理分款:查看模式只读,审批/分款模式在 canAllocate 时可维护明细 */
const canAllocate = computed(() => form.value.canAllocate === true && routeParams.value.type !== 'view');
const allocateHintText = computed(() => {
if (form.value.canAllocate) return '';
if (isFlowEditable(form.value.flowStatus) && form.value.installmentStatus === INSTALLMENT_STATUS.NOT_ALLOCATED) {
return '请先由财务派发给客户经理';
}
if (form.value.flowStatus === FLOW_STATUS.FINISH || form.value.installmentStatus === INSTALLMENT_STATUS.COMPLETE) {
return '分款已完成';
}
if (form.value.flowStatus !== FLOW_STATUS.WAITING) return '流程未处于待处理状态';
return '您无权操作该回款分款';
});
/** 仅分款审核页type=approval待办审批进入可维护分款明细 */
const canEditDetail = computed(() => routeParams.value.type === 'approval');
const allocatedAmount = computed(() =>
Number((detailList.value || []).reduce((sum, item) => sum + Number(item.detailAmount || 0), 0))
@ -249,6 +229,27 @@ const allocatedAmount = computed(() =>
const remainingAmount = computed(() => Number(form.value.paymentAmount || 0) - allocatedAmount.value);
/** 分款金额与回款金额平衡容差(元) */
const ALLOCATION_AMOUNT_EPS = 0.005;
/** 提交/审批前校验:分款总额须等于回款金额 */
const validateAllocationBeforeSubmit = (): boolean => {
const remain = remainingAmount.value;
if (remain < -ALLOCATION_AMOUNT_EPS) {
proxy?.$modal.msgWarning(`分款金额超出回款金额,已超出 ¥${formatMoney(Math.abs(remain))},无法提交`);
return false;
}
if (remain > ALLOCATION_AMOUNT_EPS) {
proxy?.$modal.msgWarning(`分款金额不足回款金额,还差 ¥${formatMoney(remain)} 未分配,无法提交`);
return false;
}
if (!detailList.value.length) {
proxy?.$modal.msgWarning('请至少添加一条分款明细后再提交');
return false;
}
return true;
};
const formRemainingAmount = computed(() => {
const currentDetailAmount = Number(detailForm.detailAmount) || 0;
const existingTotal = Number(
@ -441,8 +442,7 @@ const handleAddDetail = () => {
proxy?.$modal.msgWarning('回款数据未加载');
return;
}
if (!canAllocate.value) {
proxy?.$modal.msgWarning(allocateHintText.value || '当前不可分款');
if (!canEditDetail.value) {
return;
}
showProjectDialog.value = true;
@ -593,6 +593,9 @@ const handleApprovalRecord = () => {
};
const approvalVerifyOpen = async () => {
if (!validateAllocationBeforeSubmit()) {
return;
}
syncTaskVariables();
await submitVerifyRef.value?.openDialog(routeParams.value.taskId);
};

@ -66,7 +66,7 @@
plain
icon="Promotion"
:disabled="!canDispatchSelection"
@click="openDispatchDialog"
@click="openDispatchDialog()"
v-hasPermi="['oa/erp:finAccountInstallment:dispatch']"
>
派发客户经理
@ -116,7 +116,7 @@
link
type="warning"
icon="Promotion"
@click.stop="handleDispatchRow(row)"
@click.stop="openDispatchDialog([row])"
v-hasPermi="['oa/erp:finAccountInstallment:dispatch']"
/>
</el-tooltip>
@ -266,7 +266,6 @@
>
<template #description>
<p class="detail-empty__desc">暂无分款明细</p>
<p v-if="selectedInstallment.canAllocate" class="detail-empty__hint"></p>
</template>
</el-empty>
</div>
@ -387,7 +386,6 @@ import {
FinAccountInstallmentVO,
FinAccountInstallmentDispatchForm
} from '@/api/oa/erp/finAccountInstallment/types';
import { FlowCodeEnum } from '@/enums/OAEnum';
import { FinAccountInstallmentDetailVO } from '@/api/oa/erp/finAccountInstallmentDetail/types';
import { DArrowLeft } from '@element-plus/icons-vue';
import { getUserList } from '@/api/system/user';
@ -519,47 +517,25 @@ const submitInstallmentForm = async () => {
}
};
const openDispatchDialog = async () => {
if (!canDispatchSelection.value) {
proxy?.$modal.msgWarning('请勾选分款进度为「未分款」的回款');
/** 打开派发弹窗(批量勾选或操作列单条) */
const openDispatchDialog = async (rows?: FinAccountInstallmentVO[]) => {
const targetRows = rows ?? selectedInstallmentRows.value;
if (!targetRows.length || !targetRows.every(isNotAllocated)) {
proxy?.$modal.msgWarning(
rows?.length ? '仅未分款状态的回款可派发' : '请勾选分款进度为「未分款」的回款'
);
return;
}
selectedInstallmentRows.value = targetRows;
dispatchManagerUserIds.value = [];
await loadManagerUserOptions();
dispatchDialog.visible = true;
};
/** 操作列:单条派发 */
const handleDispatchRow = async (row: FinAccountInstallmentVO) => {
if (!isNotAllocated(row)) {
proxy?.$modal.msgWarning('仅未分款状态的回款可派发');
return;
}
selectedInstallmentRows.value = [row];
dispatchManagerUserIds.value = [];
await loadManagerUserOptions();
dispatchDialog.visible = true;
};
/** 组装派发及流程启动参数(仿出差申请 submitAndFlowStart */
const buildDispatchPayload = (): FinAccountInstallmentDispatchForm => {
const accountManagerId = dispatchManagerUserIds.value.map((id) => String(id)).join(',');
const rows = selectedInstallmentRows.value;
return {
accountInstallmentIds: rows.map((r) => r.accountInstallmentId),
managerUserIds: dispatchManagerUserIds.value,
flowCode: FlowCodeEnum.FIN_ACCOUNT_INSTALLMENT_CODE,
variables: {
ignore: true,
accountManagerId
},
flowBizList: rows.map((row) => ({
businessId: String(row.accountInstallmentId),
businessCode: row.installmentCode,
businessTitle: `${row.customerName}分款审核`
}))
};
};
const buildDispatchPayload = (): FinAccountInstallmentDispatchForm => ({
accountInstallmentIds: selectedInstallmentRows.value.map((r) => r.accountInstallmentId),
managerUserIds: dispatchManagerUserIds.value
});
const submitDispatch = async () => {
if (!dispatchManagerUserIds.value.length) {
@ -641,17 +617,6 @@ const handleView = (row: FinAccountInstallmentVO) => {
});
};
/** 客户经理分款 */
const handleGoAllocate = (row: FinAccountInstallmentVO) => {
router.push({
path: '/oa/erp/finAccountInstallment/edit',
query: {
id: String(row.accountInstallmentId),
type: 'allocate'
}
});
};
const handleRowClick = async (row: FinAccountInstallmentVO) => {
selectedInstallment.value = row;
await getDetailList();

Loading…
Cancel
Save