Steps 步骤条:https://element.eleme.io/#/zh-CN/component/steps
Alert 警告
这个页面比较复杂,因此我们一步一步创建,熟悉页面结构
创建 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>
<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>
<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>
<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>
<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
}
)
})
},
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);
}
}
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
})
},
},
会导致后端服务器被请求两次,第一次,获取token失败,第二次才会获取成功,具体原因如下:
created方法默认是在前端服务器执行的,前端服务器脱离了浏览器环境,里面是没有cookie的,因为cookie在浏览器当中才有。
如果前端服务器从cookie中取数据这个过程失败了,nuxt会在浏览器端再发起一次请求,而浏览器端则能找到cookie,所以后端服务器就能拿到数据了。
所以,为了解决这个问题,需要将代码放到mounted中,因为mounted会等待页面彻底渲染完成才加载,而渲染正是在浏览器端完成的。
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;
}
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);
}
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
})
},
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);
}
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
}
})
},