Commit 68d5fe62 authored by 沈翠玲's avatar 沈翠玲

业务审批接口对接

parent 0c4dc28a
......@@ -36,16 +36,40 @@ export const getRepayRecords = (id) => {
export const saveRepayRecord = (data) => {
return request.post('/repayRecord/save', data);
};
// 还款申请列表
export const getRepayRecordPage = (params) => {
return request.get('/repayRecord/page', params);
};
// 还款申请批量
export const repayRecordFlowStatusByIds = (params) => {
return request.get('/repayRecord/flowStatusByIds', params);
};
// 减免申请保存
export const saveReduce = (data) => {
return request.post('/reduce/save', data);
};
// 减免申请列表
export const getReducePage = (params) => {
return request.get('/reduce/page', params);
};
// 减免申请批量
export const flowStatusByIds = (params) => {
return request.get('/reduce/flowStatusByIds', params);
};
// 分期申请保存
export const savebyStages = (data) => {
return request.post('/byStages/save', data);
};
// 分期申请列表
export const getByStagesPage = (params) => {
return request.get('/byStages/page', params);
};
// 分期申请批量审核
export const byStagesflowStatusByIds = (params) => {
return request.get('/byStages/flowStatusByIds', params);
};
// 保存案件跟踪记录
export const saveTrackRecord = (data) => {
......
<template>
<div class="card content-box">
<span class="text"> 分期申请 🍓🍇🍈🍉</span>
<div class="table-box">
<ProTable :config="config" ref="ProTableRef" :api="getByStagesPage">
<template #left_buttons>
<!-- <el-button type="primary">下载申请 </el-button> -->
<el-button
type="primary"
@click="changeStatus"
:disabled="!selectdList || selectdList.length > 1"
>审批
</el-button>
<!-- <el-button type="primary">下载 </el-button>
<el-button type="primary">批量修复上传 </el-button> -->
</template>
</ProTable>
<vxe-modal
v-model="showModal"
title="审批提示"
height="282"
width="450"
show-footer
esc-closable
>
<div class="w-full px-3 h-full overflow-auto flex-col flex mytable">
是否审批通过选中的数据?
</div>
<template #footer>
<el-button type="default" @click="showModal = false">取消</el-button>
<el-button type="danger" @click="submitForm('fail')">不通过</el-button>
<el-button type="primary" @click="submitForm('pass')">通过</el-button>
</template>
</vxe-modal>
</div>
</template>
<script setup name="systemLog"></script>
<script setup name="systemLog" lang="jsx">
import { computed } from 'vue';
import { reactive, ref } from 'vue';
import { getByStagesPage, byStagesflowStatusByIds } from '@/api/property';
import { onMounted } from 'vue';
import { ElMessageBox, ElMessage, ElButton } from 'element-plus';
const ProTableRef = ref();
const showModal = ref(false);
const selectdList = ref([]);
const onCheckboxChange = (row) => {
console.log('row', row);
selectdList.value = row.records;
};
const options = [
{
value: 2,
label: '2',
},
{
value: 3,
label: '3',
},
{
value: 4,
label: '4',
},
{
value: 5,
label: '5',
},
{
value: 6,
label: '6',
},
];
const flowStatusOpt = [
{ label: '待审核', value: 'pending' },
{ label: '通过', value: 'pass' },
{ label: '未通过', value: 'fail' },
];
const changeStatus = async () => {
showModal.value = true;
};
const submitForm = async (type) => {
const ids = selectdList.value.map((v) => v.id).join(',');
await byStagesflowStatusByIds({
ids: ids,
flowStatus: type,
});
ElMessage.success({
message: '审核成功',
plain: true,
});
showModal.value = false;
query();
};
const config = computed(() => {
return {
columns: [
{ type: 'checkbox', width: 50 },
{
field: 'caseId',
title: '案件ID',
search: { el: 'input' },
width: 80,
},
{
field: 'payOrg',
title: '借款机构',
search: { el: 'input' },
width: 80,
},
{
field: 'totalRepayAmount',
title: '还款总额',
search: { el: 'input' },
width: 80,
},
{
field: 'applyDate',
title: '分期申请时间',
search: {
el: 'date-picker',
props: { type: 'datetime', valueFormat: 'YYYY-MM-DD HH:mm:ss' },
},
width: 115,
},
{
field: 'effectiveTime',
title: '分期生效时间',
search: {
el: 'date-picker',
props: { type: 'datetime', valueFormat: 'YYYY-MM-DD HH:mm:ss' },
},
width: 115,
},
{
field: 'totalPeriod',
title: '还款期数',
enum: options,
search: { el: 'select', props: { filterable: true }, span: 1 },
fieldNames: { label: 'label', value: 'value' },
width: 80,
},
{
field: 'firstApplyDate',
title: '首期还款日',
search: { el: 'input' },
search: { el: 'date-picker', props: { type: 'date', valueFormat: 'YYYY-MM-DD' } },
width: 100,
},
{
field: 'remainingAmount',
title: '剩余待还金额',
search: { el: 'input' },
width: 110,
},
{
field: 'flowStatus',
title: '审核状态',
width: 80,
enum: flowStatusOpt,
search: { el: 'select', props: { filterable: true }, span: 1 },
fieldNames: { label: 'label', value: 'value' },
slots: {
default: ({ row }) => {
return (
<>
{row.flowStatus
? flowStatusOpt.find((v) => v.value === row.flowStatus).label
: ''}
</>
);
},
},
},
],
onCheckboxChange: onCheckboxChange,
};
});
const query = () => ProTableRef.value?.search();
onMounted(() => {
query();
});
</script>
<template>
<div class="card content-box">
<span class="text"> 减免申请 🍓🍇🍈🍉</span>
<div class="table-box">
<ProTable :config="config" ref="ProTableRef" :api="getReducePage">
<template #left_buttons>
<!-- <el-button type="primary">下载申请 </el-button> -->
<el-button
type="primary"
@click="changeStatus"
:disabled="!selectdList || selectdList.length > 1"
>审批
</el-button>
<!-- <el-button type="primary">下载 </el-button>
<el-button type="primary">批量修复上传 </el-button> -->
</template>
</ProTable>
<vxe-modal
v-model="showModal"
title="审批提示"
height="282"
width="450"
show-footer
esc-closable
>
<div class="w-full px-3 h-full overflow-auto flex-col flex mytable">
是否审批通过选中的数据?
</div>
<template #footer>
<el-button type="default" @click="showModal = false">取消</el-button>
<el-button type="danger" @click="submitForm('fail')">不通过</el-button>
<el-button type="primary" @click="submitForm('pass')">通过</el-button>
</template>
</vxe-modal>
</div>
</template>
<script setup name="systemLog"></script>
<script setup name="systemLog" lang="jsx">
import { computed } from 'vue';
import { reactive, ref } from 'vue';
import { getReducePage, flowStatusByIds } from '@/api/property';
import { onMounted } from 'vue';
import { ElMessageBox, ElMessage, ElButton } from 'element-plus';
const ProTableRef = ref();
const showModal = ref(false);
const selectdList = ref([]);
const onCheckboxChange = (row) => {
console.log('row', row);
selectdList.value = row.records;
};
const reduceTypeOpt = [
{ label: '结清减免', value: 'settle' },
{ label: '分期减免', value: 'by_stages' },
];
const flowStatusOpt = [
{ label: '待审核', value: 'pending' },
{ label: '通过', value: 'pass' },
{ label: '未通过', value: 'fail' },
];
const changeStatus = async () => {
showModal.value = true;
};
const submitForm = async (type) => {
const ids = selectdList.value.map((v) => v.id).join(',');
await flowStatusByIds({
ids: ids,
flowStatus: type,
});
ElMessage.success({
message: '审核成功',
plain: true,
});
showModal.value = false;
query();
};
const config = computed(() => {
return {
columns: [
{ type: 'checkbox', width: 50 },
{
field: 'caseId',
title: '案件ID',
search: { el: 'input' },
width: 80,
},
{
field: 'reduceAmount',
title: '减免金额',
search: { el: 'input' },
width: 80,
},
{
field: 'totalReduceAmount',
title: '减免金额(总计)',
search: { el: 'input' },
width: 120,
},
{
field: 'totalNumber',
title: '减免案件数',
search: { el: 'input' },
width: 120,
},
{
field: 'remainingAmount',
title: '剩余待还金额',
search: { el: 'input' },
width: 120,
},
{
field: 'totalPayAmount',
title: '累计还款金额',
search: { el: 'input' },
width: 120,
},
{
field: 'reduceType',
title: '减免类型',
width: 80,
enum: reduceTypeOpt,
search: { el: 'select', props: { filterable: true }, span: 1 },
fieldNames: { label: 'label', value: 'value' },
slots: {
default: ({ row }) => {
return (
<>
{row.reduceType
? reduceTypeOpt.find((v) => v.value === row.reduceType).label
: ''}
</>
);
},
},
},
{
field: 'flowStatus',
title: '审核状态',
width: 80,
enum: flowStatusOpt,
search: { el: 'select', props: { filterable: true }, span: 1 },
fieldNames: { label: 'label', value: 'value' },
slots: {
default: ({ row }) => {
return (
<>
{row.flowStatus
? flowStatusOpt.find((v) => v.value === row.flowStatus).label
: ''}
</>
);
},
},
},
{
field: 'id',
title: '减免申请ID',
search: { el: 'input' },
width: 100,
},
{
field: 'applyDate',
title: '减免申请时间',
search: {
el: 'date-picker',
props: { type: 'datetime', valueFormat: 'YYYY-MM-DD HH:mm:ss' },
},
},
{
field: 'inEffectDate',
title: '减免生效时间',
search: {
el: 'date-picker',
props: { type: 'datetime', valueFormat: 'YYYY-MM-DD HH:mm:ss' },
},
},
],
onCheckboxChange: onCheckboxChange,
};
});
const query = () => ProTableRef.value?.search();
onMounted(() => {
query();
});
</script>
......@@ -2,10 +2,10 @@
<div class="table-box">
<ProTable :config="config" :data="tabledata" :showPagination="false" :showToolBar="true">
<template #left_buttons>
<el-button type="primary">下载申请 </el-button>
<!-- <el-button type="primary">下载申请 </el-button> -->
<el-button type="primary">审批 </el-button>
<el-button type="primary">下载 </el-button>
<el-button type="primary">批量修复上传 </el-button>
<!-- <el-button type="primary">下载 </el-button>
<el-button type="primary">批量修复上传 </el-button> -->
</template>
</ProTable>
</div>
......
<template>
<div class="card content-box">
<span class="text"> 还款审批 🍓🍇🍈🍉</span>
<div class="table-box">
<ProTable :config="config" ref="ProTableRef" :api="getRepayRecordPage">
<template #left_buttons>
<!-- <el-button type="primary">下载申请 </el-button> -->
<el-button
type="primary"
@click="changeStatus"
:disabled="!selectdList || selectdList.length > 1"
>审批
</el-button>
<!-- <el-button type="primary">下载 </el-button>
<el-button type="primary">批量修复上传 </el-button> -->
</template>
</ProTable>
<vxe-modal
v-model="showModal"
title="审批提示"
height="282"
width="450"
show-footer
esc-closable
>
<div class="w-full px-3 h-full overflow-auto flex-col flex mytable">
是否审批通过选中的数据?
</div>
<template #footer>
<el-button type="default" @click="showModal = false">取消</el-button>
<el-button type="danger" @click="submitForm('fail')">不通过</el-button>
<el-button type="primary" @click="submitForm('pass')">通过</el-button>
</template>
</vxe-modal>
</div>
</template>
<script setup name="systemLog"></script>
<script setup name="systemLog" lang="jsx">
import { computed } from 'vue';
import { reactive, ref } from 'vue';
import { getRepayRecordPage, repayRecordFlowStatusByIds } from '@/api/property';
import { onMounted } from 'vue';
import { ElMessageBox, ElMessage, ElButton } from 'element-plus';
const ProTableRef = ref();
const showModal = ref(false);
const selectdList = ref([]);
const onCheckboxChange = (row) => {
console.log('row', row);
selectdList.value = row.records;
};
const options = [
{
value: 'repay',
label: '直接还款',
},
{
value: 'by_stages',
label: '分期还款',
},
{
value: 'settle',
label: '结清减免还款',
},
];
const flowStatusOpt = [
{ label: '待审核', value: 'pending' },
{ label: '通过', value: 'pass' },
{ label: '未通过', value: 'fail' },
];
const changeStatus = async () => {
showModal.value = true;
};
const submitForm = async (type) => {
const ids = selectdList.value.map((v) => v.id).join(',');
await repayRecordFlowStatusByIds({
ids: ids,
flowStatus: type,
});
ElMessage.success({
message: '审核成功',
plain: true,
});
showModal.value = false;
query();
};
const config = computed(() => {
return {
columns: [
{ type: 'checkbox', width: 50 },
{
field: 'caseId',
title: '案件ID',
search: { el: 'input' },
width: 80,
},
{
field: 'id',
title: '还款记录ID',
search: { el: 'input' },
},
{
field: 'realRepayAmount',
title: '实际还款金额',
search: { el: 'input' },
},
{
field: 'realRepayTime',
title: '实际还款时间',
search: {
el: 'date-picker',
props: { type: 'datetime', valueFormat: 'YYYY-MM-DD HH:mm:ss' },
},
width: 115,
},
{
field: 'reduce.totalPayAmount',
title: '应还金额',
search: { el: 'input', key: 'reduce.totalPayAmount' },
width: 115,
},
{
field: 'repayType',
title: '还款方式',
enum: options,
search: { el: 'select', props: { filterable: true }, span: 1 },
fieldNames: { label: 'label', value: 'value' },
width: 80,
},
{
field: 'stages.loans.payOrg',
title: '借款机构',
search: { el: 'input', key: 'stages.loans.payOrg' },
width: 100,
},
{
field: 'flowStatus',
title: '审核状态',
width: 80,
enum: flowStatusOpt,
search: { el: 'select', props: { filterable: true }, span: 1 },
fieldNames: { label: 'label', value: 'value' },
slots: {
default: ({ row }) => {
return (
<>
{row.flowStatus
? flowStatusOpt.find((v) => v.value === row.flowStatus).label
: ''}
</>
);
},
},
},
],
onCheckboxChange: onCheckboxChange,
};
});
const query = () => ProTableRef.value?.search();
onMounted(() => {
query();
});
</script>
......@@ -80,7 +80,8 @@
import { computed } from 'vue';
import { reactive, ref } from 'vue';
import { saveReduce } from '@/api/property';
import { ElMessage } from 'element-plus';
const emits = defineEmits(['success']);
const showModal = ref(false);
const tabledata = ref([]);
const form = reactive({
......@@ -115,27 +116,27 @@
columns: [
// { type: 'checkbox', title: '', width: '40px' },
{
field: 'caseId',
field: 'loan.caseId',
title: '案件ID',
},
{
field: 'product',
field: 'loan.product',
title: '产品',
},
{
field: 'payOrg',
field: 'loan.payOrg',
title: '借款机构',
},
{
field: 'commissionAmount',
field: 'loan.commissionAmount',
title: '委案金额',
},
{
field: 'sumReductionAmount',
field: 'loan.sumReductionAmount',
title: '累计减免金额',
},
{
field: 'sumRepayAmount',
field: 'loan.sumRepayAmount',
title: '累计还款金额',
},
{
......@@ -152,7 +153,7 @@
},
},
{
field: 'remainingAmount',
field: 'loan.remainingAmount',
title: '剩余待还金额(减免前)',
},
{
......@@ -164,7 +165,7 @@
toolbarConfig: { enabled: false },
});
const changeNum = (row) => {
row.payAmount = row.remainingAmount - row.reduceAmount;
row.payAmount = row.loan.remainingAmount - row.reduceAmount;
form.totalReduceAmount = 0;
form.totalPayAmount = 0;
tabledata.value.forEach((item) => {
......@@ -178,22 +179,40 @@
console.log('currentDetail', currentDetail.value, caselist);
form.totalReduceAmount = 0;
form.totalPayAmount = 0;
const list = [];
caselist.forEach((item) => {
const payAmount = Number(item.remainingAmount) || 0;
list.push({ reduceAmount: Number(item.reduceAmount) || 0, payAmount: payAmount, loan: item });
form.totalReduceAmount += Number(item.reduceAmount) || 0;
form.totalPayAmount += Number(item.payAmount) || 0;
form.totalPayAmount += payAmount;
});
tabledata.value = caselist;
tabledata.value = list;
form.totalNumber = caselist.length;
};
const submitForm = () => {
const list = JSON.parse(JSON.stringify(tabledata.value));
list.forEach((item) => {
delete item.payAmount;
});
const params = {
...currentDetail.value,
borrower: currentDetail.value.borrower,
askForStatus: 'Pending',
flowStatus: 'pending',
...form,
reduceRecords: tabledata.value,
id: null,
reduceRecords: list,
};
console.log('sadas', params);
delete params.id;
delete params.cpe;
saveReduce(params).then((res) => {
if (res.success) {
ElMessage.success({
message: '保存成功',
plain: true,
});
showModal.value = false;
emits('success');
}
});
};
......
<template>
<vxe-modal
v-model="showModal"
:title="currentInfo.title"
:title="currentType"
@hide="onHide"
height="482"
width="1003"
......@@ -9,52 +9,50 @@
esc-closable
>
<div class="w-full px-3 h-full overflow-auto flex-col flex mytable">
<template v-if="currentInfo.title === '结清减免还款' || currentInfo.title === '直接还款'">
<table style="margin-bottom: 10px" v-if="currentInfo.title === '结清减免还款'">
<template v-if="currentType === '结清减免还款' || currentType === '直接还款'">
<table style="margin-bottom: 10px" v-if="currentType === '结清减免还款'">
<tr>
<td class="label">减免类型</td>
<td>结清减免</td>
<td class="label">减免申请ID</td>
<td>30</td>
<td>{{ currentInfo.id }}</td>
<td class="label">减免申请时间</td>
<td>30</td>
<td>{{ currentInfo.applyDate }}</td>
</tr>
<tr>
<td class="label">减免金额(总计)</td>
<td>johndoe@example.com</td>
<td>{{ currentInfo.totalReduceAmount }}</td>
<td class="label">减免案件数</td>
<td>johndoe@example.com</td>
<td>{{ currentInfo.totalNumber }}</td>
<td class="label">减免生效时间</td>
<td>johndoe@example.com</td>
<td>{{ currentInfo.inEffectDate }}</td>
</tr>
<tr>
<td class="label">应还金额</td>
<td colspan="5">John Doe</td>
<td colspan="5">{{ currentInfo.totalPayAmount }}</td>
</tr>
<!-- Add more rows as needed -->
</table>
<table style="margin-bottom: 10px" v-else>
<tr>
<td class="label">案件ID</td>
<td>1111</td>
<td>{{ currentInfo.caseId }}</td>
<td class="label">借款平台</td>
<td>30</td>
<td>{{ currentInfo.payOrg }}</td>
<td class="label">资管公司</td>
<td>30</td>
<td>{{ currentInfo.manageOrg }}</td>
</tr>
<tr>
<td class="label">委案金额</td>
<td>johndoe@example.com</td>
<td>{{ currentInfo.commissionAmount }}</td>
<td class="label">累计减免金额</td>
<td>johndoe@example.com</td>
<td class="label">分期生效时间</td>
<td>johndoe@example.com</td>
<td>{{ currentInfo.sumReductionAmount }}</td>
<td class="label">剩余待还金额</td>
<td>{{ currentInfo.remainingAmount }}</td>
</tr>
<tr>
<td class="label">剩余待还金额</td>
<td>John Doe</td>
<td class="label">累计还款金额</td>
<td colspan="3">John Doe</td>
<td colspan="5">{{ currentInfo.sumRepayAmount }}</td>
</tr>
<!-- Add more rows as needed -->
</table>
......@@ -62,24 +60,27 @@
<el-form ref="formRef" inline :model="form" :rules="rules" label-width="110px">
<el-row>
<el-col :span="8">
<el-form-item class="w-full" label="实际还款金额:" prop="name">
<el-form-item class="w-full" label="实际还款金额:" prop="realRepayAmount">
<div>
<el-input v-model="form.name" placeholder="请输入" style="width: 100%" />
<div class="text-red-500">*金额必须等于应还金额</div>
<el-input
v-model="form.realRepayAmount"
placeholder="请输入"
style="width: 100%"
/>
</div>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item class="w-full" label="实际还款时间:" prop="name">
<el-date-picker
v-model="form.datetime"
v-model="form.realRepayTime"
class="w-full"
format="YYYY-MM-DD HH:mm:ss"
type="datetime"
/>
</el-form-item>
</el-col>
<el-col :span="8" v-if="currentInfo.title === '结清减免还款'">
<el-col :span="8" v-if="currentType === '结清减免还款'">
<el-form-item class="w-full" label="付款凭证:" prop="name">
<el-upload
v-model:file-list="form.files"
......@@ -101,35 +102,41 @@
</el-form>
</div>
</template>
<template v-if="currentInfo.title === '分期还款'">
<template v-if="currentType === '分期还款'">
<table style="margin-bottom: 10px">
<tr>
<td class="label">分期申请ID</td>
<td>1111</td>
<td>{{ currentDetail.id }}</td>
<td class="label">还款总额</td>
<td>30</td>
<td>{{ currentDetail.totalRepayAmount }}</td>
<td class="label">分期申请时间</td>
<td>30</td>
<td>{{ currentDetail.applyDate }}</td>
</tr>
<tr>
<td class="label">还款期数</td>
<td>johndoe@example.com</td>
<td>{{ currentDetail.totalPeriod }}</td>
<td class="label">首期还款日</td>
<td>johndoe@example.com</td>
<td>{{ currentDetail.firstApplyDate }}</td>
<td class="label">分期生效时间</td>
<td>johndoe@example.com</td>
<td>{{ currentDetail.effectiveTime }}</td>
</tr>
<tr>
<td class="label">期次</td>
<td>111</td>
<td>{{ currentInfo.period }}</td>
<td class="label">期次还款到期日</td>
<td colspan="3">John Doe</td>
<td colspan="3">{{ currentInfo.playApplyDate }}</td>
</tr>
<tr>
<td class="label">期次应还金额</td>
<td>111</td>
<td>{{ currentInfo.applyAmount }}</td>
<td class="label">期次还款状态</td>
<td colspan="3">John Doe</td>
<td colspan="3">{{
currentInfo.repayStatus
? currentInfo.repayStatus === 'over'
? '已还款'
: '待还款'
: ''
}}</td>
</tr>
</table>
<div class="flex">
......@@ -137,9 +144,9 @@
<el-form ref="formRef" inline :model="form" :rules="rules" label-width="110px">
<el-row>
<el-col :span="24">
<el-form-item class="w-full" label="实际还款时间:" prop="name">
<el-form-item class="w-full" label="实际还款时间:" prop="realRepayTime">
<el-date-picker
v-model="form.datetime"
v-model="form.realRepayTime"
class="w-full"
format="YYYY-MM-DD HH:mm:ss"
type="datetime"
......@@ -147,10 +154,13 @@
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item class="w-full" label="实际还款金额:" prop="name">
<el-form-item class="w-full" label="实际还款金额:" prop="realRepayAmount">
<div class="w-full">
<el-input v-model="form.name" placeholder="请输入" class="w-full" />
<div class="text-red-500">*金额必须等于应还金额</div>
<el-input
v-model="form.realRepayAmount"
placeholder="请输入"
class="w-full"
/>
</div>
</el-form-item>
</el-col>
......@@ -180,37 +190,61 @@
import dayjs from 'dayjs';
import { reactive, ref } from 'vue';
import { getAppEnvConfig } from '@/utils/env';
import { ElMessage } from 'element-plus';
import { saveRepayRecord } from '@/api/property';
const envs = getAppEnvConfig();
const data = ref([]);
const mytransfer = ref();
const tabledata = ref([]);
const url = envs.VITE_GLOB_API_URL_PREFIX + '/sys/upload';
const showModal = ref(false);
const currentInfo = ref({ title: '结清减免还款', case: 0, money: 0 });
const currentType = ref('');
const formRef = ref();
const currentInfo = ref({});
const currentDetail = ref({});
const emits = defineEmits(['success']);
const form = reactive({
name: '',
realRepayAmount: '',
files: [],
datetime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
realRepayTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
});
const radio = ref(0);
const step = ref(0);
const validaterealRepayAmount = (rule, value, callback) => {
if (
Number(value) !== Number(currentInfo.value.totalPayAmount) &&
currentType.value === '结清减免还款'
) {
callback(new Error('*金额必须等于应还金额'));
} else if (
Number(value) !== Number(currentInfo.value.remainingAmount) &&
currentType.value === '直接还款'
) {
callback(new Error('*金额必须等于应还金额'));
} else if (
Number(value) !== Number(currentInfo.value.applyAmount) &&
currentType.value === '分期还款'
) {
callback(new Error('*金额必须等于应还金额'));
} else {
callback();
}
};
const rules = ref({
realRepayAmount: [{ validator: validaterealRepayAmount, trigger: 'blur' }],
});
const onHide = () => {
currentInfo.value = { title: '结清减免还款', case: 0, money: 0 };
currentInfo.value = {};
};
const openModal = (account) => {
const openModal = (info, detail, type) => {
showModal.value = true;
currentInfo.value = { title: '分期还款', case: 44, money: 1111 };
step.value = 0;
radio.value = 0;
currentInfo.value = info;
console.log('currentInfo', currentInfo.value);
currentDetail.value = detail;
currentType.value = type;
tabledata.value = detail.loans;
};
const submitForm = () => {
if (step.value || radio.value === 0) {
} else {
step.value = 1;
}
};
const handleRemove = (uploadFile, uploadFiles) => {
console.log(uploadFile, uploadFiles);
};
......@@ -221,26 +255,42 @@
};
const options = [
{
value: 'Option1',
label: 'Option1',
},
{
value: 'Option2',
label: 'Option2',
},
{
value: 'Option3',
label: 'Option3',
value: 'repay',
label: '直接还款',
},
{
value: 'Option4',
label: 'Option4',
value: 'by_stages',
label: '分期还款',
},
{
value: 'Option5',
label: 'Option5',
value: 'settle',
label: '结清减免还款',
},
];
const submitForm = () => {
formRef.value.validate((valid) => {
if (valid) {
saveRepayRecord({
repayType: options.find((v) => v.label === currentType.value).value,
...form,
borrower: currentInfo.value.borrower,
flowStatus: 'pending',
repayStatus: 'over',
status: 'enable',
}).then((res) => {
console.log('res', res);
if (res.success) {
ElMessage.success({
message: '保存成功',
plain: true,
});
showModal.value = false;
emits('success');
}
});
}
});
};
const handleFileSuccess = (response, file, fileList) => {
console.log('888877', response, file, fileList);
};
......@@ -249,27 +299,20 @@
toolbarConfig: { enabled: false },
columns: [
{
field: 'code',
field: 'caseId',
title: '案件ID',
},
{
field: 'code',
field: 'payOrg',
title: '借款机构',
},
{
field: 'code',
field: 'remainingAmount',
title: '剩余待还金额',
},
],
};
});
tabledata.value = [
{ name: 'admin', code: 'admin', role: 'superadmin', num: 1 },
{ name: 'account1', code: 'account1', role: 'user', num: 1 },
{ name: 'account2', code: 'account2', role: 'user', num: 1 },
{ name: 'account3', code: 'account3', role: 'user', num: 1 },
];
defineExpose({
openModal,
});
......
......@@ -32,7 +32,11 @@
</el-col>
<el-col :span="24">
<el-form-item class="w-full" label="还款总额:" prop="code">
<el-input v-model="form.totalRepayAmount" placeholder="请输入" />
<el-input
v-model="form.totalRepayAmount"
placeholder="请输入"
@change="changePeriod"
/>
</el-form-item>
</el-col>
<el-col :span="24">
......@@ -41,13 +45,14 @@
v-model="form.applyDate"
class="w-full"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
type="datetime"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item class="w-full" label="还款期数:" prop="name">
<el-select v-model="form.totalPeriod" placeholder="请选择">
<el-select v-model="form.totalPeriod" placeholder="请选择" @change="changePeriod">
<el-option
v-for="item in options"
:key="item.value"
......@@ -60,29 +65,33 @@
<el-col :span="24">
<el-form-item class="w-full" label="首期还款日:" prop="code">
<el-date-picker
@change="changePeriod"
class="w-full"
v-model="form.firstApplyDate"
format="YYYY-MM-DD HH:mm:ss"
type="datetime"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
type="date"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<!-- <el-col :span="24">
<el-form-item class="w-full" label="非首期还款日:" prop="code">
<el-date-picker
v-model="form.datetime"
class="w-full"
format="YYYY-MM-DD HH:mm:ss"
type="datetime"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
type="date"
/>
</el-form-item>
</el-col>
</el-col> -->
<el-col :span="24">
<el-form-item class="w-full" label="分期生效时间:" prop="code">
<el-date-picker
v-model="form.effectiveTime"
class="w-full"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
type="datetime"
/>
</el-form-item>
......@@ -93,13 +102,13 @@
<div class="w-3/5">
<ProTable :config="splitconfig" :data="splitdata" :showPagination="false">
<template #right_tools>
<el-button type="primary" @click="editFirst = !editFirst" class="mr-1">{{
<el-button type="primary" @click="editOrConfirm" class="mr-1">{{
editFirst ? '确定' : '修改'
}}</el-button>
</template>
</ProTable>
<div class="flex">
<div class="ml-auto text-gray-400">总计: xxxxx</div>
<div class="ml-auto text-gray-400">总计: {{ form.totalRepayAmount }}</div>
</div>
</div>
</div>
......@@ -116,8 +125,8 @@
import dayjs from 'dayjs';
import { computed } from 'vue';
import { reactive, ref } from 'vue';
import { ElInputNumber } from 'element-plus';
import { ElInputNumber, ElMessage } from 'element-plus';
import { savebyStages } from '@/api/property';
const showModal = ref(false);
const editFirst = ref(false);
const tabledata = ref([]);
......@@ -128,7 +137,7 @@
totalRepayAmount: 0,
totalPeriod: 2,
applyDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
firstApplyDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
firstApplyDate: dayjs().format('YYYY-MM-DD'),
effectiveTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
});
const currentDetail = ref({});
......@@ -136,28 +145,121 @@
currentDetail.value = {};
done();
};
const add = (a, b) => {
return (parseFloat(a) + parseFloat(b)).toFixed(2);
};
const minus = (a, b) => {
return (parseFloat(a) - parseFloat(b)).toFixed(2);
};
const multiply = (a, b) => {
return (parseFloat(a) * parseFloat(b)).toFixed(2);
};
const divide = (a, b) => {
return (parseFloat(a) / parseFloat(b)).toFixed(2);
};
const editOrConfirm = () => {
if (editFirst.value) {
if (!splitdata.value[0].applyAmount || isNaN(Number(splitdata.value[0].applyAmount)))
return ElMessage.warning({
message: '请重新确认数值',
plain: true,
});
const otherNum = form.totalRepayAmount - Number(splitdata.value[0].applyAmount);
const list = [splitdata.value[0]];
const crash = divide(Math.round(divide(otherNum, form.totalPeriod - 1) * 100), 100);
for (let i = 0; i < form.totalPeriod - 1; i++) {
console.log('i', i);
const playApplyDate = dayjs(form.firstApplyDate)
.add(i + 1, 'month')
.format('YYYY-MM-DD');
if (i === form.totalPeriod - 2) {
const other = list.reduce((pre, cur) => {
return add(pre, cur.applyAmount);
}, 0);
list.push({
period: i + 1,
playApplyDate: playApplyDate,
repayStatus: 'pending',
applyAmount: minus(form.totalRepayAmount, other),
});
} else {
list.push({
period: i + 1,
playApplyDate: playApplyDate,
repayStatus: 'pending',
applyAmount: crash,
});
}
}
splitdata.value = list;
}
editFirst.value = !editFirst.value;
};
const changePeriod = () => {
const list = [];
const crash = divide(Math.round(divide(form.totalRepayAmount, form.totalPeriod) * 100), 100);
for (let i = 0; i < form.totalPeriod; i++) {
console.log('i', i);
const playApplyDate = dayjs(form.firstApplyDate)
.add(i + 1, 'month')
.format('YYYY-MM-DD');
if (i === form.totalPeriod - 1) {
const other = list.reduce((pre, cur) => {
return add(pre, cur.applyAmount);
}, 0);
list.push({
period: i + 1,
playApplyDate: playApplyDate,
repayStatus: 'pending',
applyAmount: minus(form.totalRepayAmount, other),
});
} else {
list.push({
period: i + 1,
playApplyDate: playApplyDate,
repayStatus: 'pending',
applyAmount: crash,
});
}
}
splitdata.value = list;
};
const options = [
{
value: '2',
value: 2,
label: '2',
},
{
value: '3',
value: 3,
label: '3',
},
{
value: '4',
value: 4,
label: '4',
},
{
value: '5',
value: 5,
label: '5',
},
{
value: '6',
value: 6,
label: '6',
},
];
const repayStatusOpt = [
{
value: 'pending',
label: '待还款',
},
{
value: 'over',
label: '已还款',
},
];
const selectdList = ref([]);
const onCheckboxChange = (row) => {
selectdList.value = row.records;
......@@ -202,29 +304,40 @@
return {
minHeight: 200,
columns: [
{ type: 'seq', width: 50, title: '期次' },
{ field: 'period', width: 50, title: '期次' },
{
field: 'code',
field: 'playApplyDate',
title: '到期日',
},
{
field: 'code',
field: 'repayStatus',
title: '状态',
width: 70,
slots: {
default: ({ row, rowIndex }) => {
return (
<>
{row.repayStatus
? repayStatusOpt.find((v) => v.value === row.repayStatus).label
: ''}
</>
);
},
},
},
{
field: 'num',
field: 'applyAmount',
title: '金额',
slots: {
default: ({ row, rowIndex }) => {
if (editFirst.value && rowIndex === 0) {
return (
<>
<ElInputNumber v-model={row.num} />
<ElInputNumber v-model={row.applyAmount} />
</>
);
} else {
return <>{row.num}</>;
return <>{row.applyAmount}</>;
}
},
},
......@@ -233,20 +346,9 @@
onCheckboxChange: onCheckboxChange,
};
});
tabledata.value = [
{ name: 'admin', code: 'admin', role: 'superadmin', num: 1 },
{ name: 'account1', code: 'account1', role: 'user', num: 1 },
{ name: 'account2', code: 'account2', role: 'user', num: 1 },
{ name: 'account3', code: 'account3', role: 'user', num: 1 },
];
splitdata.value = [
{ name: 'admin', code: 'admin', role: 'superadmin', num: 1 },
{ name: 'account1', code: 'account1', role: 'user', num: 1 },
{ name: 'account2', code: 'account2', role: 'user', num: 1 },
{ name: 'account3', code: 'account3', role: 'user', num: 1 },
];
const openModal = (detail, caselist) => {
showModal.value = true;
editFirst.value = false;
currentDetail.value = detail;
console.log('currentDetail', currentDetail.value, caselist);
form.totalRepayAmount = 0;
......@@ -256,8 +358,34 @@
form.remainingAmount += Number(item.remainingAmount) || 0;
});
tabledata.value = caselist;
changePeriod();
};
const emits = defineEmits(['success']);
const submitForm = () => {
if (editFirst.value)
return ElMessage.warning({
message: '修改分期数值后要确认',
plain: true,
});
const params = {
...currentDetail.value,
...form,
byStagesRecords: splitdata.value,
loans: tabledata.value,
flowStatus: 'pending',
id: null,
};
savebyStages(params).then((res) => {
if (res.success) {
ElMessage.success({
message: '保存成功',
plain: true,
});
showModal.value = false;
emits('success');
}
});
};
const submitForm = () => {};
defineExpose({
openModal,
});
......
......@@ -176,6 +176,7 @@
<div class="w-2/3">
<ProTable
:config="splitConfig"
ref="splitRef"
:data="splitData"
:showPagination="false"
:showToolBar="false"
......@@ -204,10 +205,10 @@
</div>
</div>
<repairModal ref="repairModalRef"></repairModal>
<returnModal ref="returnModalRef"></returnModal>
<reduceDrawer ref="reduceDrawerRef"></reduceDrawer>
<splitDrawer ref="splitDrawerRef"></splitDrawer>
<callDrawer ref="callDrawerRef"></callDrawer>
<returnModal ref="returnModalRef" @success="query('还款')"></returnModal>
<reduceDrawer ref="reduceDrawerRef" @success="query('减免')"></reduceDrawer>
<splitDrawer ref="splitDrawerRef" @success="query('分期')"></splitDrawer>
<callDrawer ref="callDrawerRef" @success="query('跟进')"></callDrawer>
</div>
</template>
......@@ -238,6 +239,7 @@
guarantors: [],
},
});
const splitRef = ref();
const caseDetailRef = ref();
const returnModalRef = ref();
const repairModalRef = ref();
......@@ -454,8 +456,22 @@
],
toolbarConfig: { enabled: false },
});
const returnCrash = (row) => {
returnModalRef.value.openModal(JSON.parse(JSON.stringify(row)));
const returnCrash = (row, type) => {
if (type === '分期还款') {
const current = splitRef.value.element.getCurrentRecord();
console.log('current', current);
returnModalRef.value.openModal(
JSON.parse(JSON.stringify(row)),
JSON.parse(JSON.stringify(current)),
type
);
} else {
returnModalRef.value.openModal(
JSON.parse(JSON.stringify(row)),
JSON.parse(JSON.stringify(detail.value)),
type
);
}
};
const repair = () => {
repairModalRef.value.openModal(JSON.parse(JSON.stringify(detail.value)));
......@@ -510,7 +526,7 @@
default: ({ row, rowIndex }) => {
return (
<>
<ElButton type="primary" onClick={() => returnCrash(row)}>
<ElButton type="primary" onClick={() => returnCrash(row, '直接还款')}>
还款
</ElButton>
</>
......@@ -525,11 +541,14 @@
const onCellClick = ({ row, rowIndex }) => {
splitDeData.value = row.byStagesRecords;
};
const add = (a, b) => {
return (parseFloat(a) + parseFloat(b)).toFixed(2);
};
// 进行合计
const sumNum = (costForm, type) => {
let total = 0;
for (let i = 0; i < costForm.length; i++) {
total += costForm[i][type];
total = add(total, costForm[i][type]);
}
return total;
};
......@@ -628,8 +647,8 @@
<>
<ElButton
type="primary"
onClick={() => returnCrash(row)}
disabled={row.repayStatus !== 'over'}
onClick={() => returnCrash(row, '分期还款')}
disabled={row.repayStatus === 'over'}
>
还款
</ElButton>
......@@ -650,6 +669,7 @@
};
const onCellCase = ({ row, rowIndex }) => {
console.log('row.borrower.id', row);
getTrackRecordList(row.borrower.id);
};
const anchor = (type) => {
......@@ -718,7 +738,7 @@
default: ({ row, rowIndex }) => {
return (
<>
<ElButton type="primary" link onClick={() => returnCrash(row)}>
<ElButton type="primary" onClick={() => returnCrash(row, '结清减免还款')}>
还款
</ElButton>
</>
......@@ -729,6 +749,49 @@
],
toolbarConfig: { enabled: false },
});
const query = async (type) => {
const id = JSON.parse(route.query.id);
const { result } = await getCredit(id);
detail.value = result;
if (detail.value?.borrower?.id) {
if (type === '跟进') {
getTrackRecordList(detail.value?.borrower?.id);
} else if (type === '减免') {
getReduces(detail.value?.borrower?.id).then((res) => {
if (res.result && res.result) {
reduceData.value = res.result;
}
});
} else if (type === '分期') {
getByStages(detail.value?.borrower?.id).then((res) => {
if (res.result && res.result) {
splitData.value = res.result;
}
});
} else if (type === '还款') {
getRepayRecords(detail.value?.borrower?.id).then((res) => {
if (res.result && res.result) {
returnData.value = res.result;
}
});
getByStages(detail.value?.borrower?.id).then((res) => {
if (res.result && res.result) {
splitData.value = res.result;
}
});
getReduces(detail.value?.borrower?.id).then((res) => {
if (res.result && res.result) {
reduceData.value = res.result;
}
});
listByBorrower(detail.value?.borrower?.id).then((res) => {
if (res.result && res.result) {
caseDetailConfig.data = res.result;
}
});
}
}
};
onBeforeMount(async () => {
const id = JSON.parse(route.query.id);
const { result } = await getCredit(id);
......@@ -742,17 +805,17 @@
});
getReduces(detail.value?.borrower?.id).then((res) => {
if (res.result && res.result) {
reduceData.value.data = res.result;
reduceData.value = res.result;
}
});
getByStages(detail.value?.borrower?.id).then((res) => {
if (res.result && res.result) {
splitData.value.data = res.result;
splitData.value = res.result;
}
});
getRepayRecords(detail.value?.borrower?.id).then((res) => {
if (res.result && res.result) {
returnData.value.data = res.result;
returnData.value = res.result;
}
});
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment