邢臺(tái)網(wǎng)站建設(shè)03191688網(wǎng)絡(luò)營(yíng)銷(xiāo)的特點(diǎn)不包括
目錄
一、需求介紹
二、圖片上傳
(一)前端頁(yè)面
(二)實(shí)現(xiàn)圖片上傳
三、數(shù)據(jù)字典展示
(一)后端
(二)前端?
四、表單信息提交
(一)后端
1、VO對(duì)象(表單對(duì)象)
2、定義借款認(rèn)證狀態(tài)枚舉
3、controller
4、service
(二)前端
五、獲取借款人狀態(tài)
(一)后端
1、borrowerController
2、service
(二)前端
一、需求介紹
step1:用戶(hù)在個(gè)人中心點(diǎn)擊 “立即借款”? (http://localhost:3000/user/borrower)
step2:展示借款人信息認(rèn)證頁(yè)面
step3:借款人填寫(xiě)信息并提交
step4:展示等待審核頁(yè)面
?
step5:平臺(tái)審核
step6:顯示審批結(jié)果
?
二、圖片上傳
(一)前端頁(yè)面
<template><div class="personal-main"><div class="personal-pay"><h3><i>借款人信息認(rèn)證</i></h3><el-steps :active="active" style="margin: 40px"><el-step title="填寫(xiě)借款人信息"></el-step><el-step title="提交平臺(tái)審核"></el-step><el-step title="等待認(rèn)證結(jié)果"></el-step></el-steps><div v-if="active === 0" class="user-borrower"><h6>個(gè)人基本信息</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="學(xué)歷"><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="行業(yè)"><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="還款來(lái)源"><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><h6>聯(lián)系人信息</h6><el-form label-width="120px"><el-form-item label="聯(lián)系人姓名"><el-col :span="5"><el-input v-model="borrower.contactsName" /></el-col></el-form-item><el-form-item label="聯(lián)系人手機(jī)"><el-col :span="5"><el-input v-model="borrower.contactsMobile" /></el-col></el-form-item><el-form-item label="聯(lián)系人關(guān)系"><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><h6>身份認(rèn)證信息</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="身份證國(guó)徽面"><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="房產(chǎn)信息"><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="車(chē)輛信息"><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><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="您的認(rèn)證申請(qǐng)已成功提交,請(qǐng)耐心等待"type="warning"show-icon:closable="false">我們將在2小時(shí)內(nèi)完成審核,審核時(shí)間為周一至周五8:00至20:00。</el-alert></div></div><div v-if="active === 2"><div style="margin-top:40px;"><el-alertv-if="borrowerStatus === 2"title="您的認(rèn)證審批已通過(guò)"type="success"show-icon:closable="false"></el-alert><el-alertv-if="borrowerStatus === -1"title="您的認(rèn)證審批未通過(guò)"type="error"show-icon:closable="false"></el-alert></div></div></div></div>
</template>
(二)實(shí)現(xiàn)圖片上傳
前面四個(gè)success是el文件上傳組件成功后的回調(diào)函數(shù),response和file是組件為我們自動(dòng)封裝的,傳遞type的原因是要區(qū)別四張圖片,上傳阿里云時(shí)存儲(chǔ)在不同文件中
這里前端我們要將整個(gè)表單封裝到borrow對(duì)象中,比如年齡(borrow.age),還有附件(borrower.borrowerAttachList),即四張圖片的信息(包括圖片名字,圖片類(lèi)型,圖片在阿里云上的地址)
其次當(dāng)用戶(hù)上傳圖片又刪除后,我們需要?jiǎng)h除已經(jīng)上傳阿里云的圖片并刪除borrower.borrowerAttachList里對(duì)應(yīng)的信息,這里使用filter函數(shù)實(shí)現(xiàn)
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服務(wù)器上的內(nèi)容this.$axios.$delete('/api/oss/file/remove?url=' + file.response.data.url).then((response) => {// debuggerconsole.log('遠(yuǎn)程刪除')this.borrower.borrowerAttachList = this.borrower.borrowerAttachList.filter(function(item) {console.log('item', item)return item.imageUrl != file.response.data.url})})
},
?在瀏覽器通過(guò)vue插件查看對(duì)象封裝情況
三、數(shù)據(jù)字典展示
對(duì)于以下下拉表單選項(xiàng)的內(nèi)容儲(chǔ)存在數(shù)據(jù)字典dict表中,因此我們?nèi)ゲ樵?xún)數(shù)據(jù)庫(kù)將數(shù)據(jù)字典對(duì)應(yīng)的內(nèi)容查詢(xún)出來(lái)進(jìn)行展示
?
思路:首先根據(jù)dict_code查詢(xún)出該對(duì)象的id,然后通過(guò)這個(gè)id查詢(xún)下面的子節(jié)點(diǎn)(通過(guò)子節(jié)點(diǎn)parent_id==父節(jié)點(diǎn)id)
(一)后端
DictController
@ApiOperation("根據(jù)dictCode查詢(xún)下級(jí)節(jié)點(diǎn)")@GetMapping("/findByDictCode/{dictCode}")public R findByDictCode(@ApiParam(value = "節(jié)點(diǎn)編碼", required = true)@PathVariable String dictCode) {List<Dict> dictList = dictService.findByDictCode(dictCode);return R.ok().data("dictList", dictList);}
DictService
List<Dict> findByDictCode(String dictCode);
DictServiceImpl?
@Overridepublic List<Dict> findByDictCode(String dictCode) {QueryWrapper<Dict> wrapper = new QueryWrapper<>();wrapper.eq("dict_code", dictCode);Dict dict = baseMapper.selectOne(wrapper); // 父節(jié)點(diǎn)return this.listByParentId(dict.getId());}@Overridepublic List<Dict> listByParentId(Long parent_id) {try {// 首先查詢(xún)r(jià)edis有無(wú)數(shù)據(jù)List<Dict> dictList = (List<Dict>)redisTemplate.opsForValue().get("src:core:dictList" + parent_id);// 如果查詢(xún)到數(shù)據(jù)直接返回if(dictList != null) {log.info("redis查到數(shù)據(jù),準(zhǔn)備返回");return dictList;}} catch (Exception e) {log.error("redis服務(wù)器異常:" + ExceptionUtils.getStackTrace(e));}// redis沒(méi)有數(shù)據(jù)就查詢(xún)數(shù)據(jù)庫(kù)log.info("查詢(xún)數(shù)據(jù)庫(kù)");QueryWrapper<Dict> wrapper = new QueryWrapper<>();wrapper.eq("parent_id", parent_id);List<Dict> dicts = baseMapper.selectList(wrapper);dicts.forEach(dict -> {dict.setHasChildren(this.hasChildren(dict.getId()));});try {// 將查詢(xún)到的數(shù)據(jù)放入redislog.info("將數(shù)據(jù)庫(kù)查到的數(shù)據(jù)放入redis");redisTemplate.opsForValue().set("src:core:dictList" + parent_id, dicts, 5, TimeUnit.MINUTES);} catch (Exception e) {log.error("redis服務(wù)器異常:" + ExceptionUtils.getStackTrace(e));}// 返回查詢(xún)到的數(shù)據(jù)return dicts;}
(二)前端?
pages/user/borrower.vue中調(diào)用接口
created() {this.initSelected()},initSelected() {//學(xué)歷列表this.$axios.$get('/api/core/dict/findByDictCode/education').then((response) => {this.educationList = response.data.dictList})//行業(yè)列表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})//還款來(lái)源列表this.$axios.$get('/api/core/dict/findByDictCode/returnSource').then((response) => {this.returnSourceList = response.data.dictList})//聯(lián)系人關(guān)系列表this.$axios.$get('/api/core/dict/findByDictCode/relation').then((response) => {this.contactsRelationList = response.data.dictList})},
四、表單信息提交
(一)后端
1、VO對(duì)象(表單對(duì)象)
service-core微服務(wù),創(chuàng)建BorrowerVO,對(duì)應(yīng)的是填寫(xiě)借款申請(qǐng)時(shí)的表單對(duì)象VO(value object)
@Data
@ApiModel(description="借款人認(rèn)證信息")
public class BorrowerVO {@ApiModelProperty(value = "性別(1:男 0:女)")private Integer sex;@ApiModelProperty(value = "年齡")private Integer age;@ApiModelProperty(value = "學(xué)歷")private Integer education;@ApiModelProperty(value = "是否結(jié)婚(1:是 0:否)")private Boolean marry;@ApiModelProperty(value = "行業(yè)")private Integer industry;@ApiModelProperty(value = "月收入")private Integer income;@ApiModelProperty(value = "還款來(lái)源")private Integer returnSource;@ApiModelProperty(value = "聯(lián)系人名稱(chēng)")private String contactsName;@ApiModelProperty(value = "聯(lián)系人手機(jī)")private String contactsMobile;@ApiModelProperty(value = "聯(lián)系人關(guān)系")private Integer contactsRelation;@ApiModelProperty(value = "借款人附件資料")private List<BorrowerAttach> borrowerAttachList;
}
2、定義借款認(rèn)證狀態(tài)枚舉
BorrowerStatusEnum
數(shù)據(jù)庫(kù)設(shè)計(jì)中對(duì)應(yīng)認(rèn)證狀態(tài)status (0:未認(rèn)證,1:認(rèn)證中, 2:認(rèn)證通過(guò), -1:認(rèn)證失敗)
@AllArgsConstructor
@Getter
//@ToString
public enum BorrowerStatusEnum {NO_AUTH(0, "未認(rèn)證"),AUTH_RUN(1, "認(rèn)證中"),AUTH_OK(2, "認(rèn)證成功"),AUTH_FAIL(-1, "認(rèn)證失敗"),;private Integer status;private String msg;public static String getMsgByStatus(int status) {BorrowerStatusEnum arrObj[] = BorrowerStatusEnum.values();for (BorrowerStatusEnum obj : arrObj) {if (status == obj.getStatus().intValue()) {return obj.getMsg();}}return "";}
}
3、controller
borrowerController
@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());//認(rèn)證中baseMapper.insert(borrower);//保存附件List<BorrowerAttach> borrowerAttachList = borrowerVO.getBorrowerAttachList();borrowerAttachList.forEach(borrowerAttach -> {borrowerAttach.setBorrowerId(borrower.getId());borrowerAttachMapper.insert(borrowerAttach);});//更新會(huì)員狀態(tài),更新為認(rèn)證中userInfo.setBorrowAuthStatus(BorrowerStatusEnum.AUTH_RUN.getStatus());userInfoMapper.updateById(userInfo);
}
(二)前端
pages/user/borrower.vue?腳本
save() {// debuggerthis.submitBtnDisabled = truethis.$axios.$post('/api/core/borrower/save', this.borrower).then((response) => {this.active = 1})
},
五、獲取借款人狀態(tài)
當(dāng)借款人申請(qǐng)后,再一次刷新頁(yè)面會(huì)發(fā)現(xiàn)仍然是表單,這里正確的是應(yīng)該顯示認(rèn)證中,認(rèn)證成功或者認(rèn)證失敗,所以在加載頁(yè)面之前我們應(yīng)該請(qǐng)求后端獲取borrowerStatus
這里的認(rèn)證狀態(tài)是由active和borrowerstatus共同決定的
(一)后端
1、borrowerController
@ApiOperation("獲取借款人認(rèn)證狀態(tài)")
@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;
}
(二)前端
?pages/user/borrower.vue?腳本
created() {// 這里由initSelected換成getUserInfo,獲取borrowerStatus 狀態(tài)后再?zèng)Q定是否調(diào)用initSelectedthis.getUserInfo()
},
//獲取借款人信息
getUserInfo() {this.$axios.$get('/api/core/borrower/auth/getBorrowerStatus').then((response) => {this.borrowerStatus = response.data.borrowerStatusif (this.borrowerStatus === 0) {//未認(rèn)證this.active = 0//獲取下拉列表this.initSelected()} else if (this.borrowerStatus === 1) {//認(rèn)證中this.active = 1} else if (this.borrowerStatus === 2) {//認(rèn)證成功this.active = 2} else if (this.borrowerStatus === -1) {//認(rèn)證失敗this.active = 2}})
}