yujialong 1 year ago
parent a9c89fcdd1
commit d038fbeb37
  1. 2
      src/api/bank.ts
  2. 1
      src/api/judgment.ts
  3. 2
      src/styles/form.scss
  4. 169
      src/views/product/Add.vue
  5. 2
      src/views/product/Approve.vue
  6. 98
      src/views/product/Config.vue
  7. 75
      src/views/product/Info.vue
  8. 27
      src/views/product/List.vue

@ -17,3 +17,5 @@ export const riskUpdate = async (data: Record<string, any>): Promise<any> => (aw
export const riskById = async (id: number): Promise<any> => (await axios.post(`/product/managerOfRiskControl/bankRiskControlAllocation/findById?id=${id}`)).data; export const riskById = async (id: number): Promise<any> => (await axios.post(`/product/managerOfRiskControl/bankRiskControlAllocation/findById?id=${id}`)).data;
export const examineAndApprove = async (id: number | string, opinionDescription: string, status: number, approvalTime: string): Promise<any> => export const examineAndApprove = async (id: number | string, opinionDescription: string, status: number, approvalTime: string): Promise<any> =>
(await axios.post(`/product/product/bank/products/examineAndApprove?id=${id}&opinionDescription=${opinionDescription}&status=${status}&approvalTime=${approvalTime}`)).data; (await axios.post(`/product/product/bank/products/examineAndApprove?id=${id}&opinionDescription=${opinionDescription}&status=${status}&approvalTime=${approvalTime}`)).data;
export const update = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/product/bank/products/update`, data)).data;

@ -4,5 +4,4 @@ export const imageUploadUrl = `${import.meta.env.VITE_BASE_API}/backend/image-up
export const getProcess = async (): Promise<any> => (await axios.post('/judgment/judgment/stRecord/getProcess?systemId=19')).data; export const getProcess = async (): Promise<any> => (await axios.post('/judgment/judgment/stRecord/getProcess?systemId=19')).data;
export const getProcessInformationBasedOnRoles = async (id: number): Promise<any> => export const getProcessInformationBasedOnRoles = async (id: number): Promise<any> =>
(await axios.post(`/judgment/judgment/stRecord/getProcessInformationBasedOnRoles?systemId=19&parentId=${id}`)).data; (await axios.post(`/judgment/judgment/stRecord/getProcessInformationBasedOnRoles?systemId=19&parentId=${id}`)).data;
export const getAllBusiness = async (): Promise<any> => (await axios.post('/judgment/judgment/stRecord/getAllBusiness?systemId=19')).data;
export const addOperation = async (data: Record<string, any>): Promise<any> => (await axios.post('/product/product/bank/operation/addOperation', data)).data; export const addOperation = async (data: Record<string, any>): Promise<any> => (await axios.post('/product/product/bank/operation/addOperation', data)).data;

@ -1,5 +1,5 @@
.form { .form {
@apply max-h-[calc(100vh-270px)] overflow-auto; @apply max-h-[calc(100vh-270px)] pr-2 overflow-auto;
.step { .step {
@apply relative pl-[42px]; @apply relative pl-[42px];
&:before { &:before {

@ -2,8 +2,22 @@
<div> <div>
<el-tabs v-model="curTab" <el-tabs v-model="curTab"
@tab-click="tabChange"> @tab-click="tabChange">
<el-tab-pane label="新增产品" <el-tab-pane :label="id ? '产品要素' : '新增产品'"
name="tab1"> name="tab1">
<div v-if="info"
class="audit">
<div class="line">
<span class="field">审批意见</span>
<span class="status">{{ getStatus(+info?.status) }}</span>
</div>
<div class="line">
<span class="field">意见描述</span>
{{ info.opinionDescription }}
</div>
<p class="mb-2 text-sm text-[#333] text-right">审查日期{{ info.approvalTime }}</p>
<p class="mb-2 text-sm text-[#333] text-right">审查员公瑾</p>
</div>
<el-form ref="formRef" <el-form ref="formRef"
:model="form" :model="form"
:rules="rules" :rules="rules"
@ -104,7 +118,19 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="贷款用途" <el-form-item label="贷款用途"
prop="loanPurpose"> prop="loanPurpose"
:rules="[
{ required: true, message: '请选择贷款用途', trigger: 'change' },
{
asyncValidator: async (rule, value, callback) => {
if (value === 107 && !form.otherPurposesOfLoan) {
callback('请输入其他贷款用途')
} else {
callback()
}
},
},
]">
<div class="flex-1"> <div class="flex-1">
<p class="field-name">选择本产品贷款资金的用途</p> <p class="field-name">选择本产品贷款资金的用途</p>
<el-radio-group v-model="form.loanPurpose"> <el-radio-group v-model="form.loanPurpose">
@ -120,14 +146,28 @@
</template> </template>
</el-radio-group> </el-radio-group>
<el-input v-if="form?.loanPurpose === 107" <el-input v-if="form?.loanPurpose === 107"
class="w-[250px] ml-5" class="w-[300px] ml-5"
placeholder="请描述其他贷款用途可用于哪些方面。" placeholder="请描述其他贷款用途可用于哪些方面。"
maxlength="10" maxlength="10"
v-model="form.otherPurposesOfLoan"></el-input> v-model="form.otherPurposesOfLoan"></el-input>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="担保方式" <el-form-item label="担保方式"
prop="bankGuaranteeTypeIds"> prop="bankGuaranteeTypeIds"
:rules="[
{ required: true, message: '请选择担保方式', trigger: 'change' },
{
asyncValidator: async (rule, value, callback) => {
if (value.includes(110) && !value.find((e: any) => e > 22 && e < 33)) {
callback('请选择抵押物')
} else if (value.includes(111) && !value.find((e: any) => e > 32 && e < 38)) {
callback('请选择质押贷')
} else {
callback()
}
},
},
]">
<div class="flex-1"> <div class="flex-1">
<p class="field-name">选择本产品的担保种类</p> <p class="field-name">选择本产品的担保种类</p>
<div v-for="(item, i) in config.find((e: any) => e.name === '担保方式')?.recordChildren" <div v-for="(item, i) in config.find((e: any) => e.name === '担保方式')?.recordChildren"
@ -144,7 +184,20 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="贷款额度" <el-form-item label="贷款额度"
prop="minimumLoan"> prop="minimumLoan"
:rules="[
{ required: true, message: '请输入贷款额度', trigger: 'blur' },
{
asyncValidator: async (rule, value, callback) => {
const max = form.loanCeiling
if (isNaN(value) || value < 0 || max === '' || isNaN(max) || max < 0 || value > max) {
callback('请输入合理的贷款额度')
} else {
callback()
}
},
},
]">
<div class="flex-1"> <div class="flex-1">
<div class="num-inputs"> <div class="num-inputs">
<el-input placeholder="最小额度" <el-input placeholder="最小额度"
@ -159,7 +212,20 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="贷款利率" <el-form-item label="贷款利率"
prop="minimumAprOnLoan"> prop="minimumAprOnLoan"
:rules="[
{ required: true, message: '请输入贷款利率', trigger: 'blur' },
{
asyncValidator: async (rule, value, callback) => {
const max = form.maximumAnnualInterestRate
if (isNaN(value) || value < 0 || max === '' || isNaN(max) || max < 0 || value > max) {
callback('请输入合理的贷款利率')
} else {
callback()
}
},
},
]">
<div class="flex-1"> <div class="flex-1">
<div class="num-inputs"> <div class="num-inputs">
<el-input placeholder="最小年利率" <el-input placeholder="最小年利率"
@ -174,7 +240,20 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="贷款期限" <el-form-item label="贷款期限"
prop="minimumTermOfLoan"> prop="minimumTermOfLoan"
:rules="[
{ required: true, message: '请输入贷款期限', trigger: 'blur' },
{
asyncValidator: async (rule, value, callback) => {
const max = form.maximumTermOfLoan
if (isNaN(value) || value < 0 || max === '' || isNaN(max) || max < 0 || value > max) {
callback('请输入合理的贷款期限')
} else {
callback()
}
},
},
]">
<div class="flex-1"> <div class="flex-1">
<div class="num-inputs"> <div class="num-inputs">
<el-input placeholder="最小期限" <el-input placeholder="最小期限"
@ -212,18 +291,25 @@
</div> </div>
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="id"
label="产品风控"
name="tab2">
<info />
</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, computed, onMounted, defineEmits } from 'vue'; import { ref, reactive, computed, watch, onMounted, defineEmits } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import type { TabsPaneContext, FormInstance, FormRules } from 'element-plus'; import type { TabsPaneContext, FormInstance, FormRules } from 'element-plus';
import { productElement, typeOfGuarantee, save } from '@/api/bank'; import { findById, save, update } from '@/api/bank';
import { getProcessInformationBasedOnRoles, addOperation } from '@/api/judgment'; import { getProcessInformationBasedOnRoles, addOperation } from '@/api/judgment';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import { handleId } from '@/utils/common'; import { handleId } from '@/utils/common';
import { getStatus } from '@/store/useProduct';
import Info from './Info.vue';
const emit = defineEmits(['getList']); const emit = defineEmits(['getList']);
interface RuleForm { interface RuleForm {
@ -254,8 +340,10 @@ interface RuleForm {
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const id = computed(() => route.query.id);
const curTab = ref<string>('tab1'); const curTab = ref<string>('tab1');
const config = ref<any[]>([]); const config = ref<any[]>([]);
const info = ref<Record<string, any>>(null);
const formRef = ref<FormInstance>(); const formRef = ref<FormInstance>();
const form = reactive<RuleForm>({ const form = reactive<RuleForm>({
productDefinition: '', productDefinition: '',
@ -286,11 +374,6 @@ const rules = reactive<FormRules<RuleForm>>({
productDefinition: [{ required: true, message: '请输入产品定义', trigger: 'blur' }], productDefinition: [{ required: true, message: '请输入产品定义', trigger: 'blur' }],
productName: [{ required: true, message: '请输入产品名称', trigger: 'blur' }], productName: [{ required: true, message: '请输入产品名称', trigger: 'blur' }],
productCurrency: [{ required: true, message: '请选择产品币种', trigger: 'change' }], productCurrency: [{ required: true, message: '请选择产品币种', trigger: 'change' }],
loanPurpose: [{ required: true, message: '请选择贷款用途', trigger: 'change' }],
bankGuaranteeTypeIds: [{ required: true, message: '请选择担保方式', trigger: 'change' }],
minimumLoan: [{ required: true, message: '请输入贷款额度', trigger: 'blur' }],
minimumAprOnLoan: [{ required: true, message: '请输入贷款利率', trigger: 'blur' }],
minimumTermOfLoan: [{ required: true, message: '请输入贷款期限', trigger: 'blur' }],
modeRepayment: [{ required: true, message: '请选择还款方式', trigger: 'change' }], modeRepayment: [{ required: true, message: '请选择还款方式', trigger: 'change' }],
}); });
@ -303,6 +386,25 @@ const getConfig = async () => {
const { process } = await getProcessInformationBasedOnRoles(form.productType === 1 ? 45 : 44); const { process } = await getProcessInformationBasedOnRoles(form.productType === 1 ? 45 : 44);
config.value = process; config.value = process;
}; };
//
const getDetail = async () => {
if (id.value) {
try {
const { data } = await findById(id.value);
info.value = data;
} finally {
}
}
};
watch(
() => route.query,
() => {
getDetail();
},
{
immediate: true,
},
);
// //
const submit = async (formEl: FormInstance | undefined) => { const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return; if (!formEl) return;
@ -310,6 +412,25 @@ const submit = async (formEl: FormInstance | undefined) => {
if (valid) { if (valid) {
try { try {
const param = JSON.parse(JSON.stringify(form)); const param = JSON.parse(JSON.stringify(form));
//
if (param.productType) {
if (!param.productObject) return ElMessage.error('请选择企业类型');
}
if ((!param.productType && param.age) || param.productType) {
if (!param.minimumAge) return ElMessage.error('请输入最小年龄');
if (!param.maximumAge) return ElMessage.error('请输入最大年龄');
if (param.minimumAge < 0 || param.minimumAge > 999 || param.maximumAge < 0 || param.maximumAge > 999) return ElMessage.error('请输入合理的年龄');
if (param.minimumAge > param.maximumAge) return ElMessage.error('最小年龄不得大于最大年龄');
}
//
if (!param.productType) {
if (param.edu && !param.educationalRequirements.length) return ElMessage.error('请选择学历要求');
if (param.curWL && !param.currentWorkingLife.length) return ElMessage.error('请选择工作年限');
if (param.curWL && !param.currentWorkingLife.length) return ElMessage.error('请选择工作年限');
}
param.currentWorkingLife = param.currentWorkingLife.join(); param.currentWorkingLife = param.currentWorkingLife.join();
param.educationalRequirements = param.educationalRequirements.join(); param.educationalRequirements = param.educationalRequirements.join();
param.modeRepayment = param.modeRepayment.join(); param.modeRepayment = param.modeRepayment.join();
@ -323,8 +444,15 @@ const submit = async (formEl: FormInstance | undefined) => {
pid: e > 22 && e < 33 ? 110 : e > 32 && e < 38 ? 111 : e, pid: e > 22 && e < 33 ? 110 : e > 32 && e < 38 ? 111 : e,
}); });
}); });
const { message } = await save(param); if (id.value) {
addRecord(param, message); param.id = id.value;
param.status = 295;
await update(param);
addRecord(param, id.value);
} else {
const { message } = await save(param);
addRecord(param, message);
}
ElMessage.success('提交成功!'); ElMessage.success('提交成功!');
emit('getList', 1); emit('getList', 1);
} finally { } finally {
@ -392,4 +520,13 @@ onMounted(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
@import url(../../styles/form.scss); @import url(../../styles/form.scss);
.audit {
@apply py-5 px-4 mb-[30px] bg-[#f9fafc] rounded-[10px];
.line {
@apply mb-[18px] text-sm leading-[1.6];
}
.field {
@apply text-sm font-semibold;
}
}
</style> </style>

@ -96,7 +96,7 @@ const submit = async (formEl: FormInstance | undefined) => {
if (valid) { if (valid) {
try { try {
const param = JSON.parse(JSON.stringify(form)); const param = JSON.parse(JSON.stringify(form));
param.approvalTime = dayjs(new Date()).format('YYYY年-MM月-DD日'); param.approvalTime = dayjs(new Date()).format('YYYY年-M月-D日');
// const { message } = await examineAndApprove(param); // const { message } = await examineAndApprove(param);
const { message } = await examineAndApprove(param.id, param.opinionDescription, param.status, param.approvalTime); const { message } = await examineAndApprove(param.id, param.opinionDescription, param.status, param.approvalTime);

@ -7,7 +7,6 @@
<el-form ref="formRef" <el-form ref="formRef"
:model="form" :model="form"
:rules="rules"
label-width="120px" label-width="120px"
label-suffix=":" label-suffix=":"
class="form" class="form"
@ -46,7 +45,7 @@
<el-checkbox-group v-model="form.borrowerMaterial"> <el-checkbox-group v-model="form.borrowerMaterial">
<el-checkbox :label="config[1]?.recordChildren[1]?.subject?.itemList[0].itemId">{{ config[1]?.recordChildren[1]?.subject?.itemList[0].options }}</el-checkbox> <el-checkbox :label="config[1]?.recordChildren[1]?.subject?.itemList[0].itemId">{{ config[1]?.recordChildren[1]?.subject?.itemList[0].options }}</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
<el-select v-show="(detail.productType && form.borrowerMaterial?.includes(165)) || (!detail.productType && form.borrowerMaterial?.includes(49))" <el-select v-show="(info.productType && form.borrowerMaterial?.includes(165)) || (!info.productType && form.borrowerMaterial?.includes(49))"
class="ml-5" class="ml-5"
v-model="form.borrowerMaterialSelect" v-model="form.borrowerMaterialSelect"
placeholder="请选择"> placeholder="请选择">
@ -63,7 +62,7 @@
</el-checkbox-group> </el-checkbox-group>
<!-- 企业 --> <!-- 企业 -->
<template v-if="detail.productType"> <template v-if="info.productType">
<p class="field-name mt-5">企业材料</p> <p class="field-name mt-5">企业材料</p>
<div> <div>
<el-checkbox-group v-model="form.enterpriseMaterial"> <el-checkbox-group v-model="form.enterpriseMaterial">
@ -172,11 +171,23 @@
</el-form-item> </el-form-item>
<el-form-item label="利率定价模型" <el-form-item label="利率定价模型"
label-width="130px" label-width="130px"
prop="interestRatePricingModelCheck"> prop="interestRatePricingModelCheck"
:rules="[
{ required: true, message: '请选择利率定价模型', trigger: 'change' },
{
asyncValidator: async (rule, value, callback) => {
if (value && !form.interestRatePricingModel) {
callback(`请选择${info.productType ? '企业' : '个人'}额度模型`)
} else {
callback()
}
},
},
]">
<div class="flex-1"> <div class="flex-1">
<div class="flex items-center mb-3"> <div class="flex items-center mb-3">
<el-checkbox v-model="form.interestRatePricingModelCheck" <el-checkbox v-model="form.interestRatePricingModelCheck"
:label="(detail.productType ? '企业' : '个人') + '额度模型'" /> :label="(info.productType ? '企业' : '个人') + '额度模型'" />
<el-select v-show="form.interestRatePricingModelCheck" <el-select v-show="form.interestRatePricingModelCheck"
class="ml-5" class="ml-5"
v-model="form.interestRatePricingModel" v-model="form.interestRatePricingModel"
@ -188,7 +199,7 @@
</el-select> </el-select>
</div> </div>
<el-checkbox v-model="form.individualInterestRateModel" <el-checkbox v-model="form.individualInterestRateModel"
:label="103">{{ detail.productType ? '企业' : '个人' }}利率模型</el-checkbox> :label="103">{{ info.productType ? '企业' : '个人' }}利率模型</el-checkbox>
</div> </div>
</el-form-item> </el-form-item>
</div> </div>
@ -244,8 +255,7 @@
<el-radio v-model="form.contractMaterials" <el-radio v-model="form.contractMaterials"
:label="117">抵押物所有权证明</el-radio> :label="117">抵押物所有权证明</el-radio>
</el-form-item> </el-form-item>
<el-form-item label="合同模板" <el-form-item label="合同模板">
prop="loanContractCheck">
<div class="flex-1"> <div class="flex-1">
<div class="flex items-center mb-3"> <div class="flex items-center mb-3">
<el-checkbox v-model="form.loanContractCheck" <el-checkbox v-model="form.loanContractCheck"
@ -307,7 +317,7 @@
<el-form-item label="选择策略" <el-form-item label="选择策略"
prop="selectionStrategy"> prop="selectionStrategy">
<el-checkbox-group v-model="form.selectionStrategy"> <el-checkbox-group v-model="form.selectionStrategy">
<el-checkbox v-for="(item, i) in detail.productType ? config[7]?.recordChildren[0]?.subject?.itemList : config[7]?.subject?.itemList" <el-checkbox v-for="(item, i) in info.productType ? config[7]?.recordChildren[0]?.subject?.itemList : config[7]?.subject?.itemList"
:key="i" :key="i"
:label="item.itemId">{{ item.options }}</el-checkbox> :label="item.itemId">{{ item.options }}</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
@ -332,8 +342,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, computed, watch, onMounted } from 'vue'; import { ref, reactive, computed, watch, onMounted } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import type { TabsPaneContext, FormInstance, FormRules } from 'element-plus'; import type { TabsPaneContext, FormInstance } from 'element-plus';
import { findById, riskSave } from '@/api/bank'; import { findById, riskSave, riskUpdate } from '@/api/bank';
import { getProcessInformationBasedOnRoles, addOperation } from '@/api/judgment'; import { getProcessInformationBasedOnRoles, addOperation } from '@/api/judgment';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import { handleId } from '@/utils/common'; import { handleId } from '@/utils/common';
@ -385,7 +395,7 @@ const route = useRoute();
const id = computed(() => +route.query.id); const id = computed(() => +route.query.id);
const curTab = ref<string>('tab1'); const curTab = ref<string>('tab1');
const config = ref<any[]>([]); const config = ref<any[]>([]);
const detail = ref<Record<string, any>>({}); const info = ref<Record<string, any>>({});
const formRef = ref<FormInstance>(); const formRef = ref<FormInstance>();
const form = reactive<RuleForm>({ const form = reactive<RuleForm>({
accessStrategy: [], accessStrategy: [],
@ -426,29 +436,6 @@ const form = reactive<RuleForm>({
sendingAccount: '', sendingAccount: '',
supplementaryMaterials: [], supplementaryMaterials: [],
}); });
const rules = reactive<FormRules<RuleForm>>({
accountMaterials: [{ required: true, message: '请选择提供材料', trigger: 'change' }],
sendingAccount: [{ required: true, message: '请选择发放账户', trigger: 'change' }],
loanApplicationMethod: [{ required: true, message: '请选择申请方式', trigger: 'change' }],
borrowerMaterial: [{ required: true, message: '请选择借款人材料', trigger: 'change' }],
mateMaterial: [{ required: true, message: '请选择配偶材料', trigger: 'change' }],
businessMaterials: [{ required: true, message: '请选择经营类材料', trigger: 'change' }],
supplementaryMaterials: [{ required: true, message: '请选择补充材料', trigger: 'change' }],
runBatchObject: [{ required: true, message: '请选择跑批对象', trigger: 'change' }],
accessStrategy: [{ required: true, message: '请选择准入策略', trigger: 'change' }],
personalCreditScoringStrategiesCheck: [{ required: true, message: '请选择信用评分策略', trigger: 'change' }],
riskDegreeStrategy: [{ required: true, message: '请选择风险度策略', trigger: 'change' }],
interestRatePricingModelCheck: [{ required: true, message: '请选择利率定价模型', trigger: 'change' }],
dueDiligenceMode: [{ required: true, message: '请选择尽调方式', trigger: 'change' }],
dueDiligenceContent: [{ required: true, message: '请选择尽调内容', trigger: 'change' }],
reviewContent: [{ required: true, message: '请选择审查内容', trigger: 'change' }],
reviewSignature: [{ required: true, message: '请选择审查签字', trigger: 'change' }],
reviewApproveContent: [{ required: true, message: '请选择审批内容', trigger: 'change' }],
approvalSignature: [{ required: true, message: '请选择审批签字', trigger: 'change' }],
contractMaterials: [{ required: true, message: '请选择提供的材料', trigger: 'change' }],
loanContractCheck: [{ required: true, message: '请选择合同模板', trigger: 'change' }],
selectionStrategy: [{ required: true, message: '请选择选择策略', trigger: 'change' }],
});
// tab // tab
const tabChange = (tab: TabsPaneContext, event: Event) => { const tabChange = (tab: TabsPaneContext, event: Event) => {
@ -456,7 +443,7 @@ const tabChange = (tab: TabsPaneContext, event: Event) => {
}; };
// //
const getConfig = async () => { const getConfig = async () => {
const { process } = await getProcessInformationBasedOnRoles(detail.value.productType ? 71 : 70); // 7071 const { process } = await getProcessInformationBasedOnRoles(info.value.productType ? 71 : 70); // 7071
config.value = process; config.value = process;
}; };
// //
@ -464,7 +451,7 @@ const getDetail = async () => {
if (id.value) { if (id.value) {
try { try {
const { data } = await findById(id.value); const { data } = await findById(id.value);
detail.value = data; info.value = data;
getConfig(); getConfig();
} finally { } finally {
} }
@ -486,21 +473,33 @@ const submit = async (formEl: FormInstance | undefined) => {
await formEl.validate(async (valid, fields) => { await formEl.validate(async (valid, fields) => {
if (valid) { if (valid) {
try { try {
const isEnterprise = detail.value.productType === 1; const isEnterprise = info.value.productType === 1;
const param = JSON.parse(JSON.stringify(form)); const param = JSON.parse(JSON.stringify(form));
if (((isEnterprise && param.borrowerMaterial?.includes(165)) || (!isEnterprise && param.borrowerMaterial?.includes(49))) && !param.borrowerMaterialSelect)
return ElMessage.error('请选择借款申请表');
if (
(param.personalCreditScoringStrategiesCheck && !param.personalCreditScoringStrategies) ||
(param.corporateCreditScoringStrategiesCheck && !param.corporateCreditScoringStrategies)
)
return ElMessage.error('请选择信用评分策略');
if (param.loanContractCheck && !param.loanContract) return ElMessage.error('请选择借贷合同');
if (param.mortgageContractCheck && !param.mortgageContract) return ElMessage.error('请选择抵押合同');
if (param.pledgeContractCheck && !param.pledgeContract) return ElMessage.error('请选择质押合同');
if (param.guaranteeContractCheck && !param.guaranteeContract) return ElMessage.error('请选择担保合同');
param.accessStrategy = param.accessStrategy.join(); param.accessStrategy = param.accessStrategy.join();
if ((isEnterprise && param.borrowerMaterial?.includes(165)) || (!isEnterprise && param.borrowerMaterial?.includes(49))) if ((isEnterprise && param.borrowerMaterial?.includes(165)) || (!isEnterprise && param.borrowerMaterial?.includes(49)))
param.borrowerMaterial.splice(1, 0, param.borrowerMaterialSelect); param.borrowerMaterial.splice(1, 0, param.borrowerMaterialSelect);
param.borrowerMaterial = param.borrowerMaterial.join(); param.borrowerMaterial = param.borrowerMaterial.join();
param.accountMaterials = param.accountMaterials.join(); param.accountMaterials = param.accountMaterials.join();
if (param.approvalSignature.length) param.approvalSignature = param.approvalSignature[0]; param.approvalSignature = param.approvalSignature[0];
// //
// if (isEnterprise) { // if (isEnterprise) {
param.collateral = param.collateral.join(); param.collateral = param.collateral.join();
param.enterpriseMaterial = param.enterpriseMaterial.join(); param.enterpriseMaterial = param.enterpriseMaterial.join();
param.corporateInterestRateModel = param.corporateInterestRateModel.join(); param.corporateInterestRateModel = param.corporateInterestRateModel.join();
param.materialsForLoanApproval = param.materialsForLoanApproval.join(); param.materialsForLoanApproval = param.materialsForLoanApproval.join();
// corporateInterestRateModel,materialsForLoanApproval
// } else { // } else {
// //
param.businessMaterials = param.businessMaterials.join(); param.businessMaterials = param.businessMaterials.join();
@ -516,19 +515,26 @@ const submit = async (formEl: FormInstance | undefined) => {
if (!param.pledgeContractCheck) param.pledgeContract = ''; if (!param.pledgeContractCheck) param.pledgeContract = '';
if (!param.guaranteeContractCheck) param.guaranteeContract = ''; if (!param.guaranteeContractCheck) param.guaranteeContract = '';
if (param.contractMaterials.length) param.contractMaterials = param.contractMaterials[0]; param.contractMaterials = param.contractMaterials[0];
param.dueDiligenceContent = param.dueDiligenceContent.join(); param.dueDiligenceContent = param.dueDiligenceContent.join();
param.loanApplicationMethod = param.loanApplicationMethod.join(); param.loanApplicationMethod = param.loanApplicationMethod.join();
if (param.reviewApproveContent.length) param.reviewApproveContent = param.reviewApproveContent[0]; param.reviewApproveContent = param.reviewApproveContent[0];
// if (param.reviewContent) param.reviewContent = 114; // if (param.reviewContent) param.reviewContent = 114;
if (param.reviewSignature.length) param.reviewSignature = param.reviewSignature[0]; param.reviewSignature = param.reviewSignature[0] || '';
param.riskDegreeStrategy = param.riskDegreeStrategy.join(); param.riskDegreeStrategy = param.riskDegreeStrategy.join();
param.runBatchObject = param.runBatchObject.join(); param.runBatchObject = param.runBatchObject.join();
param.selectionStrategy = param.selectionStrategy.join(); param.selectionStrategy = param.selectionStrategy.join();
param.supplementaryMaterials = param.supplementaryMaterials.join(); param.supplementaryMaterials = param.supplementaryMaterials.join();
const { message } = await riskSave(param); if (info.value.riskControlDetails) {
addRecord(param, message); param.id = info.value.riskControlDetails.id;
await riskUpdate(param);
addRecord(param, id.value);
} else {
const { message } = await riskSave(param);
addRecord(param, message);
}
ElMessage.success('提交成功!'); ElMessage.success('提交成功!');
emit('getList', 1); emit('getList', 1);
} finally { } finally {
@ -540,7 +546,7 @@ const submit = async (formEl: FormInstance | undefined) => {
}; };
// //
const addRecord = async (data: Record<string, any>, newId: number) => { const addRecord = async (data: Record<string, any>, newId: number) => {
const isEnterprise = detail.value.productType === 1; const isEnterprise = info.value.productType === 1;
const preIds = `1,2,42,${data.productType ? 71 : 70},${newId}`; // 1id/70/71 const preIds = `1,2,42,${data.productType ? 71 : 70},${newId}`; // 1id/70/71
const lcRule = <Record<string, any>[]>[]; const lcRule = <Record<string, any>[]>[];

@ -47,8 +47,66 @@
<p v-if="info.providentFundAndSocialSecurity">连续缴纳本市社保或者公积金6个月</p> <p v-if="info.providentFundAndSocialSecurity">连续缴纳本市社保或者公积金6个月</p>
<p>持有中国银行I类账户且已关联至手机银行且在我行及其他金融同业无不良信用记录</p> <p>持有中国银行I类账户且已关联至手机银行且在我行及其他金融同业无不良信用记录</p>
</div> </div>
<template v-if="role == 43"> <template v-if="riskInfo">
<h6 class="step-name mt-5">材料要求</h6> <h6 class="step-name mt-5">材料要求</h6>
<p class="text">办理账户-提供材料{{ riskInfo?.accountMaterials }}</p>
<p v-if="riskInfo?.sendingAccount"
class="text">办理账户-发放账户借记卡或放款专户</p>
<p v-if="riskInfo?.loanApplicationMethod"
class="text">贷款申请-申请方式{{ riskInfo?.loanApplicationMethod }}</p>
<p v-if="riskInfo?.borrowerMaterial"
class="text">贷款申请-提供材料-借款人材料{{ riskInfo?.borrowerMaterial }}</p>
<template v-if="info.productType">
<p v-if="riskInfo?.enterpriseMaterial"
class="text">贷款申请-提供材料-企业材料{{ riskInfo?.enterpriseMaterial }}</p>
<p v-if="riskInfo?.collateral"
class="text">贷款申请-提供材料-抵押物{{ riskInfo?.collateral }}</p>
</template>
<template v-else>
<p v-if="riskInfo?.mateMaterial"
class="text">贷款申请-提供材料-配偶材料{{ riskInfo?.mateMaterial }}</p>
<p v-if="riskInfo?.businessMaterials"
class="text">贷款申请-提供材料-经营类材料{{ riskInfo?.businessMaterials }}</p>
</template>
<p v-if="riskInfo?.supplementaryMaterials"
class="text">贷款申请-提供材料-补充材料{{ riskInfo?.supplementaryMaterials }}</p>
<p v-if="riskInfo?.runBatchObject"
class="text">系统跑批准入风控策略-跑批对象{{ riskInfo?.runBatchObject }}</p>
<p v-if="riskInfo?.accessStrategy"
class="text">系统跑批准入风控策略-准入策略{{ riskInfo?.accessStrategy }}</p>
<p v-if="riskInfo?.personalCreditScoringStrategies"
class="text">系统跑批准入风控策略-信用评分策略{{ riskInfo?.personalCreditScoringStrategies }}</p>
<p v-if="riskInfo?.riskDegreeStrategy"
class="text">系统跑批准入风控策略-风险度策略{{ riskInfo?.riskDegreeStrategy }}</p>
<p v-if="riskInfo?.interestRatePricingModel"
class="text">系统跑批准入风控策略-利率定价模型-个人额度模型{{ riskInfo?.interestRatePricingModel }}</p>
<p v-if="riskInfo?.individualInterestRateModel"
class="text">系统跑批准入风控策略-利率定价模型-个人利率模型</p>
<p v-if="riskInfo?.dueDiligenceMode"
class="text">尽职调查-尽调方式{{ riskInfo?.dueDiligenceMode }}</p>
<p v-if="riskInfo?.dueDiligenceContent"
class="text">尽职调查-尽调内容{{ riskInfo?.dueDiligenceContent }}</p>
<p v-if="riskInfo?.reviewContent"
class="text">贷款审查-审查内容{{ riskInfo?.reviewContent }}</p>
<p v-if="riskInfo?.reviewSignature"
class="text">贷款审查-审查签字{{ riskInfo?.reviewSignature }}</p>
<p v-if="riskInfo?.reviewApproveContent"
class="text">贷款审批-审批内容{{ riskInfo?.reviewApproveContent }}</p>
<p v-if="riskInfo?.approvalSignature"
class="text">贷款审批-审批签字{{ riskInfo?.approvalSignature }}</p>
<p v-if="riskInfo?.contractMaterials"
class="text">签订合同-提供的材料{{ riskInfo?.contractMaterials }}</p>
<p v-if="riskInfo?.loanContract"
class="text">签订合同-合同模板-借贷合同{{ riskInfo?.loanContract }}</p>
<p v-if="riskInfo?.mortgageContract"
class="text">签订合同-合同模板-抵押合同{{ riskInfo?.mortgageContract }}</p>
<p v-if="riskInfo?.pledgeContract"
class="text">签订合同-合同模板-质押合同{{ riskInfo?.pledgeContract }}</p>
<p v-if="riskInfo?.guaranteeContract"
class="text">签订合同-合同模板-担保合同{{ riskInfo?.guaranteeContract }}</p>
<p v-if="riskInfo?.selectionStrategy"
class="text">贷后管理-选择策略{{ riskInfo?.selectionStrategy }}</p>
<h6 class="step-name mt-5">业务流程</h6> <h6 class="step-name mt-5">业务流程</h6>
<p class="text">1贷款人APP向智信银行公司业务部门提交借款申请同时提交贷款用途证明文件以及有关资料</p> <p class="text">1贷款人APP向智信银行公司业务部门提交借款申请同时提交贷款用途证明文件以及有关资料</p>
<p class="text">2智信银行对贷款人的贷款申请进行审查同时根据实际情况要求借款人提供补充资料</p> <p class="text">2智信银行对贷款人的贷款申请进行审查同时根据实际情况要求借款人提供补充资料</p>
@ -70,7 +128,6 @@ import { getStatus } from '@/store/useProduct';
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const role = computed(() => route.query.role || 41); // 123
const id = computed(() => +route.query.id); const id = computed(() => +route.query.id);
const info = ref<Record<string, any>>({}); const info = ref<Record<string, any>>({});
const riskInfo = ref<Record<string, any>>(null); const riskInfo = ref<Record<string, any>>(null);
@ -81,7 +138,7 @@ const getDetail = async () => {
try { try {
const { data } = await findById(id.value); const { data } = await findById(id.value);
info.value = data; info.value = data;
if (info.value.riskControlDetails) riskInfo.value = info.value.riskControlDetails; if (info.value.riskControlDetails) riskInfo.value = data.riskControlDetails;
} finally { } finally {
} }
} }
@ -113,18 +170,12 @@ watch(
} }
} }
.audit { .audit {
padding: 20px 16px; @apply py-5 px-4 mb-[30px] bg-[#f9fafc] rounded-[10px];
margin-bottom: 30px;
background: #f9fafc;
border-radius: 10px;
.line { .line {
margin-bottom: 18px; @apply mb-[18px] text-sm leading-[1.6];
font-size: 14px;
line-height: 1.6;
} }
.field { .field {
font-size: 14px; @apply text-sm font-semibold;
font-weight: 600;
} }
} }
</style> </style>

@ -88,12 +88,15 @@
<el-table-column prop="id" <el-table-column prop="id"
label="操作"> label="操作">
<template #default="{ row }"> <template #default="{ row }">
<template v-if="params.roleId != 43"> <el-button v-if="row.showElementsOrNot"
<el-button type="text" type="text"
size="small" size="small"
@click="toDetail(`/product/cardList/config`, row.id)">配置{{ params.roleId == 41 ? '要素' : '风控' }}</el-button> @click="toDetail(`/product/cardList/add`, row.id)">配置要素</el-button>
</template> <el-button v-if="row.showRiskControlOrNot"
<el-popconfirm v-if="params.roleId == 41" type="text"
size="small"
@click="toDetail(`/product/cardList/config`, row.id)">配置风控</el-button>
<el-popconfirm v-if="row.showDeleteOrNot"
title="您确定删除吗?" title="您确定删除吗?"
@confirm.stop="handleDelete(row.id)"> @confirm.stop="handleDelete(row.id)">
<template #reference> <template #reference>
@ -102,17 +105,11 @@
@click.stop="stop">删除</el-button> @click.stop="stop">删除</el-button>
</template> </template>
</el-popconfirm> </el-popconfirm>
<!-- 专家委员会 && 非待审批 展示审批结果 --> <el-button v-if="row.showDetailsOrNot"
<el-button v-if="params.roleId == 43 && row.status != 296"
type="text"
@click="toDetail(`/product/cardList/detail`, row.id)"
size="small">审批结果</el-button>
<!-- 产品经理 || 风控经理 && 非审批打回 展示产品详情 -->
<el-button v-if="params.roleId != 43 && row.status != 299"
type="text" type="text"
@click="toDetail(`/product/cardList/detail`, row.id)" @click="toDetail(`/product/cardList/detail`, row.id)"
size="small">产品详情</el-button> size="small">{{ params.roleId == 43 ? '审批结果' : '产品详情' }}</el-button>
<el-button v-if="params.roleId == 43 && row.status == 296" <el-button v-if="row.showApprovalOrNot"
type="text" type="text"
size="small" size="small"
@click="toDetail(`/product/cardList/approve`, row.id)">审批</el-button> @click="toDetail(`/product/cardList/approve`, row.id)">审批</el-button>

Loading…
Cancel
Save