尚融宝22-提交借款申请
目录
一、需求介绍
二、图片上传
(一)前端页面
(二)实现图片上传
三、数据字典展示
(一)后端
(二)前端
四、表单信息提交
(一)后端
1、VO对象(表单对象)
2、定义借款认证状态枚举
3、controller
4、service
(二)前端
五、获取借款人状态
(一)后端
1、borrowerController
2、service
(二)前端
一、需求介绍
step1:用户在个人中心点击 “立即借款” (http://localhost:3000/user/borrower)
step2:展示借款人信息认证页面
step3:借款人填写信息并提交
step4:展示等待审核页面
step5:平台审核
step6:显示审批结果
二、图片上传
(一)前端页面
<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><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><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><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><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>
(二)实现图片上传
前面四个success是el文件上传组件成功后的回调函数,response和file是组件为我们自动封装的,传递type的原因是要区别四张图片,上传阿里云时存储在不同文件中
这里前端我们要将整个表单封装到borrow对象中,比如年龄(borrow.age),还有附件(borrower.borrowerAttachList),即四张图片的信息(包括图片名字,图片类型,图片在阿里云上的地址)
其次当用户上传图片又删除后,我们需要删除已经上传阿里云的图片并删除borrower.borrowerAttachList里对应的信息,这里使用filter函数实现
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})})
},
在浏览器通过vue插件查看对象封装情况
三、数据字典展示
对于以下下拉表单选项的内容储存在数据字典dict表中,因此我们去查询数据库将数据字典对应的内容查询出来进行展示
思路:首先根据dict_code查询出该对象的id,然后通过这个id查询下面的子节点(通过子节点parent_id==父节点id)
(一)后端
DictController
@ApiOperation("根据dictCode查询下级节点")@GetMapping("/findByDictCode/{dictCode}")public R findByDictCode(@ApiParam(value = "节点编码", 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); // 父节点return this.listByParentId(dict.getId());}@Overridepublic List<Dict> listByParentId(Long parent_id) {try {// 首先查询redis有无数据List<Dict> dictList = (List<Dict>)redisTemplate.opsForValue().get("src:core:dictList" + parent_id);// 如果查询到数据直接返回if(dictList != null) {log.info("redis查到数据,准备返回");return dictList;}} catch (Exception e) {log.error("redis服务器异常:" + ExceptionUtils.getStackTrace(e));}// redis没有数据就查询数据库log.info("查询数据库");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 {// 将查询到的数据放入redislog.info("将数据库查到的数据放入redis");redisTemplate.opsForValue().set("src:core:dictList" + parent_id, dicts, 5, TimeUnit.MINUTES);} catch (Exception e) {log.error("redis服务器异常:" + ExceptionUtils.getStackTrace(e));}// 返回查询到的数据return dicts;}
(二)前端
pages/user/borrower.vue中调用接口
created() {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})},
四、表单信息提交
(一)后端
1、VO对象(表单对象)
service-core微服务,创建BorrowerVO,对应的是填写借款申请时的表单对象VO(value object)
@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:认证失败)
@AllArgsConstructor
@Getter
//@ToString
public enum BorrowerStatusEnum {NO_AUTH(0, "未认证"),AUTH_RUN(1, "认证中"),AUTH_OK(2, "认证成功"),AUTH_FAIL(-1, "认证失败"),;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());//认证中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);
}
(二)前端
pages/user/borrower.vue 脚本
save() {// debuggerthis.submitBtnDisabled = truethis.$axios.$post('/api/core/borrower/save', this.borrower).then((response) => {this.active = 1})
},
五、获取借款人状态
当借款人申请后,再一次刷新页面会发现仍然是表单,这里正确的是应该显示认证中,认证成功或者认证失败,所以在加载页面之前我们应该请求后端获取borrowerStatus
这里的认证状态是由active和borrowerstatus共同决定的
(一)后端
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;
}
(二)前端
pages/user/borrower.vue 脚本
created() {// 这里由initSelected换成getUserInfo,获取borrowerStatus 状态后再决定是否调用initSelectedthis.getUserInfo()
},
//获取借款人信息
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}})
}
相关文章:

尚融宝22-提交借款申请
目录 一、需求介绍 二、图片上传 (一)前端页面 (二)实现图片上传 三、数据字典展示 (一)后端 (二)前端 四、表单信息提交 (一)后端 1、VO对象&…...

机器学习在生态、环境经济学中的实践技术应用及论文写作
近年来,人工智能领域已经取得突破性进展,对经济社会各个领域都产生了重大影响,结合了统计学、数据科学和计算机科学的机器学习是人工智能的主流方向之一,目前也在飞快的融入计量经济学研究。表面上机器学习通常使用大数据…...

Android硬件通信之 WIFI通信
一,简介 1.1 随着网络的普及和通信技术的发展,网络的传输速度也越来越快,wifi技术也还成为手机设备最基本的配置。我们可以通过wifi实现手机与手机之前的信息传输,当然也可以与任意一台有wifi模块的其它设备传输。 1.2 wifi与蓝…...

