27. 尚融宝申请借款额度

需求

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

借款人信息表单

一、步骤导航

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-button
              type="primary"
              :disabled="submitBtnDisabled"
              @click="save"
            >
              提交
            </el-button>
          </el-form-item>
        </el-form>
      </div>
      <div v-if="active === 1">
        <div style="margin-top:40px;">
          <el-alert
            title="您的认证申请已成功提交,请耐心等待"
            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-alert
            v-if="borrowerStatus === 2"
            title="您的认证审批已通过"
            type="success"
            show-icon
            :closable="false"
          >
          </el-alert>
          <el-alert
            v-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_API
    return {
      active: 0, //步骤
      borrowerStatus: null,
      submitBtnDisabled: false,
      //借款人信息
      borrower: {
        borrowerAttachList: [],
      },
      educationList: [], //学历列表
      industryList: [], //行业列表
      incomeList: [], //月收入列表
      returnSourceList: [], //还款来源列表
      contactsRelationList: [], //联系人关系
      uploadUrl: BASE_API + '/api/oss/file/upload', //文件上传地址
    }
  },
  methods: {
    save() {
      this.submitBtnDisabled = true
      this.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-option
                       v-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-option
                       v-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-option
                       v-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-option
                       v-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-option
                       v-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) => {
          // debugger
          console.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 {
    @Resource
    private 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

    @Override
    public 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

    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private BorrowerAttachMapper borrowerAttachMapper;

	@Transactional(rollbackFor = Exception.class)
    @Override
    public 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 {
    @Resource
    private 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 = false
      this.$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

    @Override
    public 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.borrowerStatus
          if (this.borrowerStatus === 0) {
            this.active = 0
            this.initSelected()
          } else if (this.borrowerStatus === 1) {
            this.active = 1
          } else {
            this.active = 2
          }
        })
    },
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值