• 【金融项目】尚融宝项目(十一)


    21、借款申请

    21.1、需求介绍

    21.1.1、借款人申请借款

    1、需求描述

    在这里插入图片描述

    2、相关数据库表

    在这里插入图片描述

    21.1.2、具体步骤

    step1:借款人点击“我要借款”

    在这里插入图片描述

    step2:展示借款信息填写页面

    在这里插入图片描述

    step3:借款人填写信息并提交

    step4:展示等待审核页面

    在这里插入图片描述

    step5:平台审核

    step6:显示审批结果

    未通过

    在这里插入图片描述

    通过

    在这里插入图片描述

    21.2、获取借款额度

    21.2.1、获取借款额度

    1、实现思路

    (1)获取借款人积分

    (2)根据积分获取借款额度,借款人每次借款不能超过借款额度

    2、Controller

    BorrowInfoController

    package com.atguigu.srb.core.controller.api;
    
    @Api(tags = "借款信息")
    @RestController
    @RequestMapping("/api/core/borrowInfo")
    @Slf4j
    public class BorrowInfoController {
        @Resource
        private 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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3、Service

    接口:BorrowInfoService

    BigDecimal getBorrowAmount(Long userId);
    
    • 1

    实现:BorrowInfoServiceImpl

    package com.atguigu.srb.core.service.impl;
    
    @Service
    public class BorrowInfoServiceImpl extends ServiceImpl<BorrowInfoMapper, BorrowInfo> implements BorrowInfoService {
        @Resource
        private UserInfoMapper userInfoMapper;
        @Resource
        private IntegralGradeMapper integralGradeMapper;
        @Override
        public BigDecimal getBorrowAmount(Long userId) {
            //获取用户积分
            UserInfo userInfo = userInfoMapper.selectById(userId);
            Assert.notNull(userInfo, ResponseEnum.LOGIN_MOBILE_ERROR);
            Integer integral = userInfo.getIntegral();
            //根据积分查询借款额度
            QueryWrapper<IntegralGrade> queryWrapper = new QueryWrapper<>();
            queryWrapper.le("integral_start", integral);
            queryWrapper.ge("integral_end", integral);
            IntegralGrade integralGradeConfig = integralGradeMapper.selectOne(queryWrapper);
            if(integralGradeConfig == null){
                return BigDecimal.ZERO;
            }
            return integralGradeConfig.getBorrowAmount();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    21.2.2、借款入口前端

    pages/user/borrower.vue

    在这里插入图片描述

    <NuxtLink to="/user/apply" v-if="borrowerStatus === 2">
      <el-button style="margin-top:20px;" type="success">
        我要借款
      el-button>
    NuxtLink>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    21.2.3、借款申请

    1、页面

    pages/user/apply.vue

    2、获取下拉列表

    methods中定义

    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
            })
        },
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    mounted中调用

      mounted() {
        
        //初始化下拉列表
        this.initSelected()
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3、获取借款额度

    methods中定义

        //获取借款额度
        getBorrowAmount() {
          this.$axios
            .$get('/api/core/borrowInfo/auth/getBorrowAmount')
            .then((response) => {
              this.borrowAmount = response.data.borrowAmount
            })
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    created中调用

      mounted() {
        //获取借款额度
        this.getBorrowAmount()
          
        //初始化下拉列表
        ......
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4、判断借款额度

    借款人每次借款不能超过借款额度

      watch: {
        'borrowInfo.amount'(value) {
          if (value > this.borrowAmount) {
            let _this = this
            this.$alert('您的借款额度不足!', {
              type: 'error',
              callback() {
                _this.borrowInfo.amount = _this.borrowAmount
              },
            })
          }
        },
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    21.3、提交借款申请

    21.3.1、后端实现

    1、实现思路

    借款人提交借款要判断借款人账户绑定状态与借款人信息审批状态,只有这两个状态都成立才能借款,这两个状态都在会员表中

    目标:将借款申请表单中用户填写的数据保存在borrow_info数据库表中

    2、枚举

    BorrowInfoStatusEnum

        NO_AUTH(0, "未提交"),
        CHECK_RUN(1, "审核中"),
        CHECK_OK(2, "审核通过"),
        CHECK_FAIL(-1, "审核不通过"),
        ;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    状态(0:未提交,1:审核中, 2:审核通过, -1:审核不通过)

    3、Controller

    BorrowInfoController

    @ApiOperation("提交借款申请")
    @PostMapping("/auth/save")
    public R save(@RequestBody BorrowInfo borrowInfo, HttpServletRequest request) {
        String token = request.getHeader("token");
        Long userId = JwtUtils.getUserId(token);
        borrowInfoService.saveBorrowInfo(borrowInfo, userId);
        return R.ok().message("提交成功");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4、Service

    接口:BorrowInfoService

    void saveBorrowInfo(BorrowInfo borrowInfo, Long userId);
    
    • 1

    实现:BorrowInfoServiceImpl

    @Override
    public void saveBorrowInfo(BorrowInfo borrowInfo, Long userId) {
        //获取userInfo的用户数据
        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);
        //存储数据
        borrowInfo.setUserId(userId);
        
        // 校验年化利率(此处真实开发中,应该限制用户最大输入的小数点位数,并且在数据库中做足够大的小数点位数存储,否则计算利息的时候会出现精度不足导致的一系列问题)
        String borrowYearRate = borrowInfo.getBorrowYearRate().toPlainString();
        String[] borrowYearRateSplit = borrowYearRate.split("\\.");
        if (borrowYearRateSplit.length >1 && borrowYearRateSplit[1].length() > 2) {
            throw new BusinessException("年化利率仅支持到小数点后两位");
        }
        // 百分比转成小数(数据库类型修改为decimal(10,4))
        borrowInfo.setBorrowYearRate(borrowInfo.getBorrowYearRate().divide(new BigDecimal(100), 4, RoundingMode.DOWN));
        borrowInfo.setStatus(BorrowInfoStatusEnum.CHECK_RUN.getStatus());
        baseMapper.insert(borrowInfo);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    21.3.2、前端

    提交借款申请

    pages/user/apply.vue

        //提交借款申请
        save() {
          // this.submitBtnDisabled = true
          this.$axios
            .$post('/api/core/borrowInfo/auth/save', this.borrowInfo)
            .then((response) => {
              this.active = 1
            })
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    21.4、获取借款申请状态

    21.4.1、获取借款状态

    1、BorrowInfoController

    @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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2、service

    接口:BorrowInfoService

    Integer getStatusByUserId(Long userId);
    
    • 1

    实现:BorrowInfoServiceImpl

    @Override
    public Integer getStatusByUserId(Long userId) {
        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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    21.4.2、前端开发

    脚本

    pages/user/apply.vue

    将this.getBorrowAmount()和this.initSelected()移植到this.getBorrowInfoStatus()中

    mounted() {
        //获取审批状态
        this.getBorrowInfoStatus()
    },
    
    • 1
    • 2
    • 3
    • 4

    methods中添加方法:

    //获取借款审批状态
    getBorrowInfoStatus() {
        this.$axios
            .$get('/api/core/borrowInfo/auth/getBorrowInfoStatus')
            .then((response) => {
            this.borrowInfoStatus = response.data.borrowInfoStatus
            if (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
            }
        })
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    将 data() 中 active的初始化值设置为null

    active: null, //步骤
    
    • 1

    22、借款审核

    22.1、借款信息列表

    22.1.1、需求

    在这里插入图片描述

    22.1.2、后端实现

    1、扩展实体对象

    列表的结果需要关联查询,数据字典的数据也需要展示对应的文本内容而不是值,除了定义VO的方式,我们也可以使用扩展实体类的方式

    在BorrowInfo类中扩展以下字段

    //扩展字段
    @ApiModelProperty(value = "姓名")
    @TableField(exist = false)
    private String name;
    
    @ApiModelProperty(value = "手机")
    @TableField(exist = false)
    private String mobile;
    
    @ApiModelProperty(value = "其他参数")
    @TableField(exist = false)
    private Map<String,Object> param = new HashMap<>();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2、Controller

    添加 AdminBorrowInfoController

    package com.atguigu.srb.core.controller.admin;
    
    @Api(tags = "借款管理")
    @RestController
    @RequestMapping("/admin/core/borrowInfo")
    @Slf4j
    public class AdminBorrowInfoController {
        @Resource
        private BorrowInfoService borrowInfoService;
        @ApiOperation("借款信息列表")
        @GetMapping("/list")
        public R list() {
            List<BorrowInfo>  borrowInfoList = borrowInfoService.selectList();
            return R.ok().data("list", borrowInfoList);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    3、Service

    接口:BorrowInfoService

    List<BorrowInfo> selectList();
    
    • 1

    实现:BorrowInfoServiceImpl

    @Resource
    private DictService dictService;
    
    @Override
    public List<BorrowInfo> selectList() {
        List<BorrowInfo> borrowInfoList = baseMapper.selectBorrowInfoList();
        borrowInfoList.forEach(borrowInfo -> {
            String returnMethod = dictService.getNameByParentDictCodeAndValue("returnMethod", borrowInfo.getReturnMethod());
            String moneyUse = dictService.getNameByParentDictCodeAndValue("moneyUse", borrowInfo.getMoneyUse());
            String status = BorrowInfoStatusEnum.getMsgByStatus(borrowInfo.getStatus());
            borrowInfo.getParam().put("returnMethod", returnMethod);
            borrowInfo.getParam().put("moneyUse", moneyUse);
            borrowInfo.getParam().put("status", status);
        });
        return borrowInfoList;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4、Mapper

    接口:BorrowInfoMapper

    List<BorrowInfo> selectBorrowInfoList();
    
    • 1

    xml:BorrowInfoMapper.xml

    <select id="selectBorrowInfoList" resultType="com.atguigu.srb.core.pojo.entity.BorrowInfo">
        SELECT
        bi.*,
        b.name,
        b.mobile
        FROM
        borrow_info AS bi
        LEFT JOIN borrower AS b ON bi.user_id = b.user_id
        WHERE bi.is_deleted = 0
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    22.1.3、前端

    1、创建页面组件

    创建 src/views/core/borrow-info/list.vue

    <template>
      <div class="app-container">
        借款列表
      div>
    template>
    <script>
    export default {
      
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    创建 src/views/core/borrow-info/detail.vue

    <template>
      <div class="app-container">
        借款详情
      div>
    template>
    <script>
    export default {
      
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2、配置路由

    src/router/index.js

    在“借款管理”下添加子路由

          {
            path: 'info-list',
            name: 'coreBorrowInfoList',
            component: () => import('@/views/core/borrow-info/list'),
            meta: { title: '借款列表' }
          },
          {
            path: 'info-detail/:id',
            name: 'coreBorrowInfoDetail',
            component: () => import('@/views/core/borrow-info/detail'),
            meta: { title: '借款详情' },
            hidden: true
          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3、定义api

    创建 src/api/core/borrow-info.js

    import request from '@/utils/request'
    export default {
      getList() {
        return request({
          url: `/admin/core/borrowInfo/list`,
          method: 'get'
        })
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4、页面脚本

    src/views/core/borrow-info/list.vue

    <script>
    import borrowInfoApi from '@/api/core/borrow-info'
    export default {
      data() {
        return {
          list: null // 列表
        }
      },
      created() {
        this.fetchData()
      },
      methods: {
        // 加载列表数据
        fetchData() {
          borrowInfoApi.getList().then(response => {
            this.list = response.data.list
          })
        }
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    5、页面模板

    src/views/core/borrow-info/list.vue

    <template>
      <div class="app-container">
        
        <el-table :data="list" stripe>
          <el-table-column type="index" label="序号" width="60" align="center" />
          <el-table-column prop="name" label="借款人姓名" width="90" />
          <el-table-column prop="mobile" label="手机" />
          <el-table-column prop="amount" label="借款金额" />
          <el-table-column label="借款期限" width="90">
            <template slot-scope="scope">{{ scope.row.period }}个月template>
          el-table-column>
          <el-table-column prop="param.returnMethod" label="还款方式" width="150" />
          <el-table-column prop="param.moneyUse" label="资金用途" width="100" />
          <el-table-column label="年化利率" width="90">
            <template slot-scope="scope">
              {{ scope.row.borrowYearRate * 100 }}%
            template>
          el-table-column>
          <el-table-column prop="param.status" label="状态" width="100" />
          <el-table-column prop="createTime" label="申请时间" width="150" />
          <el-table-column label="操作" width="150" align="center">
            <template slot-scope="scope">
              <el-button type="primary" size="mini">
                <router-link :to="'/core/borrower/info-detail/' + scope.row.id">
                  查看
                router-link>
              el-button>
              <el-button
                v-if="scope.row.status === 1"
                type="warning"
                size="mini"
                @click="approvalShow(scope.row)"
              >
                审批
              el-button>
            template>
          el-table-column>
        el-table>
      div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    22.2、借款详情

    22.2.1、需求

    借款详情展示借款信息与借款人信息

    在这里插入图片描述

    22.2.2、后端实现

    1、Controller

    AdminBorrowInfoController

    @ApiOperation("获取借款信息")
    @GetMapping("/show/{id}")
    public R show(
        @ApiParam(value = "借款id", required = true)
        @PathVariable Long id) {
        Map<String, Object> borrowInfoDetail = borrowInfoService.getBorrowInfoDetail(id);
        return R.ok().data("borrowInfoDetail", borrowInfoDetail);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2、Service

    接口:BorrowInfoService

    Map<String, Object> getBorrowInfoDetail(Long id);
    
    • 1

    实现:BorrowInfoServiceImpl

    @Resource
    private BorrowerMapper borrowerMapper;
    @Resource
    private BorrowerService borrowerService;
    
    @Override
    public Map<String, Object> getBorrowInfoDetail(Long id) {
        //查询借款对象
        BorrowInfo borrowInfo = baseMapper.selectById(id);
        //组装数据
        String returnMethod = dictService.getNameByParentDictCodeAndValue("returnMethod", borrowInfo.getReturnMethod());
        String moneyUse = dictService.getNameByParentDictCodeAndValue("moneyUse", borrowInfo.getMoneyUse());
        String status = BorrowInfoStatusEnum.getMsgByStatus(borrowInfo.getStatus());
        borrowInfo.getParam().put("returnMethod", returnMethod);
        borrowInfo.getParam().put("moneyUse", moneyUse);
        borrowInfo.getParam().put("status", status);
        //根据user_id获取借款人对象
        QueryWrapper<Borrower> borrowerQueryWrapper = new QueryWrapper<Borrower>();
        borrowerQueryWrapper.eq("user_id", borrowInfo.getUserId());
        Borrower borrower = borrowerMapper.selectOne(borrowerQueryWrapper);
        //组装借款人对象
        BorrowerDetailVO borrowerDetailVO = borrowerService.getBorrowerDetailVOById(borrower.getId());
        //组装数据
        Map<String, Object> result = new HashMap<>();
        result.put("borrowInfo", borrowInfo);
        result.put("borrower", borrowerDetailVO);
        return result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    22.2.3、前端

    1、定义api

    src/api/core/borrow-info.js

      show(id) {
        return request({
          url: `/admin/core/borrowInfo/show/${id}`,
          method: 'get'
        })
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、添加自定义css

    src/styles/show.css

    3、页面脚本

    src/views/core/borrow-info/detail.vue

    <script>
    import borrowInfoApi from '@/api/core/borrow-info'
    import '@/styles/show.css'
    export default {
      data() {
        return {
          borrowInfoDetail: {
            borrowInfo: {
              param: {}
            },
            borrower: {}
          }
        }
      },
      created() {
        if (this.$route.params.id) {
          this.fetchDataById()
        }
      },
      methods: {
        fetchDataById() {
          borrowInfoApi.show(this.$route.params.id).then(response => {
            this.borrowInfoDetail = response.data.borrowInfoDetail
          })
        },
        back() {
          this.$router.push({ path: '/core/borrower/info-list' })
        }
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    4、页面模板

    src/views/core/borrow-info/detail.vue

    <template>
      <div class="app-container">
        <h4>借款信息h4>
        <table
          class="table table-striped table-condenseda table-bordered"
          width="100%"
        >
          <tbody>
            <tr>
              <th width="15%">借款金额th>
              <td width="35%">{{ borrowInfoDetail.borrowInfo.amount }}元td>
              <th width="15%">借款期限th>
              <td width="35%">{{ borrowInfoDetail.borrowInfo.period }}个月td>
            tr>
            <tr>
              <th>年化利率th>
              <td>{{ borrowInfoDetail.borrowInfo.borrowYearRate * 100 }}%td>
              <th>还款方式th>
              <td>{{ borrowInfoDetail.borrowInfo.param.returnMethod }}td>
            tr>
            <tr>
              <th>资金用途th>
              <td>{{ borrowInfoDetail.borrowInfo.param.moneyUse }}td>
              <th>状态th>
              <td>{{ borrowInfoDetail.borrowInfo.param.status }}td>
            tr>
            <tr>
              <th>创建时间th>
              <td>{{ borrowInfoDetail.borrowInfo.createTime }}td>
              <th>th>
              <td>td>
            tr>
          tbody>
        table>
        <h4>借款人信息h4>
        <table
          class="table table-striped table-condenseda table-bordered"
          width="100%"
        >
          <tbody>
            <tr>
              <th width="15%">借款人th>
              <td width="35%">
                <b>{{ borrowInfoDetail.borrower.name }}b>
              td>
              <th width="15%">手机th>
              <td width="35%">{{ borrowInfoDetail.borrower.mobile }}td>
            tr>
            <tr>
              <th>身份证th>
              <td>{{ borrowInfoDetail.borrower.idCard }}td>
              <th>性别th>
              <td>{{ borrowInfoDetail.borrower.sex }}td>
            tr>
            <tr>
              <th>年龄th>
              <td>{{ borrowInfoDetail.borrower.age }}td>
              <th>是否结婚th>
              <td>{{ borrowInfoDetail.borrower.marry }}td>
            tr>
            <tr>
              <th>学历th>
              <td>{{ borrowInfoDetail.borrower.education }}td>
              <th>行业th>
              <td>{{ borrowInfoDetail.borrower.industry }}td>
            tr>
            <tr>
              <th>月收入th>
              <td>{{ borrowInfoDetail.borrower.income }}td>
              <th>还款来源th>
              <td>{{ borrowInfoDetail.borrower.returnSource }}td>
            tr>
            <tr>
              <th>创建时间th>
              <td>{{ borrowInfoDetail.borrower.createTime }}td>
              <th>状态th>
              <td>{{ borrowInfoDetail.borrower.status }}td>
            tr>
          tbody>
        table>
        <el-row style="text-align:center;margin-top: 40px;">
          <el-button @click="back">
            返回
          el-button>
        el-row>
      div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    22.3、借款审批

    22.3.1、需求

    管理平台借款审批,审批通过后产生标的,审批前我们需要跟借款人进行电话沟通,确定借款年化和平台服务费率(平台收益),借款年化可能根据实际情况调高或调低;起息日通常我们把它确定为募集结束时间(或放款时间)

    在这里插入图片描述

    22.3.2、后端实现

    1、定义VO对象

    package com.atguigu.srb.core.pojo.vo;
    
    @Data
    @ApiModel(description = "借款信息审批")
    public class BorrowInfoApprovalVO {
        @ApiModelProperty(value = "id")
        private Long id;
        @ApiModelProperty(value = "状态")
        private Integer status;
        @ApiModelProperty(value = "审批内容")
        private String content;
        @ApiModelProperty(value = "标题")
        private String title;
        @ApiModelProperty(value = "年化利率")
        private BigDecimal lendYearRate;
        @ApiModelProperty(value = "平台服务费率")
        private BigDecimal serviceRate;
        @ApiModelProperty(value = "开始日期")
        private String lendStartDate;
        @ApiModelProperty(value = "描述信息")
        private String lendInfo;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2、Controller

    AdminBorrowInfoController

    @ApiOperation("审批借款信息")
    @PostMapping("/approval")
    public R approval(@RequestBody BorrowInfoApprovalVO borrowInfoApprovalVO) {
        borrowInfoService.approval(borrowInfoApprovalVO);
        return R.ok().message("审批完成");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3、Service

    接口:BorrowInfoService

    void approval(BorrowInfoApprovalVO borrowInfoApprovalVO);
    
    • 1

    实现:BorrowInfoServiceImpl

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void approval(BorrowInfoApprovalVO borrowInfoApprovalVO) {
        //修改借款信息状态
        Long borrowInfoId = borrowInfoApprovalVO.getId();
        BorrowInfo borrowInfo = baseMapper.selectById(borrowInfoId);
        borrowInfo.setStatus(borrowInfoApprovalVO.getStatus());
        borrowInfo.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(borrowInfo);
        
        //审核通过则创建标的
        if (borrowInfoApprovalVO.getStatus().intValue() == BorrowInfoStatusEnum.CHECK_OK.getStatus().intValue()) {
            //创建标的
            //TODO
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    22.3.3、前端实现

    1、定义api

    src/api/core/borrow-info.js

      approval(borrowInfoApproval) {
        return request({
          url: '/admin/core/borrowInfo/approval',
          method: 'post',
          data: borrowInfoApproval
        })
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、页面脚本

    src/views/core/borrow-info/list.vue

    data:

    dialogVisible: false, //审批对话框
    borrowInfoApproval: {
      status: 2,
      serviceRate: 5,
      lendYearRate: 0 //初始化,解决表单中数据修改时无法及时渲染的问题
    } //审批对象
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    methods:

        approvalShow(row) {
          this.dialogVisible = true
          this.borrowInfoApproval.id = row.id
          this.borrowInfoApproval.lendYearRate = row.borrowYearRate * 100
        },
        approvalSubmit() {
          borrowInfoApi.approval(this.borrowInfoApproval).then(response => {
            this.dialogVisible = false
            this.$message.success(response.message)
            this.fetchData()
          })
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3、页面模板

    src/views/core/borrow-info/list.vue

    
    <el-dialog title="审批" :visible.sync="dialogVisible" width="490px">
        <el-form label-position="right" label-width="100px">
            <el-form-item label="是否通过">
                <el-radio-group v-model="borrowInfoApproval.status">
                    <el-radio :label="2">通过el-radio>
                    <el-radio :label="-1">不通过el-radio>
                el-radio-group>
            el-form-item>
            <el-form-item v-if="borrowInfoApproval.status == 2" label="标的名称">
                <el-input v-model="borrowInfoApproval.title" />
            el-form-item>
            <el-form-item v-if="borrowInfoApproval.status == 2" label="起息日">
                <el-date-picker
                                v-model="borrowInfoApproval.lendStartDate"
                                type="date"
                                placeholder="选择开始时间"
                                value-format="yyyy-MM-dd"
                                />
            el-form-item>
            <el-form-item v-if="borrowInfoApproval.status == 2" label="年化收益率">
                <el-input v-model="borrowInfoApproval.lendYearRate">
                    <template slot="append">%template>
                el-input>
            el-form-item>
            <el-form-item v-if="borrowInfoApproval.status == 2" label="服务费率">
                <el-input v-model="borrowInfoApproval.serviceRate">
                    <template slot="append">%template>
                el-input>
            el-form-item>
            <el-form-item v-if="borrowInfoApproval.status == 2" label="标的描述">
                <el-input v-model="borrowInfoApproval.lendInfo" type="textarea" />
            el-form-item>
        el-form>
        <div slot="footer" class="dialog-footer">
            <el-button @click="dialogVisible = false">
                取消
            el-button>
            <el-button type="primary" @click="approvalSubmit">
                确定
            el-button>
        div>
    el-dialog>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    本文章参考B站 尚硅谷《尚融宝》Java微服务分布式金融项目,仅供个人学习使用,部分内容为本人自己见解,与尚硅谷无关。

  • 相关阅读:
    PO、VO、DAO、BO、DTO、POJO到底代表啥
    JAVA学习------ConcurrentHashMap实现原理
    Code Llama: Open Foundation Models for Code
    Mysql基础知识梳理
    5.软件测试-----自动化测试
    如何有效的禁止Google Chrome自动更新?
    瀑布流 - Vue3基于Grid布局简单实现一个瀑布流组件
    Linux—系统基础一
    Spring Cloud Function Spel表达式注入漏洞分析
    如何处理linux 自动执行的sh脚本
  • 原文地址:https://blog.csdn.net/Chovy_pyc/article/details/127759713