> 文章列表 > 核心业务3:借款人借款申请

核心业务3:借款人借款申请

核心业务3:借款人借款申请

核心业务3:借款人借款申请

1.借款人借款申请业务流程图

2.借款项数据库绑定

---------------------借款申请流程----------------------

3.借款申请流程

4.前端代码逻辑

5.后端代码逻辑

---------------------借款申请流程----------------------

核心业务3:借款人借款申请

1.借款人借款申请业务流程图

核心业务3:借款人借款申请

①此时用户已经获得了积分,可以在额度申请页面点击我要借款

核心业务3:借款人借款申请

②点击我要借款后展示借款信息填写页

核心业务3:借款人借款申请

③借款信息提交后显示等待审核

核心业务3:借款人借款申请

④后台管理员审核技术后获取审核结果

核心业务3:借款人借款申请

2.借款项数据库绑定

①数据库表

borrow_info
核心业务3:借款人借款申请
integral_grade
核心业务3:借款人借款申请

②关联

  • borrow_info表通过user_id与user_info关联,即一个user只能发起一次借款
  • user_info的积分字段可查integral_grade表获取对应额度,然后borrow_info根据user_info的额度来发起借款
  • borrow表和borrow_info表无关,两者都只是通过user_id与user_info关联,一个是借款额度申请表单,一个是借款申请表单

3.借款申请流程

①前端

  • 用户在注册登陆绑定数据和获得额度之后,可以发起我要借款
  • 进入界面判断借款的状态,如果未借款进入表单界面,如果其他状态跳到响应的界面
  • 表单数据的填写,用户可以看到自己的额度(调用api),用户也可以再下拉列表里填写数据(调用api)
  • 用户填写完表单后提交后台

②后端

  • 用户刚进入借款页面判断用户借款状态(通过user_id查询borrow_info看用户借款状态)
  • 用户未发起借款,需要返回数据字典数据初始化下拉列表,需要返回用户的借款额度
  • 用户提交表单,需要校验(防止恶意用户跳过入口直接访问后台),然后保存数据到borrow_info表

4.前端代码逻辑

①前端封装表单对象

核心业务3:借款人借款申请

②前端调用接口

核心业务3:借款人借款申请

③前端代码

  • 增加按钮到借款额度申请成功页
    srb-site\\pages\\user\\borrower.vue
    添加按钮到审批通过组件下
 <!--在审批通过后,增加我要借款按钮,进入借款信息页面--><NuxtLink to="/user/apply" v-if="borrowerStatus === 2"><el-button style="margin-top:20px;" type="success">我要借款</el-button></NuxtLink>
  • 借款申请页面
    srb-site\\pages\\user\\apply.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"><el-form label-width="120px"><el-form-item label="借款金额"><el-col :span="6"><el-input v-model="borrowInfo.amount" /></el-col><el-col :span="6">&nbsp;&nbsp;您最多可借款{{ borrowAmount }}</el-col></el-form-item><el-form-item label="期数"><el-select v-model="borrowInfo.period"><el-option :value="1" label="1个月" /><el-option :value="3" label="3个月" /><el-option :value="6" label="6个月" /><el-option :value="9" label="9个月" /><el-option :value="12" label="12个月" /><el-option :value="24" label="24个月" /></el-select></el-form-item><el-form-item label="还款方式"><el-select v-model="borrowInfo.returnMethod"><el-optionv-for="item in returnMethodList":key="item.value":label="item.name":value="item.value"/></el-select></el-form-item><el-form-item label="资金用途"><el-select v-model="borrowInfo.moneyUse"><el-optionv-for="item in moneyUseList":key="item.value":label="item.name":value="item.value"/></el-select></el-form-item><el-form-item label="年利率"><el-col :span="6"><el-input v-model="borrowInfo.borrowYearRate"><template slot="append">%</template></el-input></el-col><el-col :span="8">&nbsp;&nbsp;年利率越高,借款越容易成功。</el-col></el-form-item><el-form-item><el-buttontype="primary":disabled="submitBtnDisabled"@click="save">提交</el-button></el-form-item></el-form><el-alerttitle="您提供的任何信息尚融宝都承诺予以保护,不会挪作他用。"type="warning":closable="false"></el-alert></div><div v-if="active === 1"><div style="margin-top:40px;"><el-alerttitle="您的借款申请已成功提交,请耐心等待"type="warning"show-icon:closable="false">我们将在10分钟内完成审核,审核时间为周一至周五8:0020:00</el-alert></div></div><div v-if="active === 2"><div style="margin-top:40px;"><el-alertv-if="borrowInfoStatus === 2"title="您的借款申请审批已通过"type="success"show-icon:closable="false"></el-alert><el-alertv-if="borrowInfoStatus === -1"title="您的借款申请审批未通过"type="error"show-icon:closable="false"></el-alert></div></div></div></div>
