新增产品和新增记录

V0.1
yujialong 1 year ago
parent cbb444ad55
commit f69fdd1a8a
  1. 5
      src/api/bank.ts
  2. 2
      src/api/judgment.ts
  3. 19
      src/utils/common.ts
  4. 207
      src/views/product/Add.vue
  5. 16
      src/views/product/CardList.vue
  6. 40
      src/views/product/Detail.vue
  7. 20
      src/views/product/List.vue

@ -7,8 +7,9 @@ export const updateStorage = async (data: Record<string, any>): Promise<any> =>
export const primaryTypeOfGuarantee = async (): Promise<any> => (await axios.post('/product/bankGuaranteeType/primaryTypeOfGuarantee')).data;
export const typeOfGuarantee = async (): Promise<any> => (await axios.post('/product/bankGuaranteeType/typeOfGuarantee')).data;
export const bankingProductsList = async (data: Record<string, any>): Promise<any> => (await axios.post('/product/product/bank/products/bankingProductsList', data)).data;
export const batchDeletion = async (data: Record<string, any>): Promise<any> => (await axios.post('/product/product/bank/products/batchDeletion', data)).data;
export const batchDeletion = async (ids: number[]): Promise<any> => (await axios.post('/product/product/bank/products/batchDeletion', ids)).data;
export const personalRiskControlConfigurationField = async (): Promise<any> =>
(await axios.post('/product/riskControlConfigurationField/personalRiskControlConfigurationField')).data;
export const productElement = async (data: Record<string, any>): Promise<any> => (await axios.post('/product/product/bank/products/productElement', data)).data;
export const productElement = async (id: number): Promise<any> => (await axios.post(`/product/product/bank/products/productElement?id=${id}`)).data;
export const findById = async (id: number): Promise<any> => (await axios.post(`/product/product/bank/products/findById?id=${id}`)).data;
export const save = async (data: Record<string, any>): Promise<any> => (await axios.post(`/product/product/bank/products/save`, data)).data;

@ -1,8 +1,8 @@
import axios from '@/utils/request';
export const imageUploadUrl = `${import.meta.env.VITE_BASE_API}/backend/image-upload`;
export const cropImage = async (data: Record<string, any>): Promise<any> => (await axios.post('/backend/image-crop', data)).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> =>
(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;

@ -113,3 +113,22 @@ export const moveList = (selected: any[], list: any[], type: 'top' | 'up' | 'dow
}
return list;
};
/**
* lcJudgmentRuleReq
*/
export const handleId = (
answerId: number | string,
emptyOne: number | string,
emptyTwo: number | string,
operationIds: number | string,
type: number | string,
): Record<string, any> => {
return {
answerId,
emptyOne,
emptyTwo,
operationIds,
type,
};
};

