30. 尚融宝借款审核

借款信息列表

需求

在这里插入图片描述

一、后端实现

1、entity

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

BorrowInfo.java类中扩展以下字段

    //扩展字段
    @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<>();

2、controller

添加 AdminBorrowInfoController.java

package com.indi.srb.core.controller.admin;

@Api(tags = "借款管理")
@RestController
@RequestMapping("/admin/core/borrowInfo")
public class AdminBorrowInfoController {
    @Resource
    private BorrowInfoService borrowInfoService;

    @ApiOperation("借款列表")
    @GetMapping("/list")
    public R selectList() {
        List<BorrowInfo> borrowInfoList = borrowInfoService.selectList();
        return R.ok().setData("list", borrowInfoList);
    }
}

3、service

BorrowInfoService.java

    List<BorrowInfo> selectList();

BorrowInfoServiceImpl.java

    @Resource
    private DictService dictService;
    
    @Override
    public List<BorrowInfo> selectList() {
        List<BorrowInfo> borrowInfoList = baseMapper.selectBorrowInfoList();
        borrowInfoList.forEach(borrowInfo -> {
            setExtensionBorrowInfo(borrowInfo);
        });
        return borrowInfoList;
    }
    
    /**
     * 设置BorrowInfo扩展的字段
     * @param borrowInfo
     */
    private void setExtensionBorrowInfo(BorrowInfo borrowInfo) {
        String returnMethod = dictService.getNameByDictCodeAndValue("returnMethod", borrowInfo.getReturnMethod());
        String moneyUse = dictService.getNameByDictCodeAndValue("moneyUse", borrowInfo.getMoneyUse());
        String status = BorrowInfoStatusEnum.getMsgByStatus(borrowInfo.getStatus());

        borrowInfo.getParam().put("returnMethod", returnMethod);
        borrowInfo.getParam().put("moneyUse", moneyUse);
        borrowInfo.getParam().put("status", status);
    }    

4、mapper

BorrowInfoMapper.java

    List<BorrowInfo> selectBorrowInfoList();

BorrowInfoMapper.xml

	<select id="selectBorrowInfoList" resultType="com.indi.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 b.is_deleted = 0
	</select>

二、前端实现

1、创建页面组件

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

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

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
      }

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'
    })
  }
}

4、template

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>

5、script

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、controller

AdminBorrowInfoController.java

    @ApiOperation("借款详情")
    @GetMapping("/getBorrowInfoDetail/{id}")
    public R getBorrowInfoDetail(
            @ApiParam(value = "借款信息的id", required = true)
            @PathVariable Long id) {
        Map<String, Object> map = borrowInfoService.getBorrowInfoDetail(id);
        return R.ok().setData("borrowInfoDetail", map);
    }

2、service

BorrowInfoService.java

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

BorrowInfoServiceImpl.java

    @Resource
    private BorrowerService borrowerService;

    @Override
    public Map<String, Object> getBorrowInfoDetail(Long id) {
        // 借款信息
        BorrowInfo borrowInfo = baseMapper.selectById(id);
        setExtensionBorrowInfo(borrowInfo);

        Long userId = borrowInfo.getUserId();
        QueryWrapper<Borrower> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id").eq("user_id", userId);
        Borrower borrower = borrowerService.getBaseMapper().selectOne(queryWrapper);

        // 借款人信息
        BorrowerDetailVO borrowerDetailVO = borrowerService.getBorrowerDetailVO(borrower.getId());

        Map<String, Object> map = new HashMap<>();
        map.put("borrowInfo", borrowInfo);
        map.put("borrower", borrowerDetailVO);
        return map;
    }

二、前端

1、定义api

src/api/core/borrow-info.js

  show(id) {
    return request({
      url: `/admin/core/borrowInfo/show/${id}`,
      method: 'get'
    })
  }

2、添加自定义css

src/styles/show.css

.app-container{
  background: #fff;
  position: absolute;
  width:100%;
  height: 100%;
  overflow: auto;
}
table {
  border-spacing: 0;
  border-collapse: collapse;
}
.table-bordered {
  border: 1px solid #ddd;
}
.table-striped>tbody>tr:nth-child(odd)>td, .table-striped>tbody>tr:nth-child(odd)>th {
  background-color: #f9f9f9;
}
.table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th,
.table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td {
  font-size: 14px;
  color: #333;
  padding: 8px;
  line-height: 1.42857143;
  vertical-align: top;
  border-top: 1px solid #ddd;
}
.table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th{
  text-align: right;
  width: 120px;
}
.table-bordered>thead>tr>th, .table-bordered>tbody>tr>th, .table-bordered>tfoot>tr>th, .table-bordered>thead>tr>td, .table-bordered>tbody>tr>td, .table-bordered>tfoot>tr>td {
  border: 1px solid #ddd;
}
.active_content{
  padding: 0 20px  ;
  border-radius: 4px;
  border: 1px solid #ebeef5;
  background-color: #fff;
  overflow: hidden;
  color: #303133;
  transition: .3s;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);

}
.active_content h4{
  /*line-height: 0;*/
}
.active_content span{
  font-size: 12px;
  color: #999;
}

4、template

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>

3、script

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、vo

BorrowInfoApprovalVO .java

package com.indi.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;
}

2、controller