</template><script>
export default {data() {return {active: null, //步骤borrowInfoStatus: null, //审批状态//借款申请borrowInfo: {borrowYearRate: '12',},borrowAmount: 0, //借款额度submitBtnDisabled: false,returnMethodList: [], //还款方式列表moneyUseList: [], //资金用途列表}},methods: {//初始化下拉列表的数据initSelected() {//还款方式列表this.$axios.$get('/api/core/dict/findByDictCode/returnMethod').then((response) => {this.returnMethodList = response.data.dictList})//资金用途列表this.$axios.$get('/api/core/dict/findByDictCode/moneyUse').then((response) => {this.moneyUseList = response.data.dictList})},//获取借款额度getBorrowAmount() {this.$axios.$get('/api/core/borrowInfo/auth/getBorrowAmount').then((response) => {this.borrowAmount = response.data.borrowAmount})},//提交借款申请save() {// this.submitBtnDisabled = truethis.$axios.$post('/api/core/borrowInfo/auth/save', this.borrowInfo).then((response) => {this.active = 1})},//获取借款审批状态getBorrowInfoStatus() {this.$axios.$get('/api/core/borrowInfo/auth/getBorrowInfoStatus').then((response) => {this.borrowInfoStatus = response.data.borrowInfoStatusif (this.borrowInfoStatus === 0) {//未认证this.active = 0//获取借款额度this.getBorrowAmount()//初始化下拉列表this.initSelected()} else if (this.borrowInfoStatus === 1) {//审批中this.active = 1} else if (this.borrowInfoStatus === 2) {//审批成功this.active = 2} else if (this.borrowInfoStatus === -1) {//审批失败this.active = 2}})},},created() {//created方法默认情况下在前端服务器执行,而不是在浏览器执行,前端服务器端执行失败,在浏览器端还会再发起请求(浏览器端成功)//即在nuxt前端服务器初始化时候并没有带token,故可以用mounted渲染,mounted一定在浏览器端执行(渲染完成后执行)//获取借款额度//this.getBorrowAmount()//初始化下拉列表//this.initSelected()//获取审批状态this.getBorrowInfoStatus()},//监听某一个值,如果这一值一旦改变则调用watch: {'borrowInfo.amount'(value) {if (value > this.borrowAmount) {let _this = thisthis.$alert('您的借款额度不足!', {type: 'error',//当错误信息弹出完毕之后点击确定,然后执行回调函数callback() {//this的作用域和外部的作用域不一样(callback的作用域和外面的this不一样,需要传入this)_this.borrowInfo.amount = _this.borrowAmount},})}},},
}
</script>

④前端代码逻辑难点

  • 需要监听额度字段如果超过最大额度设置其值为最大额度
    用watch方法监听字段
    核心业务3:借款人借款申请

5.后端代码逻辑

①后端对象

  • borrow_info对象即可不需要专门创建vo对象

②后端接口

核心业务3:借款人借款申请

③后端代码

  • controller
package com.atguigu.srb.core.controller.api;import com.atguigu.common.result.R;
import com.atguigu.srb.base.util.JwtUtils;
import com.atguigu.srb.core.pojo.entity.BorrowInfo;
import com.atguigu.srb.core.service.BorrowInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;@Api(tags = "借款信息")
@RestController
@RequestMapping("/api/core/borrowInfo")
@Slf4j
public class BorrowInfoController {@Resourceprivate BorrowInfoService borrowInfoService;@ApiOperation("获取借款额度")@GetMapping("/auth/getBorrowAmount")public R getBorrowAmount(HttpServletRequest request) {String token = request.getHeader("token");Long userId = JwtUtils.getUserId(token);BigDecimal borrowAmount = borrowInfoService.getBorrowAmount(userId);return R.ok().data("borrowAmount", borrowAmount);}@ApiOperation("提交借款申请")@PostMapping("/auth/save")public R save(@RequestBody BorrowInfo borrowInfo, HttpServletRequest request) {//目标就是把用户提交的数据保存到数据表borrow_info中//该接口防止恶意攻击//前端不提供入口 + 后端进行校验(是否绑定,是否审批借款申请)String token = request.getHeader("token");Long userId = JwtUtils.getUserId(token);//将借款信息存储数据库,校验用户是否绑定和审批borrowInfoService.saveBorrowInfo(borrowInfo, userId);return R.ok().message("提交成功");}@ApiOperation("获取借款申请审批状态")@GetMapping("/auth/getBorrowInfoStatus")public R getBorrowerStatus(HttpServletRequest request){String token = request.getHeader("token");Long userId = JwtUtils.getUserId(token);Integer status = borrowInfoService.getStatusByUserId(userId);return R.ok().data("borrowInfoStatus", status);}
}
  • service
package com.atguigu.srb.core.service;import com.atguigu.srb.core.pojo.entity.BorrowInfo;
import com.baomidou.mybatisplus.extension.service.IService;import java.math.BigDecimal;/*** <p>* 借款信息表 服务类* </p>** @author Likejin* @since 2023-04-09*/
public interface BorrowInfoService extends IService<BorrowInfo> {BigDecimal getBorrowAmount(Long userId);void saveBorrowInfo(BorrowInfo borrowInfo, Long userId);Integer getStatusByUserId(Long userId);
}
package com.atguigu.srb.core.service.impl;import com.atguigu.common.exception.Assert;
import com.atguigu.common.result.ResponseEnum;
import com.atguigu.srb.core.enums.BorrowInfoStatusEnum;
import com.atguigu.srb.core.enums.BorrowerStatusEnum;
import com.atguigu.srb.core.enums.UserBindEnum;
import com.atguigu.srb.core.mapper.BorrowInfoMapper;
import com.atguigu.srb.core.mapper.IntegralGradeMapper;
import com.atguigu.srb.core.mapper.UserInfoMapper;
import com.atguigu.srb.core.pojo.entity.BorrowInfo;
import com.atguigu.srb.core.pojo.entity.IntegralGrade;
import com.atguigu.srb.core.pojo.entity.UserInfo;
import com.atguigu.srb.core.service.BorrowInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;/*** <p>* 借款信息表 服务实现类* </p>** @author Likejin* @since 2023-04-09*/
@Service
public class BorrowInfoServiceImpl extends ServiceImpl<BorrowInfoMapper, BorrowInfo> implements BorrowInfoService {@Resourceprivate UserInfoMapper userInfoMapper;@Resourceprivate IntegralGradeMapper integralGradeMapper;/*** @param userId:* @return BigDecimal* @author Likejin* @description 根据用户id查询用户积分,根据积分获取用户额度* @date 2023/4/16 14:30*/@Overridepublic BigDecimal getBorrowAmount(Long userId) {//获取用户积分UserInfo userInfo = userInfoMapper.selectById(userId);Assert.notNull(userInfo, ResponseEnum.LOGIN_MOBILE_ERROR);Integer integral = userInfo.getIntegral();//根据积分获取用户额度QueryWrapper<IntegralGrade> integralGradeQueryWrapper = new QueryWrapper<>();//做一个区间比较,le为大于左边,ge为小于右边integralGradeQueryWrapper.le("integral_start",integral).ge("integral_end",integral);IntegralGrade integralGrade = integralGradeMapper.selectOne(integralGradeQueryWrapper);if(integralGrade == null){return new BigDecimal("0");}return integralGrade.getBorrowAmount();}/*** @param borrowInfo:* @param userId:* @return void* @author Likejin* @description 将借款信息存储数据库,校验用户是否绑定和审批* @date 2023/4/16 15:11*/@Overridepublic void saveBorrowInfo(BorrowInfo borrowInfo, Long userId) {//校验绑定状态和借款人额度审批状态UserInfo userInfo = userInfoMapper.selectById(userId);Assert.isTrue(userInfo.getBindStatus().intValue() == UserBindEnum.BIND_OK.getStatus().intValue(),ResponseEnum.USER_NO_BIND_ERROR);Assert.isTrue(userInfo.getBorrowAuthStatus().intValue() == BorrowerStatusEnum.AUTH_OK.getStatus().intValue(),ResponseEnum.USER_NO_AMOUNT_ERROR);//判断借款人额度是否充足BigDecimal borrowAmount = this.getBorrowAmount(userId);Assert.isTrue(borrowInfo.getAmount().doubleValue() <=borrowAmount.doubleValue(),ResponseEnum.USER_AMOUNT_LESS_ERROR);//存储borrower_info数据borrowInfo.setUserId(userId);//百分比转小数borrowInfo.setBorrowYearRate(borrowInfo.getBorrowYearRate().divide(new BigDecimal(100)));//设置借款申请的审核状态borrowInfo.setStatus(BorrowInfoStatusEnum.CHECK_RUN.getStatus());baseMapper.insert(borrowInfo);}/*** @param userId:* @return Integer* @author Likejin* @description 获取用户申请借款的状态* @date 2023/4/16 15:35*/@Overridepublic Integer getStatusByUserId(Long userId) {//根据user_id查询用户的借款申请状态QueryWrapper<BorrowInfo> borrowInfoQueryWrapper = new QueryWrapper<>();borrowInfoQueryWrapper.select("status").eq("user_id", userId);List<Object> objects = baseMapper.selectObjs(borrowInfoQueryWrapper);if(objects.size() == 0){//借款人尚未提交信息return BorrowInfoStatusEnum.NO_AUTH.getStatus();}Integer status = (Integer)objects.get(0);return status;}
}

④后端代码逻辑难点

  • 获取借款额度
    通过token获得user_id,然后通过user_id查询user_info获得积分,在通过查表integral_grade表的的区间查询(根据积分所在的区间查询对应的额度)获取额度
  • 提交借贷申请
    需要从token中拿到user_id,通过user_id校验user是否绑定和是否申请借款额度(防止恶意攻击),还需要通过user_id校验该user的额度是否没被申请的额度超过,封装数据(年利率前端传整型,后端小数,除以100),设置借款流程的状态borrow_info的status,保存数据到数据库。
  • 获取借款流程状态
    直接根据user_id查询borrow_info中的status即可。

未更新

未更新

未更新

未更新

未更新

未更新

未更新

未更新

未更新