需求


借款人信息表单

一、步骤导航

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>

二、借款人信息页面

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>

文件的上传/删除

前端

/pages/user/borrower.vue

    // 以下定义的多个方法是为了区分文件存储的路径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) {if (response.code === 0) {this.borrower.borrowerAttachList.push({imageName: file.name,imageUrl: response.data.url,imageType: type,})} else {this.$message.error(response.message)}},// 删除成功之后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((item) => {console.log('item', item)return item.imageUrl !== file.response.data.url})})},

表单数据展示

后端

controller

DictController.java

package com.indi.srb.core.controller.api;@Api(tags = "数据字典")
@RestController
@RequestMapping("/api/core/dict")
public class DictController {@Resourceprivate DictService dictService;@ApiOperation("根据节点编码查询列表")@GetMapping("/findByDictCode/{dictCode}")public R findByDictCode(@ApiParam(value = "节点编码",required = true)@PathVariable String dictCode) {List<Dict> dictList = dictService.findByDictCode(dictCode);return R.ok().setData("dictList", dictList);}
}

service

DictService.java

    List<Dict> findByDictCode(String dictCode);

DictServiceImpl.java

    @Overridepublic List<Dict> findByDictCode(String dictCode) {QueryWrapper<Dict> queryWrapper = new QueryWrapper<>();queryWrapper.eq("dict_code",dictCode);Dict dict = baseMapper.selectOne(queryWrapper);List<Dict> dictList = listByParentId(dict.getId());return dictList;}

前端

/pages/user/borrower.vue

  mounted() {this.initSelected()},
    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中执行呢?

会导致后端服务器被请求两次,第一次,获取token失败,第二次才会获取成功,具体原因如下:

created方法默认是在前端服务器执行的,前端服务器脱离了浏览器环境,里面是没有cookie的,因为cookie在浏览器当中才有。

如果前端服务器从cookie中取数据这个过程失败了,nuxt会在浏览器端再发起一次请求,而浏览器端则能找到cookie,所以后端服务器就能拿到数据了。

所以,为了解决这个问题,需要将代码放到mounted中,因为mounted会等待页面彻底渲染完成才加载,而渲染正是在浏览器端完成的。

表单数据提交

后端

vo

BorrowerVO.java

@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;
}

service

BorrowerService.java

    void saveBorrower(BorrowerVO borrowerVO, Long userId);

BorrowerServiceImpl.java

    @Resourceprivate UserInfoMapper userInfoMapper;@Resourceprivate BorrowerAttachMapper borrowerAttachMapper;@Transactional(rollbackFor = Exception.class)@Overridepublic void saveBorrower(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 -> {// 上面添加了borrower数据之后,此处就能直接得到id了// 应该是因为@TableId的原因borrowerAttach.setBorrowerId(borrower.getId());borrowerAttachMapper.insert(borrowerAttach);});userInfo.setBorrowAuthStatus(BorrowerStatusEnum.AUTH_RUN.getStatus());userInfoMapper.updateById(userInfo);}

controller

BorrowerController.java

package com.indi.srb.core.controller.api;@Api(tags = "借款人")
@RestController
@RequestMapping("/api/core/borrower")
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.saveBorrower(borrowerVO, userId);return R.ok().setMessage("提交成功");}
}

前端

pages/user/borrower.vue

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

获取表单状态

后端

controller

BorrowerController.java

    @ApiOperation("获取借款人状态")@GetMapping("/getBorrowerStatus")public R getBorrowerStatus(HttpServletRequest request) {String token = request.getHeader("token");log.info("getBorrowerStatus()方法中token的值:" + token);Long userId = JwtUtils.getUserId(token);Integer status = borrowerService.getBorrowerStatus(userId);return R.ok().setData("borrowerStatus", status);}

service

BorrowerService.java

    Integer getBorrowerStatus(Long userId);

BorrowerServiceImpl.java

    @Overridepublic Integer getBorrowerStatus(Long userId) {QueryWrapper<Borrower> queryWrapper = new QueryWrapper<>();queryWrapper.select("status").eq("user_id",userId);List<Object> objects = baseMapper.selectObjs(queryWrapper);if (objects.size() == 0) {return BorrowerStatusEnum.NO_AUTH.getStatus();}return (Integer) objects.get(0);}

前端


  created() {this.getBorrowerStatus()},
    getBorrowerStatus() {this.$axios.$get('/api/core/borrower/getBorrowerStatus').then((response) => {this.borrowerStatus = response.data.borrowerStatusif (this.borrowerStatus === 0) {this.active = 0this.initSelected()} else if (this.borrowerStatus === 1) {this.active = 1} else {this.active = 2}})},

27. 尚融宝申请借款额度相关推荐

  1. 29. 尚融宝借款申请

    需求描述 整体流程图 相关数据库表 获取借款额度 需求 step1:借款人在"借款人信息认证"界面点击"我要借款" step2:展示借款信息填写页面 后端 co ...

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

    19.申请借款额度 19.1.需求介绍 19.1.1.借款人申请额度 1.需求描述 平台管理员根据借款人个人信息设置积分,通过积分规则借款人可以获取额度. 2.相关数据库表 19.1.2.具体步骤 s ...

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

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

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

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

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

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

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

    5.管理平台前端搭建 5.1.搭建管理平台前端程序 5.1.1.vue-element-admin vue-element-admin是基于element-ui 的一套后台管理系统集成方案. GitH ...

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

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

  8. 尚融宝01-项目简介

    目录 一.项目简介 (一).项目名称 (二).项目介绍 (三).项目架构 (四).业务流程总结 二.信用贷款平台的类别 (一).银行系 (二).国资系 (三).民营系 三.业务流程 (一).投资人 ( ...

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

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

最新文章

  1. dubbo入门--Hello World
  2. Edison与Arduino通过USB对接通信
  3. C++ - 编写一个从字符串转变成长整型的函数
  4. mac安全与隐私只有两个选项,少了一个任何来源
  5. sqlserver 查询表锁死,解除表锁死
  6. java删除csv一行_如何删除两个CSV之间的不常见行?
  7. 探索ring0之内核概述
  8. 安装pangolin
  9. 阿里云上CentOS的图形访问
  10. vue.js源码学习分享(四)
  11. Oracle 逗号分割的字符串转换为可放入in的语句
  12. 电脑内录录音软件,可选择录音来源
  13. 计算机毕业论文选题 - 毕设选题推荐
  14. 杭州辣府餐饮JAVA_超全“滨江美食必打卡list”,不收藏会后悔!年前再去搓几顿啊~...
  15. 5“机”时代,如何掘金新价值和新机遇?
  16. “创宇ADS”获公安部颁发《计算机信息系统安全专用产品销售许可证》!
  17. 请问我这段多线程代码为什么会死机?
  18. 小程序——疫情下企业数字化的新方向
  19. activiti实战系列 activiti连线
  20. 苹果7显示无法接通激活服务器,打电话时,显示对方手机暂时无法接通是什么原因?答案其实很简单...

热门文章

  1. 洛必达法则的一种极简证明
  2. [推荐书籍]12本程序员必备书籍
  3. 小说作者推荐:张廉合集
  4. Dell电脑如何设置Fn键和其它功能键的组合
  5. Linux 内核配置项详解 myimx6
  6. 【第75题】给定一个字符串,将它转换成整数
  7. IOS 插屏广告弹窗
  8. 宠物粮竞争后半场:国牌与洋牌的「信任保卫战」
  9. python3 tk_python3.5 安装python3-tk
  10. 面试题:在9个点上画十条直线,每条直线上至少三个点