【金融项目】尚融宝项目(十)
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.前言 尚融宝项目是一个网络借贷信息中介服务平台,为个人投资者.个人融资用户和小微企业提供专业的线上信贷及出借撮合服务. 行业案例:人人贷 https://www.renre ...
- 【金融项目】尚融宝项目(十四)
27.放款 27.1.需求介绍 27.1.1.平台放款 1.需求描述 标的募资时间到,平台会操作放款或撤标,如果达到放款条件则操作放款 说明:撤标过程与放款过程一致,处理业务相对简单,只是将出借金额返 ...
- 【金融项目】尚融宝项目(十六)
31.RabbitMQ 31.1.整合Rabbit MQ发送短信 31.1.1.MQ服务器设置 1.访问MQ控制台 http://192.168.100.103:15672 2.创建用户 创建用户 s ...
- 【金融项目】尚融宝项目(十五)
29.提现和还款 29.1.提现 29.1.1.需求 放款成功后,借款人可以申请提现. 参考<汇付宝商户账户技术文档>3.15用户申请提现 29.1.2.前端整合 pages/user/w ...
- 【金融项目】尚融宝项目(四)
6.Alibaba EasyExcel 6.1.EasyExcel简介 6.1.1.Excel导入导出的应用场景 6.1.1.1.数据导入 减轻录入工作量 6.1.1.2.数据导出 统计信息归档 6. ...
- 【金融项目】尚融宝项目(六)
11.访问令牌 11.1.单点登录 11.1.1.用户身份认证 11.1.1.1.单一服务器模式 一般过程如下: 用户向服务器发送用户名和密码. 验证服务器后,相关数据(如用户名,用户角色等)将保存在 ...
- 【金融项目】尚融宝项目(九)
18.账户绑定 18.1.需求介绍 18.1.1.运行汇付宝 1.数据库 hfb.sql 2.程序 hfb 3.数据库配置 application-dev.yml 中修改数据库配置 4.启动程序 端口 ...
- 【金融项目】尚融宝项目(八)
16.服务调用 16.1.注册中心和服务发现 16.1.1.运行Nacos注册中心 16.1.1.1.Nacos下载和安装 下载地址:https://github.com/alibaba/nacos/ ...
- 【金融项目】尚融宝项目(十一)
21.借款申请 21.1.需求介绍 21.1.1.借款人申请借款 1.需求描述 2.相关数据库表 21.1.2.具体步骤 step1:借款人点击"我要借款" step2:展示借款信 ...
最新文章
- 2021中科院院士候选名单出炉:清华胡事民、南大周志华等人在列
- 【多线程】Synchronized及实现原理
- 「 每日一练,快乐水题 」717. 1比特与2比特字符
- java poi excel 单元格样式_java poi批量导出excel 设置单元格样式
- Deeplab unexpected label
- python需要掌握的词汇量_北大保安英语词汇量1.5万,会用Python编程,孟母三迁真有道理...
- 信息学奥赛C++语言:统计数字字符个数
- java填吧_请高手为我填上JAVA代码吧
- JS阻止冒泡方法(转)
- 【LOJ2127】「HAOI2015」按位或
- linux部署was找不到8879端口,WAS8.0与IHS集群安装与配置指导手册
- 找不到ADO.NET Entity Data Model模板或 sql server database project模板
- xp系统扫描仪服务器,xp系统扫描仪添加步骤全程的图文教程
- 大学英语B---词汇与语法
- Java-满天繁星案例(2)
- 社交网络分析的 R 基础:(三)向量、矩阵与列表
- 打包chromium浏览器
- Spring当中循环依赖很少有人讲,今天一起来学习!
- spring加载一个或者多个properties配置文件方法
- 数模每日小练习——数据处理——插值