@ -1,127 +1,180 @@
<template>
<div>
<el-tabs v-model="curTab" @tab-click="tabChange">
<el-tab-pane label="新增产品" name="tab1">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" label-suffix="" class="form" status-icon>
<el-form-item label="产品定义" prop="productDefinition">
<el-input
type="textarea"
<el-tabs v-model="curTab"
@tab-click="tabChange">
<el-tab-pane label="新增产品"
name="tab1">
<el-form ref="formRef"
:model="form"
:rules="rules"
label-width="100px"
label-suffix=":"
class="form"
status-icon>
<el-form-item label="产品定义"
prop="productDefinition">
<el-input type="textarea"
placeholder="用一段话简单介绍一下这个产品或者描述产品的设计理念。例如:本产品根据个人客户的信用状况,为其提供的一种短期融资便利产品,借款人可在额度金额内可循环周转使用贷款。"
maxlength="200"
></el-input>
v-model="form.productDefinition"></el-input>
</el-form-item>
<el-form-item label="产品名称" prop="productName">
<el-input placeholder="取个有吸引力的产品名,限20字。" maxlength="20"></el-input>
<el-form-item label="产品名称"
prop="productName">
<el-input placeholder="取个有吸引力的产品名,限20字。"
maxlength="20"
v-model="form.productName"></el-input>
</el-form-item>
<el-form-item label="产品币种" prop="productCurrency">
<el-select v-model="form.productCurrency" placeholder="请选择">
<el-option label="人民币" :value="1" />
<el-form-item label="产品币种"
prop="productCurrency">
<el-select v-model="form.productCurrency"
placeholder="请选择">
<el-option label="人民币"
:value="1" />
</el-select>
</el-form-item>
<el-form-item label="贷款对象" required>
<el-form-item label="贷款对象"
required>
<div class="flex-1">
<p class="field-name">选择本产品的贷款对象</p>
<div class="flex items-center mb-2">
<el-checkbox-group class="mt-1" v-model="form.age">
<el-checkbox-group class="mt-1"
v-model="form.age">
<el-checkbox label="年龄" />
</el-checkbox-group>
<div class="num-inputs ml-7">
<el-input placeholder="最小年龄" v-model.number="form.minimumAge"></el-input>
<el-input placeholder="最小年龄"
v-model.number="form.minimumAge"></el-input>
<span class="split">-</span>
<el-input placeholder="最大年龄" v-model.number="form.maximumAge"></el-input>
<el-input placeholder="最大年龄"
v-model.number="form.maximumAge"></el-input>
</div>
</div>
<div class="flex items-center mb-2">
<el-checkbox v-model="form.edu" label="学历要求"></el-checkbox>
<el-checkbox-group v-if="form.edu" class="mt-2 ml-5" v-model="form.educationalRequirements">
<el-checkbox v-for="(item, i) in config[3]?.subject?.itemList?.slice(2, 6)" :key="i" :label="i + 1">{{ item.options }}</el-checkbox>
<el-checkbox v-model="form.edu"
label="学历要求"></el-checkbox>
<el-checkbox-group v-if="form.edu"
class="mt-2 ml-5"
v-model="form.educationalRequirements">
<el-checkbox v-for="(item, i) in config[3]?.subject?.itemList?.slice(2, 6)"
:key="i"
:label="item.itemId">{{ item.options }}</el-checkbox>
</el-checkbox-group>
</div>
<div class="flex items-center mb-2">
<el-checkbox v-model="form.curWL" label="工作年限"></el-checkbox>
<el-checkbox-group v-if="form.curWL" class="mt-2 ml-5" v-model="form.currentWorkingLife">
<el-checkbox v-for="(item, i) in config[3]?.subject?.itemList?.slice(7, 11)" :key="i" :label="i + 1">{{ item.options }}</el-checkbox>
<el-checkbox v-model="form.curWL"
label="工作年限"></el-checkbox>
<el-checkbox-group v-if="form.curWL"
class="mt-2 ml-5"
v-model="form.currentWorkingLife">
<el-checkbox v-for="(item, i) in config[3]?.subject?.itemList?.slice(7, 11)"
:key="i"
:label="item.itemId">{{ item.options }}</el-checkbox>
</el-checkbox-group>
</div>
<el-checkbox v-model="form.providentFundAndSocialSecurity" label="公积金/社保" :true-label="1" :false-label="2"></el-checkbox>
<el-checkbox v-model="form.providentFundAndSocialSecurity"
label="公积金/社保"></el-checkbox>
</div>
</el-form-item>
<el-form-item label="贷款用途" prop="loanPurpose">
<el-form-item label="贷款用途"
prop="loanPurpose">
<div class="flex-1">
<p class="field-name">选择本产品贷款资金的用途</p>
<el-radio-group v-model="form.loanPurpose">
<el-radio v-for="(item, i) in config[4]?.subject?.itemList" :key="i" :label="item.itemId">{{ item.options }}</el-radio>
<el-radio v-for="(item, i) in config[4]?.subject?.itemList"
:key="i"
:label="item.itemId">{{ item.options }}</el-radio>
<el-radio :label="4">其他</el-radio>
</el-radio-group>
<el-input
v-if="form?.loanPurpose === 4"
<el-input v-if="form?.loanPurpose === 4"
class="w-[250px] ml-5"
placeholder="请描述其他贷款用途可用于哪些方面。"
maxlength="10"
v-model="form.otherPurposesOfLoan"
></el-input>
v-model="form.otherPurposesOfLoan"></el-input>
</div>
</el-form-item>
<el-form-item label="担保方式" prop="bankGuaranteeTypeIds">
<el-form-item label="担保方式"
prop="bankGuaranteeTypeIds">
<div class="flex-1">
<p class="field-name">选择本产品的担保种类</p>
<div v-for="(item, i) in guaranteees" :key="i" class="mb-2">
<div v-for="(item, i) in guaranteees"
:key="i"
class="mb-2">
<el-checkbox-group v-model="form.bankGuaranteeTypeIds">
<el-checkbox :label="item.id">{{ item.guarantyStyle }}</el-checkbox>
<el-checkbox v-for="(child, j) in item?.children" :key="j" :label="child.id">{{ child.guarantyStyle }}</el-checkbox>
<el-checkbox v-for="(child, j) in item?.children"
:key="j"
:label="child.id">{{ child.guarantyStyle }}</el-checkbox>
</el-checkbox-group>
</div>
</div>
</el-form-item>
<el-form-item label="贷款额度" prop="minimumLoan">
<el-form-item label="贷款额度"
prop="minimumLoan">
<div class="flex-1">
<div class="num-inputs">
<el-input placeholder="最小额度" min="0" v-model.number="form.minimumLoan"></el-input>
<el-input placeholder="最小额度"
min="0"
v-model.number="form.minimumLoan"></el-input>
<span class="split">-</span>
<el-input placeholder="最高额度" min="0" v-model.number="form.loanCeiling"></el-input>
<el-input placeholder="最高额度"
min="0"
v-model.number="form.loanCeiling"></el-input>
<span class="unit">万元</span>
</div>
</div>
</el-form-item>
<el-form-item label="贷款利率" prop="minimumAprOnLoan">
<el-form-item label="贷款利率"
prop="minimumAprOnLoan">
<div class="flex-1">
<div class="num-inputs">
<el-input placeholder="最小年利率" min="0" v-model.number="form.minimumAprOnLoan"></el-input>
<el-input placeholder="最小年利率"
min="0"
v-model.number="form.minimumAprOnLoan"></el-input>
<span class="split">-</span>
<el-input placeholder="最高年利率" min="0" v-model.number="form.maximumAnnualInterestRate"></el-input>
<el-input placeholder="最高年利率"
min="0"
v-model.number="form.maximumAnnualInterestRate"></el-input>
<span class="unit">%</span>
</div>
</div>
</el-form-item>
<el-form-item label="贷款期限" prop="minimumTermOfLoan">
<el-form-item label="贷款期限"
prop="minimumTermOfLoan">
<div class="flex-1">
<div class="num-inputs">
<el-input placeholder="最小期限" min="0" v-model.number="form.minimumTermOfLoan"></el-input>
<el-input placeholder="最小期限"
min="0"
v-model.number="form.minimumTermOfLoan"></el-input>
<span class="split">-</span>
<el-input placeholder="最大期限" min="0" v-model.number="form.maximumTermOfLoan"></el-input>
<el-input placeholder="最大期限"
min="0"
v-model.number="form.maximumTermOfLoan"></el-input>
<span class="unit"></span>
</div>
</div>
</el-form-item>
<el-form-item label="还款方式" prop="modeRepayment">
<el-form-item label="还款方式"
prop="modeRepayment">
<div class="flex-1">
<p class="field-name">选择本产品可以选择的还款方式</p>
<el-checkbox-group v-model="form.modeRepayment">
<el-checkbox :label="1">等额本息</el-checkbox>
<el-checkbox :label="2">先息后本</el-checkbox>
<el-checkbox :label="3">等额本金</el-checkbox>
<el-checkbox v-for="(item, i) in config[9]?.subject?.itemList"
:key="i"
:label="item.itemId">{{ item.options }}</el-checkbox>
</el-checkbox-group>
</div>
</el-form-item>
<el-form-item label="提前还款" prop="whetherToSupportEarlyRepayment">
<el-form-item label="提前还款"
prop="whetherToSupportEarlyRepayment">
<div class="flex-1 flex items-center">
<el-switch :active-value="1" :inactive-value="2" v-model="form.whetherToSupportEarlyRepayment" />
<el-switch v-model="form.whetherToSupportEarlyRepayment" />
<p class="tips ml-4">本产品是否支持提前还款</p>
</div>
</el-form-item>
<div class="flex justify-end">
<div class="submit" @click="submit(formRef)">完成提交风控经理</div>
<div class="submit"
@click="submit(formRef)">完成提交风控经理</div>
</div>
</el-form>
</el-tab-pane>
@ -130,13 +183,15 @@
</template>
<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue';
import { ref, reactive, computed, onMounted, defineEmits } from 'vue';
import { ElMessage } from 'element-plus';
import type { TabsPaneContext, FormInstance, FormRules } from 'element-plus';
import { productElement, typeOfGuarantee } from '@/api/bank';
import { getProcessInformationBasedOnRoles, getAllBusiness } from '@/api/judgment';
import { productElement, typeOfGuarantee, save } from '@/api/bank';
import { getProcessInformationBasedOnRoles, addOperation } from '@/api/judgment';
import { useRouter, useRoute } from 'vue-router';
import { handleId } from '@/utils/common';
const emit = defineEmits(['getList']);
interface RuleForm {
productDefinition: string;
productName: string;
@ -157,8 +212,8 @@ interface RuleForm {
otherPurposesOfLoan: string;
productObject?: number;
productType: number;
providentFundAndSocialSecurity?: number;
whetherToSupportEarlyRepayment?: number;
providentFundAndSocialSecurity: any;
whetherToSupportEarlyRepayment?: any;
}
const router = useRouter();
@ -187,8 +242,8 @@ const form = reactive<RuleForm>({
otherPurposesOfLoan: '',
productObject: '',
productType: computed(() => +route.query.type),
providentFundAndSocialSecurity: 2,
whetherToSupportEarlyRepayment: 2,
providentFundAndSocialSecurity: false,
whetherToSupportEarlyRepayment: false,
});
const rules = reactive<FormRules<RuleForm>>({
productDefinition: [{ required: true, message: '请输入产品定义', trigger: 'blur' }],
@ -220,9 +275,17 @@ const submit = async (formEl: FormInstance | undefined) => {
await formEl.validate(async (valid, fields) => {
if (valid) {
try {
console.log(33, form.value);
// const { data } = await productElement(form.value);
// ElMessage.success('');
const param = JSON.parse(JSON.stringify(form));
param.currentWorkingLife = param.currentWorkingLife.join();
param.educationalRequirements = param.educationalRequirements.join();
param.modeRepayment = param.modeRepayment.join();
param.providentFundAndSocialSecurity = param.providentFundAndSocialSecurity ? 13 : '';
param.whetherToSupportEarlyRepayment = param.whetherToSupportEarlyRepayment ? 58 : '';
console.log(33, form, param);
const { data } = await save(param);
addRecord(param);
ElMessage.success('提交成功!');
emit('getList');
// setTimeout(() => {
// router.push(``)
// }, 1500);
@ -233,6 +296,34 @@ const submit = async (formEl: FormInstance | undefined) => {
}
});
};
//
const addRecord = async (data: any) => {
const preIds = `1,2,41,44`;
const lcRule = <Record<string, any>[]>[
handleId(48, 1, data.productDefinition, preIds + ',48', 3),
handleId(49, 2, data.productName, preIds + ',49', 3),
handleId(50, 3, 1, preIds + ',50', 1),
];
if (data.age) {
lcRule.push(handleId(51, 41, 2, preIds + ',51', 1), handleId(51, 41, '[' + data.minimumAge + ',' + data.maximumAge + ']' + '', preIds + ',51', 5));
}
if (data.edu) {
lcRule.push(handleId(51, 4, '3,' + data.educationalRequirements, preIds + ',51', 1));
}
if (data.curWL) {
lcRule.push(handleId(51, 4, '3,' + data.currentWorkingLife, preIds + ',51', 1));
}
data.providentFundAndSocialSecurity && lcRule.push(handleId(51, 4, '3,13', preIds + ',51', 1));
//
lcRule.push(data.loanPurpose === 4 ? handleId(52, 11, data.otherPurposesOfLoan, preIds + ',52', 3) : handleId(52, 10, data.loanPurpose, preIds + ',52', 1));
await addOperation({
parentId: '1,2,41,44',
lcJudgmentRuleReq: lcRule,
projectId: 1,
});
};
onMounted(() => {
getConfig();
});

@ -21,10 +21,15 @@
:key="i"
:class="{ active: item.id === id }"
@click="switchProduct(item)">
<el-popconfirm title="您确定删除吗?"
@confirm="handleDelete(item.id)">
<template #reference>
<img src="@/assets/images/trash.png"
alt=""
class="del"
@click="handleDelete(row.id)" />
class="del" />
</template>
</el-popconfirm>
<h6>{{ item.productName }}</h6>
<p class="type">{{ item.productNumber + ' ' + item.guarantyStyle }}</p>
<p class="status">{{ getStatus(item.status) }}</p>
@ -40,6 +45,7 @@
<detail v-if="action === 'detail'"
v-model="form"></detail>
<add v-else-if="action === 'add'"
@getList="getList"
v-model="form"></add>
</div>
</div>
@ -108,10 +114,10 @@ const toAdd = () => {
query: route.query,
});
};
const handleDelete = async (id: number[]) => {
const handleDelete = async (id: number) => {
await batchDeletion([id]);
getList();
ElMessage.success(t('success'));
ElMessage.success('删除成功!');
};
</script>
@ -121,7 +127,7 @@ const handleDelete = async (id: number[]) => {
}
.products {
li {
@apply relative p-5 mb-5 rounded-[10px] cursor-pointer border border-solid;
@apply relative p-5 pt-7 mb-5 rounded-[10px] cursor-pointer border border-solid;
background: url(../../assets/images/10.png) 0 0/100% 100% no-repeat;
&.active {
@apply border-[#CAE0FF];

@ -9,36 +9,26 @@
<p class="text">{{ info.productDefinition }}</p>
<h6 class="step-name mt-5">产品要素</h6>
<div class="line">
<label class="label">产品名称</label>
<p class="text">{{ info.productName }}</p>
</div>
<div class="line">
<label class="label">贷款币种</label>
<p class="text">人民币</p>
<p class="text">贷款币种人民币</p>
</div>
<div class="line">
<label class="label">贷款用途</label>
<p class="text">{{ info.productName }}</p>
</div>
<div class="line">
<label class="label">担保方式</label>
<p class="text">{{ info.productName }}</p>
</div>
<div class="line">
<label class="label">贷款期限</label>
<p class="text">{{ info.productName }}</p>
<div v-if="info.loanPurpose"
class="line">
<p class="text">{{ info.loanPurpose }}</p>
</div>
<div class="line">
<label class="label">贷款利率</label>
<p class="text">{{ info.productName }}</p>
<div v-if="info.guarantyStyleList"
class="line">
<p class="text">{{ info.guarantyStyleList }}</p>
</div>
<div class="line">
<label class="label">还款方式</label>
<p class="text">{{ info.productName }}</p>
<div v-if="info.lengthOfMaturity"
class="line">
<p class="text">{{ info.lengthOfMaturity }}</p>
</div>
<div class="line">
<label class="label">贷款对象</label>
<p class="text">{{ info.productName }}</p>
<div v-if="info.loanCommitment"
class="line">
<p class="text">{{ info.loanCommitment }}</p>
</div>
</div>
</el-tab-pane>
@ -50,7 +40,7 @@
import { ref, computed, watch, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import type { TabsPaneContext } from 'element-plus';
import { findById } from '@/api/bank';
import { productElement } from '@/api/bank';
import { useRouter, useRoute } from 'vue-router';
defineProps({ modelValue: { type: Object, required: true } });
@ -70,7 +60,7 @@ const tabChange = (tab: TabsPaneContext, event: Event) => {
const getDetail = async () => {
if (id.value) {
try {
const { data } = await findById(id.value);
const { data } = await productElement(id.value);
info.value = data;
} finally {
}

@ -79,11 +79,15 @@
@click="handleEdit(row.id)"
size="small">配置要素</el-button>
<el-button type="text"
@click="handleEdit(row.id)"
@click="toDetail(row.id)"
size="small">产品详情</el-button>
<el-popconfirm title="您确定删除吗?"
@confirm="handleDelete(row.id)">
<template #reference>
<el-button type="text"
@click="handleDelete(row.id)"
size="small">删除</el-button>
</template>
</el-popconfirm>
</template></el-table-column>
</el-table>
<el-pagination v-model:currentPage="currentPage"
@ -197,12 +201,22 @@ const toAdd = () => {
query: route.query,
});
};
//
const toDetail = async (id: number) => {
router.push({
path: `/product/cardList/detail`,
query: {
...route.query,
id,
},
});
};
//
const toCardList = () => {
router.push('/product/cardList/config');
};
const handleDelete = async (id: number[]) => {
const handleDelete = async (id: number) => {
await batchDeletion([id]);
getList();
ElMessage.success(t('success'));

Loading…
Cancel
Save