19、申请借款额度

19.1、需求介绍

19.1.1、借款人申请额度

1、需求描述

平台管理员根据借款人个人信息设置积分,通过积分规则借款人可以获取额度。

2、相关数据库表

19.1.2、具体步骤

step1:用户在个人中心点击 “立即借款” (http://localhost:3000/user/borrower)

step2:展示借款人信息认证页面

step3:借款人填写信息并提交

step4:展示等待审核页面

step5:平台审核

step6:显示审批结果

19.2、借款人信息表单

19.2.1、步骤导航

1、参考

Steps 步骤条:https://element.eleme.io/#/zh-CN/component/steps

Alert 警告:

2、页面模板

这个页面比较复杂,因此我们一步一步创建,熟悉页面结构

创建 pages/user/borrower.vue

<template><div class="personal-main"><div class="personal-pay"><h3><i>借款人信息认证</i></h3><el-steps :active="active" style="margin: 40px"><el-step title="填写借款人信息"></el-step><el-step title="提交平台审核"></el-step><el-step title="等待认证结果"></el-step></el-steps><div v-if="active === 0" class="user-borrower"><h6>个人基本信息</h6><h6>联系人信息</h6><h6>身份认证信息</h6><h6>其他信息</h6><el-form label-width="120px"><el-form-item><el-buttontype="primary":disabled="submitBtnDisabled"@click="save">提交</el-button></el-form-item></el-form></div><div v-if="active === 1"><div style="margin-top:40px;"><el-alerttitle="您的认证申请已成功提交,请耐心等待"type="warning"show-icon:closable="false">我们将在2小时内完成审核,审核时间为周一至周五8:00至20:00。</el-alert></div></div><div v-if="active === 2"><div style="margin-top:40px;"><el-alertv-if="borrowerStatus === 2"title="您的认证审批已通过"type="success"show-icon:closable="false"></el-alert><el-alertv-if="borrowerStatus === -1"title="您的认证审批未通过"type="error"show-icon:closable="false"></el-alert></div></div></div></div>
</template>
<script>
export default {data() {let BASE_API = process.env.BASE_APIreturn {active: 0, //步骤borrowerStatus: null,submitBtnDisabled: false,//借款人信息borrower: {borrowerAttachList: [],},educationList: [], //学历列表industryList: [], //行业列表incomeList: [], //月收入列表returnSourceList: [], //还款来源列表contactsRelationList: [], //联系人关系uploadUrl: BASE_API + '/api/oss/file/upload', //文件上传地址}},methods: {save() {this.submitBtnDisabled = truethis.active = 1},},
}
</script>

19.2.2、借款人信息页面

1、个人基本信息

<h6>个人基本信息</h6>
<el-form label-width="120px"><el-form-item label="年龄"><el-col :span="5"><el-input v-model="borrower.age" /></el-col></el-form-item><el-form-item label="性别"><el-select v-model="borrower.sex"><el-option :value="1" :label="'男'" /><el-option :value="0" :label="'女'" /></el-select></el-form-item><el-form-item label="婚否"><el-select v-model="borrower.marry"><el-option :value="true" :label="'是'" /><el-option :value="false" :label="'否'" /></el-select></el-form-item><el-form-item label="学历"><el-select v-model="borrower.education"><el-optionv-for="item in educationList":key="item.value":label="item.name":value="item.value"/></el-select></el-form-item><el-form-item label="行业"><el-select v-model="borrower.industry"><el-optionv-for="item in industryList":key="item.value":label="item.name":value="item.value"/></el-select></el-form-item><el-form-item label="月收入"><el-select v-model="borrower.income"><el-optionv-for="item in incomeList":key="item.value":label="item.name":value="item.value"/></el-select></el-form-item><el-form-item label="还款来源"><el-select v-model="borrower.returnSource"><el-optionv-for="item in returnSourceList":key="item.value":label="item.name":value="item.value"/></el-select></el-form-item>
</el-form>

2、联系人信息

<h6>联系人信息</h6>
<el-form label-width="120px"><el-form-item label="联系人姓名"><el-col :span="5"><el-input v-model="borrower.contactsName" /></el-col></el-form-item><el-form-item label="联系人手机"><el-col :span="5"><el-input v-model="borrower.contactsMobile" /></el-col></el-form-item><el-form-item label="联系人关系"><el-select v-model="borrower.contactsRelation"><el-optionv-for="item in contactsRelationList":key="item.value":label="item.name":value="item.value"/></el-select></el-form-item>
</el-form>

3、身份认证信息

<h6>身份认证信息</h6>
<el-form label-width="120px"><el-form-item label="身份证人像面"><el-upload:on-success="onUploadSuccessIdCard1":on-remove="onUploadRemove":multiple="false":action="uploadUrl":data="{ module: 'idCard1' }":limit="1"list-type="picture-card"><i class="el-icon-plus"></i></el-upload></el-form-item><el-form-item label="身份证国徽面"><el-upload:on-success="onUploadSuccessIdCard2":on-remove="onUploadRemove":multiple="false":action="uploadUrl":data="{ module: 'idCard2' }":limit="1"list-type="picture-card"><i class="el-icon-plus"></i></el-upload></el-form-item>
</el-form>

4、其他信息

<h6>其他信息</h6>
<el-form label-width="120px"><el-form-item label="房产信息"><el-upload:on-success="onUploadSuccessHouse":on-remove="onUploadRemove":multiple="false":action="uploadUrl":data="{ module: 'house' }"list-type="picture-card"><i class="el-icon-plus"></i></el-upload></el-form-item><el-form-item label="车辆信息"><el-upload:on-success="onUploadSuccessCar":on-remove="onUploadRemove":multiple="false":action="uploadUrl":data="{ module: 'car' }"list-type="picture-card"><i class="el-icon-plus"></i></el-upload></el-form-item>
</el-form>

5、文件上传

pages/user/borrower.vue

定义methods:

onUploadSuccessIdCard1(response, file) {this.onUploadSuccess(response, file, 'idCard1')
},
onUploadSuccessIdCard2(response, file) {this.onUploadSuccess(response, file, 'idCard2')
},
onUploadSuccessHouse(response, file) {this.onUploadSuccess(response, file, 'house')
},
onUploadSuccessCar(response, file) {this.onUploadSuccess(response, file, 'car')
},
onUploadSuccess(response, file, type) {// debuggerif (response.code !== 0) {this.$message.error(response.message)return}// 填充上传文件列表this.borrower.borrowerAttachList.push({imageName: file.name,imageUrl: response.data.url,imageType: type,})
},
onUploadRemove(file, fileList) {console.log('fileList', fileList)//删除oss服务器上的内容this.$axios.$delete('/api/oss/file/remove?url=' + file.response.data.url).then((response) => {// debuggerconsole.log('远程删除')this.borrower.borrowerAttachList = this.borrower.borrowerAttachList.filter(function(item) {console.log('item', item)return item.imageUrl != file.response.data.url})})
},

19.3、表单数据展示

19.3.1、根据编码获取数据字典

1、controller

sevice-core中添加接口方法

package com.atguigu.srb.core.controller.api;@Api(tags = "数据字典")
@RestController
@RequestMapping("/api/core/dict")
@Slf4j
public class DictController {@Resourceprivate DictService dictService;@ApiOperation("根据dictCode获取下级节点")@GetMapping("/findByDictCode/{dictCode}")public R findByDictCode(@ApiParam(value = "节点编码", required = true)@PathVariable String dictCode) {List<Dict> list = dictService.findByDictCode(dictCode);return R.ok().data("dictList", list);}
}

2、service

接口:DictService

List<Dict> findByDictCode(String dictCode);

实现:DictServiceImpl

@Override
public List<Dict> findByDictCode(String dictCode) {QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();dictQueryWrapper.eq("dict_code", dictCode);Dict dict = baseMapper.selectOne(dictQueryWrapper);return this.listByParentId(dict.getId());
}

19.3.2、前端展示借款人信息

展示下拉列表

pages/user/borrower.vue中调用接口

定义methods:

   initSelected() {//学历列表this.$axios.$get('/api/core/dict/findByDictCode/education').then((response) => {this.educationList = response.data.dictList})//行业列表this.$axios.$get('/api/core/dict/findByDictCode/industry').then((response) => {this.industryList = response.data.dictList})//收入列表this.$axios.$get('/api/core/dict/findByDictCode/income').then((response) => {this.incomeList = response.data.dictList})//还款来源列表this.$axios.$get('/api/core/dict/findByDictCode/returnSource').then((response) => {this.returnSourceList = response.data.dictList})//联系人关系列表this.$axios.$get('/api/core/dict/findByDictCode/relation').then((response) => {this.contactsRelationList = response.data.dictList})},

页面加载时调用

  created() {this.initSelected()},

19.4、表单数据提交

19.4.1、后端开发

1、定义VO对象

service-core微服务,创建BorrowerVO

package com.atguigu.srb.core.pojo.vo;@Data
@ApiModel(description="借款人认证信息")
public class BorrowerVO {@ApiModelProperty(value = "性别(1:男 0:女)")private Integer sex;@ApiModelProperty(value = "年龄")private Integer age;@ApiModelProperty(value = "学历")private Integer education;@ApiModelProperty(value = "是否结婚(1:是 0:否)")private Boolean marry;@ApiModelProperty(value = "行业")private Integer industry;@ApiModelProperty(value = "月收入")private Integer income;@ApiModelProperty(value = "还款来源")private Integer returnSource;@ApiModelProperty(value = "联系人名称")private String contactsName;@ApiModelProperty(value = "联系人手机")private String contactsMobile;@ApiModelProperty(value = "联系人关系")private Integer contactsRelation;@ApiModelProperty(value = "借款人附件资料")private List<BorrowerAttach> borrowerAttachList;
}

2、定义枚举

BorrowerStatusEnum

数据库设计中对应认证状态status (0:未认证,1:认证中, 2:认证通过, -1:认证失败)

3、controller

service-core中在BorrowerController中定义接口方法

package com.atguigu.srb.core.controller.api;@Api(tags = "借款人")
@RestController
@RequestMapping("/api/core/borrower")
@Slf4j
public class BorrowerController {@Resourceprivate BorrowerService borrowerService;@ApiOperation("保存借款人信息")@PostMapping("/auth/save")public R save(@RequestBody BorrowerVO borrowerVO, HttpServletRequest request) {String token = request.getHeader("token");Long userId = JwtUtils.getUserId(token);borrowerService.saveBorrowerVOByUserId(borrowerVO, userId);return R.ok().message("信息提交成功");}
}

4、service

接口:BorrowerService

void saveBorrowerVOByUserId(BorrowerVO borrowerVO, Long userId);

实现:BorrowerServiceImpl

@Resource
private BorrowerAttachMapper borrowerAttachMapper;
@Resource
private UserInfoMapper userInfoMapper;@Transactional(rollbackFor = Exception.class)
@Override
public void saveBorrowerVOByUserId(BorrowerVO borrowerVO, Long userId) {UserInfo userInfo = userInfoMapper.selectById(userId);//保存借款人信息Borrower borrower = new Borrower();BeanUtils.copyProperties(borrowerVO, borrower);borrower.setUserId(userId);borrower.setName(userInfo.getName());borrower.setIdCard(userInfo.getIdCard());borrower.setMobile(userInfo.getMobile());borrower.setStatus(BorrowerStatusEnum.AUTH_RUN.getStatus());//认证中baseMapper.insert(borrower);//保存附件List<BorrowerAttach> borrowerAttachList = borrowerVO.getBorrowerAttachList();borrowerAttachList.forEach(borrowerAttach -> {borrowerAttach.setBorrowerId(borrower.getId());borrowerAttachMapper.insert(borrowerAttach);});//更新会员状态,更新为认证中userInfo.setBorrowAuthStatus(BorrowerStatusEnum.AUTH_RUN.getStatus());userInfoMapper.updateById(userInfo);
}

19.4.2、前端整合

pages/user/borrower.vue 脚本

save() {// debuggerthis.submitBtnDisabled = truethis.$axios.$post('/api/core/borrower/auth/save', this.borrower).then((response) => {this.active = 1})
},

19.5、获取借款人状态

19.5.1、获取借款人状态

1、BorrowerController

@ApiOperation("获取借款人认证状态")
@GetMapping("/auth/getBorrowerStatus")
public R getBorrowerStatus(HttpServletRequest request){String token = request.getHeader("token");Long userId = JwtUtils.getUserId(token);Integer status = borrowerService.getStatusByUserId(userId);return R.ok().data("borrowerStatus", status);
}

2、service

接口:BorrowerService

Integer getStatusByUserId(Long userId);

实现:BorrowerServiceImpl

@Override
public Integer getStatusByUserId(Long userId) {QueryWrapper<Borrower> borrowerQueryWrapper = new QueryWrapper<>();borrowerQueryWrapper.select("status").eq("user_id", userId);List<Object> objects = baseMapper.selectObjs(borrowerQueryWrapper);if(objects.size() == 0){//借款人尚未提交信息return BorrowerStatusEnum.NO_AUTH.getStatus();}Integer status = (Integer)objects.get(0);return status;
}

19.5.2、前端开发

pages/user/borrower.vue 脚本

将this.initSelected()在this.getUserInfo()中调用

created() {this.getUserInfo()
},

methods中添加方法:

//获取借款人信息
getUserInfo() {this.$axios.$get('/api/core/borrower/auth/getBorrowerStatus').then((response) => {this.borrowerStatus = response.data.borrowerStatusif (this.borrowerStatus === 0) {//未认证this.active = 0//获取下拉列表this.initSelected()} else if (this.borrowerStatus === 1) {//认证中this.active = 1} else if (this.borrowerStatus === 2) {//认证成功this.active = 2} else if (this.borrowerStatus === -1) {//认证失败this.active = 2}})
},

将 data() 中 active的初始化值设置为null

active: null, //步骤

20、借款额度审核

20.1、借款列表展示

20.1.1、需求

借款人列表

额度审批

额度审批的目标:

(1)在user_integral表中添加积分明细

(2)在user_info表中添加总积分(user_info表中的原始积分 + user_integral表中的积分明细之和 )

(3)修改borrower表的借款申请审核状态

(4)修改user_info表中的借款申请审核状态

20.1.2、后端实现

1、创建接口

创建 AdminBorrowerController

package com.atguigu.srb.core.controller.admin;@Api(tags = "借款人管理")
@RestController
@RequestMapping("/admin/core/borrower")
@Slf4j
public class AdminBorrowerController {@Resourceprivate BorrowerService borrowerService;@ApiOperation("获取借款人分页列表")@GetMapping("/list/{page}/{limit}")public R listPage(@ApiParam(value = "当前页码", required = true)@PathVariable Long page,@ApiParam(value = "每页记录数", required = true)@PathVariable Long limit,@ApiParam(value = "查询关键字", required = false)@RequestParam String keyword) { //这里的@RequestParam其实是可以省略的,但是在目前的swagger版本中(2.9.2)不能省略,//否则默认将没有注解的参数解析为body中的传递的数据Page<Borrower> pageParam = new Page<>(page, limit);IPage<Borrower> pageModel = borrowerService.listPage(pageParam, keyword);return R.ok().data("pageModel", pageModel);}
}

2、创建Service方法

接口:BorrowerService

IPage<Borrower> listPage(Page<Borrower> pageParam, String keyword);

实现:BorrowerServiceImpl

@Override
public IPage<Borrower> listPage(Page<Borrower> pageParam, String keyword) {if (StringUtils.isBlank(keyword)) {return baseMapper.selectPage(pageParam, null);}QueryWrapper<Borrower> borrowerQueryWrapper = new QueryWrapper<>();borrowerQueryWrapper.like("name", keyword).or().like("id_card", keyword).or().like("mobile", keyword).orderByDesc("id");return baseMapper.selectPage(pageParam, borrowerQueryWrapper);
}

20.1.3、前端实现

1、创建页面组件

创建 src/views/core/borrower/list.vue

<template><div class="app-container">借款用户列表</div>
</template>
<script>
export default {}
</script>

创建 src/views/core/borrower/detail.vue

<template><div class="app-container">借款用户详情</div>
</template>
<script>
export default {}
</script>

2、配置路由

src/router/index.js

 {path: '/core/borrower',component: Layout,name: 'coreBorrower',meta: { title: '借款管理', icon: 'el-icon-s-unfold' },alwaysShow: true,children: [{path: 'list',name: 'coreBorrowerList',component: () => import('@/views/core/borrower/list'),meta: { title: '借款人列表' }},{path: 'detail/:id',name: 'coreBorrowerDetail',component: () => import('@/views/core/borrower/detail'),meta: { title: '借款人详情' },hidden: true}]},

3、定义api

创建 src/api/core/borrower.js

import request from '@/utils/request'
export default {getPageList(page, limit, keyword) {return request({url: `/admin/core/borrower/list/${page}/${limit}`,method: 'get',params: {keyword}})}
}

4、页面模板

src/views/core/borrower/list.vue

<template><div class="app-container"><!--查询表单--><el-form :inline="true"><el-form-item label="关键字"><el-input v-model="keyword" placeholder="姓名/手机/身份证" /></el-form-item><el-button type="primary" icon="el-icon-search" @click="fetchData()">查询</el-button><el-button type="default" @click="resetData()">清空</el-button></el-form><!-- 列表 --><el-table :data="list" stripe><el-table-column label="序号" width="70" align="center"><template slot-scope="scope">{{ (page - 1) * limit + scope.$index + 1 }}</template></el-table-column><el-table-column prop="name" label="姓名" /><el-table-column prop="mobile" label="手机" /><el-table-column prop="idCard" label="身份证号" width="200" /><el-table-column label="性别" width="80"><template slot-scope="scope">{{ scope.row.sex === 1 ? '男' : '女' }}</template></el-table-column><el-table-column prop="age" label="年龄" width="80" /><el-table-column label="是否结婚" width="120"><template slot-scope="scope">{{ scope.row.marry ? '是' : '否' }}</template></el-table-column><el-table-column label="状态" width="100"><template slot-scope="scope"><el-tag v-if="scope.row.status === 0" type="info" size="mini">未认证</el-tag><el-tag v-if="scope.row.status === 1" type="warning" size="mini">认证中</el-tag><el-tag v-if="scope.row.status === 2" type="success" size="mini">认证通过</el-tag><el-tag v-if="scope.row.status === -1" type="danger" size="mini">认证失败</el-tag></template></el-table-column><el-table-column prop="createTime" label="申请时间" width="160" /><el-table-column label="操作" width="200" align="center"><template slot-scope="scope"><router-link :to="'/core/borrower/detail/' + scope.row.id"><el-button v-if="scope.row.status === 1" type="warning" size="mini">审批</el-button><el-button v-else type="primary" size="mini">查看</el-button></router-link></template></el-table-column></el-table><!-- 分页组件 --><el-pagination:current-page="page":total="total":page-size="limit":page-sizes="[2, 10, 20]"style="padding: 30px 0; "layout="total, sizes, prev, pager, next, jumper"@size-change="changePageSize"@current-change="changeCurrentPage"/></div>
</template>

5、页面脚本

src/views/core/borrower/list.vue

<script>
import borrowerApi from '@/api/core/borrower'export default {data() {return {list: null, // banner列表total: 0, // 数据库中的总记录数page: 1, // 默认页码limit: 10, // 每页记录数keyword: '' // 查询表单对象}},// 生命周期函数:内存准备完毕,页面尚未渲染created() {this.fetchData()},methods: {// 加载banner列表数据fetchData() {borrowerApi.getPageList(this.page, this.limit, this.keyword).then(response => {this.list = response.data.pageModel.recordsthis.total = response.data.pageModel.total})},// 每页记录数改变,size:回调参数,表示当前选中的“每页条数”changePageSize(size) {this.limit = sizethis.fetchData()},// 改变页码,page:回调参数,表示当前选中的“页码”changeCurrentPage(page) {this.page = pagethis.fetchData()},// 重置表单resetData() {this.keyword = ''this.fetchData()}}
}
</script>

20.2、借款人信息展示

20.2.1、后端实现

1、定义VO对象

BorrowerAttachVO

package com.atguigu.srb.core.pojo.vo;@Data
@ApiModel(value="借款人附件资料")
public class BorrowerAttachVO {@ApiModelProperty(value = "图片类型(idCard1:身份证正面,idCard2:身份证反面,house:房产证,car:车)")private String imageType;@ApiModelProperty(value = "图片路径")private String imageUrl;
}

BorrowerDetailVO

package com.atguigu.srb.core.pojo.vo;@Data
@ApiModel(description="借款人信息详情")
public class BorrowerDetailVO {@ApiModelProperty(value = "用户id")private Long userId;@ApiModelProperty(value = "姓名")private String name;@ApiModelProperty(value = "身份证号")private String idCard;@ApiModelProperty(value = "手机")private String mobile;@ApiModelProperty(value = "性别")private String sex;@ApiModelProperty(value = "年龄")private Integer age;@ApiModelProperty(value = "学历")private String education;@ApiModelProperty(value = "是否结婚")private String marry;@ApiModelProperty(value = "行业")private String industry;@ApiModelProperty(value = "月收入")private String income;@ApiModelProperty(value = "还款来源")private String returnSource;@ApiModelProperty(value = "联系人名称")private String contactsName;@ApiModelProperty(value = "联系人手机")private String contactsMobile;@ApiModelProperty(value = "联系人关系")private String contactsRelation;@ApiModelProperty(value = "审核状态")private String status;@ApiModelProperty(value = "创建时间")private LocalDateTime createTime;@ApiModelProperty(value = "借款人附件资料")private List<BorrowerAttachVO> borrowerAttachVOList;
}

2、Controller

AdminBorrowerController

@ApiOperation("获取借款人信息")
@GetMapping("/show/{id}")
public R show(@ApiParam(value = "借款人id", required = true)@PathVariable Long id) {BorrowerDetailVO borrowerDetailVO = borrowerService.getBorrowerDetailVOById(id);return R.ok().data("borrowerDetailVO", borrowerDetailVO);
}

3、BorrowerService

接口

BorrowerDetailVO getBorrowerDetailVOById(Long id);

实现:调用BorrowerAttachService和DictService

@Resource
private DictService dictService;
@Resource
private BorrowerAttachService borrowerAttachService;@Override
public BorrowerDetailVO getBorrowerDetailVOById(Long id) {//获取借款人信息Borrower borrower = baseMapper.selectById(id);//填充基本借款人信息BorrowerDetailVO borrowerDetailVO = new BorrowerDetailVO();BeanUtils.copyProperties(borrower, borrowerDetailVO);//婚否borrowerDetailVO.setMarry(borrower.getMarry()?"是":"否");//性别borrowerDetailVO.setSex(borrower.getSex()==1?"男":"女");//计算下拉列表选中内容String education = dictService.getNameByParentDictCodeAndValue("education", borrower.getEducation());String industry = dictService.getNameByParentDictCodeAndValue("industry", borrower.getIndustry());String income = dictService.getNameByParentDictCodeAndValue("income", borrower.getIncome());String returnSource = dictService.getNameByParentDictCodeAndValue("returnSource", borrower.getReturnSource());String contactsRelation = dictService.getNameByParentDictCodeAndValue("relation", borrower.getContactsRelation());//设置下拉列表选中内容borrowerDetailVO.setEducation(education);borrowerDetailVO.setIndustry(industry);borrowerDetailVO.setIncome(income);borrowerDetailVO.setReturnSource(returnSource);borrowerDetailVO.setContactsRelation(contactsRelation);//审批状态String status = BorrowerStatusEnum.getMsgByStatus(borrower.getStatus());borrowerDetailVO.setStatus(status);//获取附件VO列表List<BorrowerAttachVO> borrowerAttachVOList =  borrowerAttachService.selectBorrowerAttachVOList(id);borrowerDetailVO.setBorrowerAttachVOList(borrowerAttachVOList);return borrowerDetailVO;
}

4、DictService

接口

String getNameByParentDictCodeAndValue(String dictCode, Integer value);

实现

@Override
public String getNameByParentDictCodeAndValue(String dictCode, Integer value) {QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<Dict>();dictQueryWrapper.eq("dict_code", dictCode);Dict parentDict = baseMapper.selectOne(dictQueryWrapper);if(parentDict == null) {return "";}dictQueryWrapper = new QueryWrapper<>();dictQueryWrapper.eq("parent_id", parentDict.getId()).eq("value", value);Dict dict = baseMapper.selectOne(dictQueryWrapper);if(dict == null) {return "";}return dict.getName();
}

5、BorrowerAttachService

接口

List<BorrowerAttachVO> selectBorrowerAttachVOList(Long borrowerId);

实现

@Override
public List<BorrowerAttachVO> selectBorrowerAttachVOList(Long borrowerId) {QueryWrapper<BorrowerAttach> borrowerAttachQueryWrapper = new QueryWrapper<>();borrowerAttachQueryWrapper.eq("borrower_id", borrowerId);List<BorrowerAttach> borrowerAttachList = baseMapper.selectList(borrowerAttachQueryWrapper);List<BorrowerAttachVO> borrowerAttachVOList = new ArrayList<>();borrowerAttachList.forEach(borrowerAttach -> {BorrowerAttachVO borrowerAttachVO = new BorrowerAttachVO();borrowerAttachVO.setImageType(borrowerAttach.getImageType());borrowerAttachVO.setImageUrl(borrowerAttach.getImageUrl());borrowerAttachVOList.add(borrowerAttachVO);});return borrowerAttachVOList;
}

20.2.2、前端实现

1、定义api

api/borrower.js中添加方法

  show(id) {return request({url: `/admin/core/borrower/show/${id}`,method: 'get'})},

2、页面脚本

src/views/core/borrower/detail.vue

<script>
// 引入组件
import borrowerApi from '@/api/core/borrower'
export default {data() {return {borrower: {},saveBtnDisabled: false,approvalForm: {borrowerId: 0,status: 2,content: '',infoIntegral: 30,isIdCardOk: false,isHouseOk: false,isCarOk: false}}},created() {if (this.$route.params.id) {this.fetchDataById()}},methods: {// 根据id查询记录fetchDataById() {borrowerApi.show(this.$route.params.id).then(response => {this.borrower = response.data.borrowerDetailVO})},back() {this.$router.push({ path: '/core/borrower/list' })}}
}
</script>

3、页面模板

src/views/core/borrower/detail.vue

<template><div class="app-container"><el-form label-width="100px" class="form-table"><el-row><el-col :span="6"><el-form-item label="状态">{{ borrower.status }}</el-form-item></el-col><el-col :span="6"><el-form-item label="创建时间">{{ borrower.createTime }}</el-form-item></el-col></el-row><el-row><el-col :span="6"><el-form-item label="姓名">{{ borrower.name }}</el-form-item></el-col><el-col :span="6"><el-form-item label="性别">{{ borrower.sex }}</el-form-item></el-col><el-col :span="6"><el-form-item label="年龄">{{ borrower.age }}</el-form-item></el-col><el-col :span="6"><el-form-item label="手机">{{ borrower.mobile }}</el-form-item></el-col></el-row><el-row><el-col :span="6"><el-form-item label="学历">{{ borrower.education }}</el-form-item></el-col><el-col :span="6"><el-form-item label="是否结婚">{{ borrower.marry }}</el-form-item></el-col><el-col :span="6"><el-form-item label="行业">{{ borrower.industry }}</el-form-item></el-col><el-col :span="6"><el-form-item label="还款来源">{{ borrower.returnSource }}</el-form-item></el-col></el-row><el-row><el-col :span="6"><el-form-item label="身份证号">{{ borrower.idCard }}</el-form-item></el-col><el-col :span="6"><el-form-item label="联系人名称">{{ borrower.contactsName }}</el-form-item></el-col><el-col :span="6"><el-form-item label="联系人手机">{{ borrower.contactsMobile }}</el-form-item></el-col><el-col :span="6"><el-form-item label="联系人关系">{{ borrower.contactsRelation }}</el-form-item></el-col></el-row><el-row><el-col :span="24"><el-form-item label="身份证正面"><span v-for="item in borrower.borrowerAttachVOList" :key="item.id"><el-imagev-if="item.imageType == 'idCard1'"style="width: 150px;":src="item.imageUrl":preview-src-list="[item.imageUrl]"/></span></el-form-item></el-col></el-row><el-row><el-col :span="24"><el-form-item label="身份证反面"><span v-for="item in borrower.borrowerAttachVOList" :key="item.id"><el-imagev-if="item.imageType == 'idCard2'"style="width: 150px;":src="item.imageUrl":preview-src-list="[item.imageUrl]"/></span></el-form-item></el-col></el-row><el-row><el-col :span="24"><el-form-item label="房产信息"><span v-for="item in borrower.borrowerAttachVOList" :key="item.id"><el-imagev-if="item.imageType == 'house'"style="width: 150px;":src="item.imageUrl":preview-src-list="[item.imageUrl]"/></span></el-form-item></el-col></el-row><el-row><el-col :span="24"><el-form-item label="车辆信息"><span v-for="item in borrower.borrowerAttachVOList" :key="item.id"><el-imagev-if="item.imageType == 'car'"style="width: 150px;":src="item.imageUrl":preview-src-list="[item.imageUrl]"/></span></el-form-item></el-col></el-row><el-row style="text-align:center"><el-button @click="back">返回</el-button></el-row></el-form></div>
</template>

20.3、借款额度审核

20.3.1、后端实现

1、创建VO

BorrowerApprovalVO

package com.atguigu.srb.core.pojo.vo;@Data
@ApiModel(description = "借款人审批")
public class BorrowerApprovalVO {@ApiModelProperty(value = "id")private Long borrowerId;@ApiModelProperty(value = "状态")private Integer status;@ApiModelProperty(value = "身份证信息是否正确")private Boolean isIdCardOk;@ApiModelProperty(value = "房产信息是否正确")private Boolean isHouseOk;@ApiModelProperty(value = "车辆信息是否正确")private Boolean isCarOk;@ApiModelProperty(value = "基本信息积分")private Integer infoIntegral;
}

2、controller

AdminBorrowerController

@ApiOperation("借款额度审批")
@PostMapping("/approval")
public R approval(@RequestBody BorrowerApprovalVO borrowerApprovalVO) {borrowerService.approval(borrowerApprovalVO);return R.ok().message("审批完成");
}

**3、BorrowerService **

接口

void approval(BorrowerApprovalVO borrowerApprovalVO);

实现

@Resource
private UserIntegralMapper userIntegralMapper;@Transactional(rollbackFor = Exception.class)
@Override
public void approval(BorrowerApprovalVO borrowerApprovalVO) {if (borrowerApprovalVO.getInfoIntegral() < 30 || borrowerApprovalVO.getInfoIntegral() > 100) {throw new BusinessException("基本信息积分区间为30至100");}//借款人认证状态Long borrowerId = borrowerApprovalVO.getBorrowerId();Borrower borrower = baseMapper.selectById(borrowerId);borrower.setStatus(borrowerApprovalVO.getStatus());baseMapper.updateById(borrower);Long userId = borrower.getUserId();UserInfo userInfo = userInfoMapper.selectById(userId);//添加积分UserIntegral userIntegral = new UserIntegral();userIntegral.setUserId(userId);userIntegral.setIntegral(borrowerApprovalVO.getInfoIntegral());userIntegral.setContent("借款人基本信息");userIntegralMapper.insert(userIntegral);int curIntegral = userInfo.getIntegral() + borrowerApprovalVO.getInfoIntegral();if(borrowerApprovalVO.getIsIdCardOk()) {curIntegral += IntegralEnum.BORROWER_IDCARD.getIntegral();userIntegral = new UserIntegral();userIntegral.setUserId(userId);userIntegral.setIntegral(IntegralEnum.BORROWER_IDCARD.getIntegral());userIntegral.setContent(IntegralEnum.BORROWER_IDCARD.getMsg());userIntegralMapper.insert(userIntegral);}if(borrowerApprovalVO.getIsHouseOk()) {curIntegral += IntegralEnum.BORROWER_HOUSE.getIntegral();userIntegral = new UserIntegral();userIntegral.setUserId(userId);userIntegral.setIntegral(IntegralEnum.BORROWER_HOUSE.getIntegral());userIntegral.setContent(IntegralEnum.BORROWER_HOUSE.getMsg());userIntegralMapper.insert(userIntegral);}if(borrowerApprovalVO.getIsCarOk()) {curIntegral += IntegralEnum.BORROWER_CAR.getIntegral();userIntegral = new UserIntegral();userIntegral.setUserId(userId);userIntegral.setIntegral(IntegralEnum.BORROWER_CAR.getIntegral());userIntegral.setContent(IntegralEnum.BORROWER_CAR.getMsg());userIntegralMapper.insert(userIntegral);}userInfo.setIntegral(curIntegral);//修改审核状态userInfo.setBorrowAuthStatus(borrowerApprovalVO.getStatus());userInfoMapper.updateById(userInfo);
}

20.3.2、前端实现

1、定义api

api/borrower.js中添加方法

  approval(borrowerApproval) {return request({url: '/admin/core/borrower/approval',method: 'post',data: borrowerApproval})}

2、页面模板

src/views/core/borrower/detail.vue

<el-form label-width="170px" v-if="borrower.status === '认证中'"><el-form-item label="是否通过"><el-radio-group v-model="approvalForm.status"><el-radio :label="2">通过</el-radio><el-radio :label="-1">不通过</el-radio></el-radio-group></el-form-item><el-form-item v-if="approvalForm.status == 2" label="基本信息积分"><el-input v-model="approvalForm.infoIntegral" style="width: 140px;" /><span style="color: indianred">(可获取30至100积分)</span></el-form-item><el-form-item v-if="approvalForm.status == 2" label="身份证信息是否正确"><el-radio-group v-model="approvalForm.isIdCardOk"><el-radio :label="true">是</el-radio><el-radio :label="false">否</el-radio></el-radio-group><span style="color: indianred">(可获得积分30积分)</span></el-form-item><el-form-item v-if="approvalForm.status == 2" label="车辆信息是否正确"><el-radio-group v-model="approvalForm.isCarOk"><el-radio :label="true">是</el-radio><el-radio :label="false">否</el-radio></el-radio-group><span style="color: indianred">(可获得积分60积分)</span></el-form-item><el-form-item v-if="approvalForm.status == 2" label="房产信息是否正确"><el-radio-group v-model="approvalForm.isHouseOk"><el-radio :label="true">是</el-radio><el-radio :label="false">否</el-radio></el-radio-group><span style="color: indianred">(可获得积分100积分)</span></el-form-item><el-row style="text-align:center"><el-button type="primary" @click="approvalSubmit()">确定</el-button></el-row></el-form>

3、页面脚本

src/views/core/borrower/detail.vue

    approvalSubmit() {this.saveBtnDisabled = truethis.approvalForm.borrowerId = this.$route.params.idborrowerApi.approval(this.approvalForm).then(response => {this.$message.success(response.message)this.$router.push({ path: '/core/borrower/list' })})}

4、查看用户积分

审批后可以在会员列表查看用户积分


本文章参考B站 尚硅谷《尚融宝》Java微服务分布式金融项目,仅供个人学习使用,部分内容为本人自己见解,与尚硅谷无关。

【金融项目】尚融宝项目(十)相关推荐

  1. 【金融项目】尚融宝项目(一)

    1.尚融宝项目简介 1.1.前言 尚融宝项目是一个网络借贷信息中介服务平台,为个人投资者.个人融资用户和小微企业提供专业的线上信贷及出借撮合服务. 行业案例:人人贷 https://www.renre ...

  2. 【金融项目】尚融宝项目(十四)

    27.放款 27.1.需求介绍 27.1.1.平台放款 1.需求描述 标的募资时间到,平台会操作放款或撤标,如果达到放款条件则操作放款 说明:撤标过程与放款过程一致,处理业务相对简单,只是将出借金额返 ...

  3. 【金融项目】尚融宝项目(十六)

    31.RabbitMQ 31.1.整合Rabbit MQ发送短信 31.1.1.MQ服务器设置 1.访问MQ控制台 http://192.168.100.103:15672 2.创建用户 创建用户 s ...

  4. 【金融项目】尚融宝项目(十五)

    29.提现和还款 29.1.提现 29.1.1.需求 放款成功后,借款人可以申请提现. 参考<汇付宝商户账户技术文档>3.15用户申请提现 29.1.2.前端整合 pages/user/w ...

  5. 【金融项目】尚融宝项目(四)

    6.Alibaba EasyExcel 6.1.EasyExcel简介 6.1.1.Excel导入导出的应用场景 6.1.1.1.数据导入 减轻录入工作量 6.1.1.2.数据导出 统计信息归档 6. ...

  6. 【金融项目】尚融宝项目(六)

    11.访问令牌 11.1.单点登录 11.1.1.用户身份认证 11.1.1.1.单一服务器模式 一般过程如下: 用户向服务器发送用户名和密码. 验证服务器后,相关数据(如用户名,用户角色等)将保存在 ...

  7. 【金融项目】尚融宝项目(九)

    18.账户绑定 18.1.需求介绍 18.1.1.运行汇付宝 1.数据库 hfb.sql 2.程序 hfb 3.数据库配置 application-dev.yml 中修改数据库配置 4.启动程序 端口 ...

  8. 【金融项目】尚融宝项目(八)

    16.服务调用 16.1.注册中心和服务发现 16.1.1.运行Nacos注册中心 16.1.1.1.Nacos下载和安装 下载地址:https://github.com/alibaba/nacos/ ...

  9. 【金融项目】尚融宝项目(十一)

    21.借款申请 21.1.需求介绍 21.1.1.借款人申请借款 1.需求描述 2.相关数据库表 21.1.2.具体步骤 step1:借款人点击"我要借款" step2:展示借款信 ...

最新文章

  1. 2021中科院院士候选名单出炉:清华胡事民、南大周志华等人在列
  2. 【多线程】Synchronized及实现原理
  3. 「 每日一练,快乐水题 」717. 1比特与2比特字符
  4. java poi excel 单元格样式_java poi批量导出excel 设置单元格样式
  5. Deeplab unexpected label
  6. python需要掌握的词汇量_北大保安英语词汇量1.5万,会用Python编程,孟母三迁真有道理...
  7. 信息学奥赛C++语言:统计数字字符个数
  8. java填吧_请高手为我填上JAVA代码吧
  9. JS阻止冒泡方法(转)
  10. 【LOJ2127】「HAOI2015」按位或
  11. linux部署was找不到8879端口,WAS8.0与IHS集群安装与配置指导手册
  12. 找不到ADO.NET Entity Data Model模板或 sql server database project模板
  13. xp系统扫描仪服务器,xp系统扫描仪添加步骤全程的图文教程
  14. 大学英语B---词汇与语法
  15. Java-满天繁星案例(2)
  16. 社交网络分析的 R 基础:(三)向量、矩阵与列表
  17. 打包chromium浏览器
  18. Spring当中循环依赖很少有人讲,今天一起来学习!
  19. spring加载一个或者多个properties配置文件方法
  20. 数模每日小练习——数据处理——插值

热门文章

  1. 电脑开不了机 ,怎么解决?
  2. Android 设置Switch样式
  3. iOS 自定义封装WKWebView,可以网页回退转跳,与网页交互事件监听,解决内存释放问题
  4. 数据标准化方法z-score讲解(matlab)
  5. 孩子英语课听不懂?还要给孩子找线上外教英语吗?
  6. 在 WPF 中使用 Prism DryIOC 加载应用程序时导航到默认视图
  7. 一文了解Java强制类型转换
  8. 版号审批重启,游戏行业有望尽早度过寒冬?
  9. 漩涡鸣人的十大过人之处
  10. 什么是连连一键开店?连连一键开店是怎么操作的?