AdminBorrowInfoController.java

    @ApiOperation("审批借款信息")
    @PostMapping("/approval")
    public R approval(@RequestBody BorrowInfoApprovalVO borrowInfoApprovalVO){
        borrowInfoService.approval(borrowInfoApprovalVO);
        return R.ok().setMessage("审批完成");
    }

3、BorrowInfoService

BorrowInfoService.java

    void approval(BorrowInfoApprovalVO borrowInfoApprovalVO);

BorrowInfoServiceImpl.java

    @Resource
    private LendService lendService;	
	
	@Transactional(rollbackFor = Exception.class)
    @Override
    public void approval(BorrowInfoApprovalVO borrowInfoApprovalVO) {
        // 修改借款信息状态
        Long id = borrowInfoApprovalVO.getId();
        BorrowInfo borrowInfo = baseMapper.selectById(id);
        borrowInfo.setStatus(borrowInfoApprovalVO.getStatus());
        baseMapper.updateById(borrowInfo);

        // 如果借款状态为审核通过的话,则生成一个标的
        if (borrowInfoApprovalVO.getStatus().intValue() == BorrowInfoStatusEnum.CHECK_OK.getStatus().intValue()) {
            //TODO
            lendService.createLend(borrowInfoApprovalVO, borrowInfo);
        }
    }

3、编号辅助类

创建util

LendNoUtils.java

package com.indi.srb.core.util;

public class LendNoUtils {

    public static String getNo() {

        LocalDateTime time=LocalDateTime.now();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String strDate = dtf.format(time);

        String result = "";
        Random random = new Random();
        for (int i = 0; i < 3; i++) {
            result += random.nextInt(10);
        }

        return strDate + result;
    }

    public static String getLendNo() {

        return "LEND" + getNo();
    }

    public static String getLendItemNo() {

        return "INVEST" + getNo();
    }

    public static String getLoanNo() {

        return "LOAN" + getNo();
    }

    public static String getReturnNo() {
        return "RETURN" + getNo();
    }


    public static Object getWithdrawNo() {
        return "WITHDRAW" + getNo();
    }


    public static String getReturnItemNo() {
        return "RETURNITEM" + getNo();
    }


    public static String getChargeNo() {

        return "CHARGE" + getNo();
    }

    /**
     * 获取交易编码
     */
    public static String getTransNo() {
        return "TRANS" + getNo();
    }

}

4、LendService

LendService.java

    void createLend(BorrowInfoApprovalVO borrowInfoApprovalVO, BorrowInfo borrowInfo);

LendServiceImpl.java

建议在idea中添加一个插件,GenerateAllSetter,可以快速生成对象的全部set方法。

    @Override
    public void createLend(BorrowInfoApprovalVO borrowInfoApprovalVO, BorrowInfo borrowInfo) {
        Lend lend = new Lend();
        lend.setUserId(borrowInfo.getUserId());
        lend.setBorrowInfoId(borrowInfo.getId());
        lend.setLendNo(LendNoUtils.getLendNo());
        lend.setTitle(borrowInfoApprovalVO.getTitle());
        lend.setAmount(borrowInfo.getAmount());
        lend.setPeriod(borrowInfo.getPeriod());

        // 年化率(转小数)
        lend.setLendYearRate(borrowInfoApprovalVO.getLendYearRate().divide(new BigDecimal(100)));
        // 平台服务费率(转小数)
        lend.setServiceRate(borrowInfoApprovalVO.getServiceRate().divide(new BigDecimal(100)));

        lend.setReturnMethod(borrowInfo.getReturnMethod());
        lend.setLowestAmount(new BigDecimal(100));
        lend.setInvestAmount(new BigDecimal(0));
        lend.setInvestNum(0);
        lend.setPublishDate(LocalDateTime.now());

        // 起息日期
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate lendStartDate = LocalDate.parse(borrowInfoApprovalVO.getLendStartDate(), dateTimeFormatter);
        lend.setLendStartDate(lendStartDate);
        // 结束日期
        lend.setLendEndDate(lendStartDate.plusMonths(borrowInfo.getPeriod()));

        lend.setLendInfo(borrowInfoApprovalVO.getLendInfo());

        // 平台预期收益
        // 每月年化利率 = 平台服务费率 / 12,保留小数点后8位,去除最后一位
        BigDecimal monthRate = lend.getServiceRate().divide(new BigDecimal(12), 8, BigDecimal.ROUND_DOWN);
        // 平台预期收益:借款金额 * 月年化 * 借款期限
        BigDecimal exceptAmount = borrowInfo.getAmount().multiply(monthRate).multiply(new BigDecimal(borrowInfo.getPeriod()));
        lend.setExpectAmount(exceptAmount);

        lend.setRealAmount(new BigDecimal(0));
        lend.setStatus(LendStatusEnum.INVEST_RUN.getStatus());
        lend.setCheckTime(LocalDateTime.now());
        lend.setCheckAdminId(1L);

        baseMapper.insert(lend);
    }

二、前端实现

1、定义api

src/api/core/borrow-info.js

  approval(borrowInfoApproval) {
    return request({
      url: '/admin/core/borrowInfo/approval',
      method: 'post',
      data: borrowInfoApproval
    })
  }

2、template

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>

3、script

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

data

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

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()
      })
    }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值