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');
}
});
};
......
......@@ -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