面试官:“请描述一下Android系统的启动流程”
作者:OpenGL 前言 什么是Android启动流程呢?其实指的就是我们Android系统从按下电源到显示界面的整个过程。 当我们把手机充好电,按下电源,手机会弹出相应启动界面,在等了一段时间之后,会弹出我们熟悉的主…...
k8s delete node 后 重启kubelet会自己加入到集群 ?
原因 当执行kubectl delete node命令时,Kubernetes API服务器会收到该节点的删除请求,并将其从集群中删除。此时,kubelet服务在该节点上仍然在运行,但已经不再与集群通信。 当您重启kubelet服务时,它会重新向API服务…...

REXROTH液压方向阀安装须知
安装规程 阀安装到系统之前,应该对照订货型号比较其型号说明。 确认阀的连接表面和底板无水分,没有油。 - 清洁: ‧ 安装元件时,确认工业阀和周围干净 ‧ 油箱须密闭,以防止外部污染 ‧ 安装之前&…...
【数据结构实验】哈夫曼树
【数据结构实验】哈夫曼树 简介: 为一个信息收发站编写一个哈夫曼码的编/译码系统。文末贴出了源代码。 需求分析 完整的系统需要具备完整的功能,包含初始化、编码、译码、印代码文件和印哈夫曼树,因此需要进行相应的文件操作进行配合。哈…...

浏览器不好用?插件来帮忙
一、目的 浏览器本身具备的功能并不完善,不同的用户可以为自己浏览器增加想要功能,使得浏览器更能符合自己的需求,提高浏览器使用的舒适度 二、推荐插件 AdblockPlus LastPass(密码记录,全平台通用) Dar…...

Qt Quick - 容器控件综述
Qt Quick - 容器控件综述 一、概述二、ApplicationWindow Control三、Frame Control四、GroupBox Control五、Page Control六、Pane Control七、ScrollView Control八、StackView Control九、SwipeView Control十、TabBarControl十一、ToolBar控件 一、概述 Qt Quick Controls…...
面试题30天打卡-day06
1、什么是反射机制?说说反射机制的优缺点、应用场景? 反射机制:Java的反射机制是在运行状态,对于任意一个类,都能够动态的获得这个类的属性和方法;对于一个对象,都能动态的调用它当中的方法和属…...

Spring Boot的基础使用和< artifactId>spring-boot-maven-plugin</ artifactId>爆红的处理
Spring Boot的基础使用和< artifactId>spring-boot-maven-plugin</ artifactId>爆红的处理 Spring Boot概述 微服务概述 微服务Microservices是一种软件架构风格,他是以专注于单一责任与功能的小型功能区块Small Building Blocks 为基础,…...

项目管理中的必不可少的强大工具有哪些?
在项目管理中,我们总是想寻求一套功能强大的工具,来满足我们多样化的需求。但往往事与愿违,这样强大的工具总是费用高,操作复杂,需安装多个插件。下面,我就给大家推荐一款项目管理软件 ~Zoho Projects&…...

嵌入式学习笔记——SPI通信的应用
SPI通信的应用 前言屏幕分类1.3OLED概述驱动芯片框图原理图通信时序显示的方式页地址、列地址初始化指令 程序设计初始化代码初始化写数据与写命令清屏函数 初始化代码字符显示函数 总结 前言 上一篇中介绍了STM32的SPI通信,并根据框图和寄存器进行了SPI通信的初始…...
.Net下企业应用系统架构构建心得
在开始架构设计之前,需要了解一下架构是什么,按照IEEE标准的定义是: Architecture 是一个系统的基本组织,它蕴含于系统的组件中、组件之间的相互关系中、组件与环境的相互关系中、以及呈现于其设计和演进的原则中。 (The embodied…...
【社区图书馆】关于Mybatis原理学习的读后感
1、为什么会看原理书籍 Mybatis是我们Java后端开发中的主流ORM框架,基本都会在工作中用到。所以,是既熟悉,又陌生。熟悉是因为一直都在使用,而陌生则是对于其内部原理还不够深入。刚好近期的工作中,又遇到了一个需求&a…...

C++ Primer阅读笔记--表达式和运算符的使用
1--左值和右值 C 的表达式有右值(rvalue, are-value)和左值(lvalue, ell-value)两个形式;当一个对象被用作右值时,使用的是对象的值(内容);当对象被用作左值时࿰…...
npm install xxx的执行过程及示例
当你在终端中执行npm install xxx命令时,npm会执行以下步骤来安装软件包: 检查本地npm缓存中是否有该软件包。 如果本地npm缓存中已经存在该软件包,npm将直接从缓存中提取软件包并安装。这将显著加快安装速度,因为npm无需从网络下…...

excel数据分析比赛
基础 sql:百度网盘 请输入提取码 excel函数 <...
Git使用GitHub说明
GitHub为公网代码托管仓库,Git可以将本地仓库推送到GitHub管理。 步骤:1、注册GitHub账号 2、创建仓库(会得到一个仓库地址) 3、推送本地仓库 git remote add origin https://github.com/jianshengchuanqi/xuesezhanjiang.git…...

这些不可不知的JVM知识
JVM是面试中必问的部分,本文通过思维导图以面向面试的角度整理JVM中不可不知的知识。 先上图: JVM必备知识 1、JVM基本概念 1.1、JVM是什么 JVM 的全称是 「Java Virtual Machine」,也就是我们耳熟能详的 Java 虚拟机。 JVM具备着计算机的…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...