核心业务4:标的管理

核心业务4:标的管理

1.标的管理流程图

2.数据库表设计

3.前端逻辑设计

4.后端逻辑设计

5.标的放款TODO

核心业务4:标的管理

1.标的管理流程图

在这里插入图片描述

①上一个核心业务通过审核借款申请结束之后产生新标的

②该标的在后台管理系统展示

在这里插入图片描述

③可以查看标的详情

在这里插入图片描述

④注意略过审核标的步骤,产生标的直接审核通过,进入状态募资中

在这里插入图片描述

2.数据库表设计

①标的表

  • lend
    在这里插入图片描述

②标的表关联

  • 标的表通过user_id与user_info表关联(用户表)
  • 标的表通过borrower_info_id与borrow_info表关联(借款信息表)

3.前端逻辑设计

①表单对象

  • 标的列表
    在这里插入图片描述

  • 标的详情
    在这里插入图片描述

②调用接口

  • 前端内部跳转
    在这里插入图片描述
  • 调用后端api
    在这里插入图片描述

③后端代码详细

  • 路由定义(前端内部)
    srb-admin\src\router\index.js
//标的管理路由
  {
    path: '/core/lend',
    component: Layout,
    name: 'coreLend',
    meta: { title: '标的管理', icon: 'el-icon-s-flag' },
    alwaysShow: true,
    children: [
      {
        path: 'list',
        name: 'coreLendList',
        component: () => import('@/views/core/lend/list'),
        meta: { title: '标的列表' },
      },
      {
        path: 'detail/:id',
        name: 'coreLendDetail',
        component: () => import('@/views/core/lend/detail'),
        meta: { title: '标的详情' },
        hidden: true,
      },
    ],
  },
  • 调用接口定义
    srb-admin\src\api\core\lend.js
import request from '@/utils/request'

export default {
  //标的列表
  getList() {
    return request({
      url: `/admin/core/lend/list`,
      method: 'get',
    })
  },

  //标的详情
  show(id) {
    return request({
      url: `/admin/core/lend/show/${id}`,
      method: 'get',
    })
  },
}

  • 列表页
    srb-admin\src\views\core\lend\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="lendNo" label="标的编号" width="160" />
      <el-table-column prop="amount" label="标的金额" />
      <el-table-column prop="period" label="投资期数" />
      <el-table-column label="年化利率">
        <template slot-scope="scope">
          {{ scope.row.lendYearRate * 100 }}%
        </template>
      </el-table-column>
      <el-table-column prop="investAmount" label="已投金额" />
      <el-table-column prop="investNum" label="投资人数" />
      <el-table-column prop="publishDate" label="发布时间" width="150" />
      <el-table-column prop="lendStartDate" label="开始日期" />
      <el-table-column prop="lendEndDate" label="结束日期" />
      <el-table-column prop="param.returnMethod" label="还款方式" />
      <el-table-column prop="param.status" label="状态" />

      <el-table-column label="操作" width="150" align="center">
        <template slot-scope="scope">
          <el-button type="primary" size="mini">
            <router-link :to="'/core/lend/detail/' + scope.row.id">
              查看
            </router-link>
          </el-button>

          <el-button
            v-if="scope.row.status == 1"
            type="warning"
            size="mini"
            @click="makeLoan(scope.row.id)"
          >
            放款
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import lendApi from '@/api/core/lend'

export default {
  data() {
    return {
      list: null, // 列表
    }
  },

  created() {
    this.fetchData()
  },

  methods: {
    // 加载列表数据
    fetchData() {
      lendApi.getList().then((response) => {
        this.list = response.data.list
      })
    },
  },
}
</script>

  • 详情页
    srb-admin\src\views\core\lend\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%">
            <b>{{ lendDetail.lend.lendNo }}</b>
          </td>
          <th width="15%">标题</th>
          <td width="35%">{{ lendDetail.lend.title }}</td>
        </tr>
        <tr>
          <th>标的金额</th>
          <td>{{ lendDetail.lend.amount }}</td>
          <th>投资期数</th>
          <td>{{ lendDetail.lend.period }}个月</td>
        </tr>
        <tr>
          <th>年化利率</th>
          <td>
            标的:{{ lendDetail.lend.lendYearRate * 100 }}%
            <br />
            平台:{{ lendDetail.lend.serviceRate * 100 }}%
          </td>
          <th>还款方式</th>
          <td>{{ lendDetail.lend.param.returnMethod }}</td>
        </tr>

        <tr>
          <th>最低投资金额</th>
          <td>{{ lendDetail.lend.lowestAmount }}</td>
          <th>发布日期</th>
          <td>{{ lendDetail.lend.publishDate }}</td>
        </tr>
        <tr>
          <th>开始日期</th>
          <td>{{ lendDetail.lend.lendStartDate }}</td>
          <th>结束日期</th>
          <td>{{ lendDetail.lend.lendEndDate }}</td>
        </tr>
        <tr>
          <th>已投金额</th>
          <td>
            <b>{{ lendDetail.lend.investAmount }}</b>
          </td>
          <th>投资人数</th>
          <td>{{ lendDetail.lend.investNum }}</td>
        </tr>
        <tr>
          <th>状态</th>
          <td>
            <b>{{ lendDetail.lend.param.status }}</b>
          </td>
          <th>创建时间</th>
          <td>{{ lendDetail.lend.createTime }}</td>
        </tr>
        <tr>
          <th>说明</th>
          <td colspan="3">
            <b>{{ lendDetail.lend.lendInfo }}</b>
          </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>{{ lendDetail.lend.expectAmount }}</b>
          </td>
          <th width="15%">标的已获取收益</th>
          <td width="35%">{{ lendDetail.lend.realAmount }}</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>{{ lendDetail.borrower.name }}</b>
          </td>
          <th width="15%">手机</th>
          <td width="35%">{{ lendDetail.borrower.mobile }}</td>
        </tr>
        <tr>
          <th>身份证</th>
          <td>{{ lendDetail.borrower.idCard }}</td>
          <th>性别</th>
          <td>{{ lendDetail.borrower.sex }}</td>
        </tr>
        <tr>
          <th>年龄</th>
          <td>{{ lendDetail.borrower.age }}</td>
          <th>是否结婚</th>
          <td>{{ lendDetail.borrower.marry }}</td>
        </tr>
        <tr>
          <th>学历</th>
          <td>{{ lendDetail.borrower.education }}</td>
          <th>行业</th>
          <td>{{ lendDetail.borrower.industry }}</td>
        </tr>
        <tr>
          <th>月收入</th>
          <td>{{ lendDetail.borrower.income }}</td>
          <th>还款来源</th>
          <td>{{ lendDetail.borrower.returnSource }}</td>
        </tr>
        <tr>
          <th>创建时间</th>
          <td>{{ lendDetail.borrower.createTime }}</td>
          <th>状态</th>
          <td>{{ lendDetail.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>
<script>
import lendApi from '@/api/core/lend'
import '@/styles/show.css'

export default {
  data() {
    return {
      lendDetail: {
        lend: {
          param: {},
        },
        borrower: {},
      },
    }
  },

  created() {
    if (this.$route.params.id) {
      this.fetchDataById()
    }
  },

  methods: {
    fetchDataById() {
      lendApi.show(this.$route.params.id).then((response) => {
        this.lendDetail = response.data.lendDetail
      })
    },

    back() {
      this.$router.push({ path: '/core/lend/list' })
    },
  },
}
</script>

4.后端逻辑设计

①后端对象

  • 列表对象
    com.atguigu.srb.core.pojo.entity.Lend
    //扩充的其他参数
    @ApiModelProperty(value = "其他参数")
    @TableField(exist = false)
    private Map<String,Object> param = new HashMap<>();
  • 详情对象
    封装为map

②后端接口

在这里插入图片描述

③后端代码(完成核心业务3中最后的10.TODO创建标的)

  • 调用位置
    com.atguigu.srb.core.service.impl.BorrowInfoServiceImpl
 if(borrowInfoApprovalVO.getStatus().intValue() == BorrowInfoStatusEnum.CHECK_OK.getStatus().intValue()){
            //创建新标的
            //TODO

            lendService.createLend(borrowInfoApprovalVO,borrowInfo);
        }

  • service编写
    com.atguigu.srb.core.service.LendService
void createLend(BorrowInfoApprovalVO borrowInfoApprovalVO, BorrowInfo borrowInfo);
 /**
     * @param borrowInfoApprovalVO:
     * @param borrowInfo:
     * @return void
     * @author Likejin
     * @description 审批后生成新标的的流程
     * @date 2023/4/17 9:18
     */

    @Override
    public void createLend(BorrowInfoApprovalVO borrowInfoApprovalVO, BorrowInfo borrowInfo) {
        Lend lend = new Lend();

        //填充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));//初始化最低投款金额为100
        lend.setInvestAmount(new BigDecimal(0));//初始化已投金额为0
        lend.setInvestNum(0);//初始化已投人为0
        lend.setPublishDate(LocalDateTime.now());//初始化表弟发布时间

        //计算开始日期和结束日期
        String lendStartDateVo = borrowInfoApprovalVO.getLendStartDate();
        //计算起息日期
        //转换时间(字符串到LocalDate)
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate lendStartDate = LocalDate.parse(lendStartDateVo, dateTimeFormatter);
        lend.setLendStartDate(lendStartDate);
        //计算结束日期
        LocalDate lendEndDate = lendStartDate.plusMonths(borrowInfo.getPeriod());
        lend.setLendEndDate(lendEndDate);

        //描述
        lend.setLendInfo(borrowInfoApprovalVO.getLendInfo());

        //设置平台预期受益(年费费率转化为月化费率然后乘以借款月份)标的金额 * 年化/12 * 期数
        BigDecimal monthRate = lend.getServiceRate().divide(new BigDecimal(12), 8, BigDecimal.ROUND_DOWN);//小数点精确,抹零
        BigDecimal expectMount = lend.getAmount().multiply(monthRate.multiply(new BigDecimal(lend.getPeriod())));
        lend.setExpectAmount(expectMount);//预期受益

        lend.setRealAmount(new BigDecimal(0));//实际收益
        lend.setStatus(LendStatusEnum.INVEST_RUN.getStatus());//标的状态

        //标的不需审核通过,生成标的直接通过,直接审核通过的时间
        lend.setCheckTime(LocalDateTime.now());//审核通过时间
        //硬编码
        lend.setCheckAdminId(1L);//设置审核人

        //存入数据库
        baseMapper.insert(lend);
    }

④后端代码(展示标的列表和标的详情)

  • controller
package com.atguigu.srb.core.controller.admin;

import com.atguigu.common.result.R;
import com.atguigu.srb.core.pojo.entity.Lend;
import com.atguigu.srb.core.service.LendService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Api(tags = "标的管理")
@RestController
@RequestMapping("/admin/core/lend")
@Slf4j
public class AdminLendController {

    @Resource
    private LendService lendService;

    @ApiOperation("标的列表")
    @GetMapping("/list")
    public R list() {
        List<Lend> lendList = lendService.selectList();
        return R.ok().data("list", lendList);
    }

    @ApiOperation("获取标的信息")
    @GetMapping("/show/{id}")
    public R show(
            @ApiParam(value = "标的id", required = true)
            @PathVariable Long id) {
        Map<String, Object> result = lendService.getLendDetail(id);
        return R.ok().data("lendDetail", result);
    }
}
  • service
package com.atguigu.srb.core.service;

import com.atguigu.srb.core.pojo.entity.BorrowInfo;
import com.atguigu.srb.core.pojo.entity.Lend;
import com.atguigu.srb.core.pojo.vo.BorrowInfoApprovalVO;
import com.baomidou.mybatisplus.extension.service.IService;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * 标的准备表 服务类
 * </p>
 *
 * @author Likejin
 * @since 2023-04-09
 */
public interface LendService extends IService<Lend> {

    void createLend(BorrowInfoApprovalVO borrowInfoApprovalVO, BorrowInfo borrowInfo);

    List<Lend> selectList();

    Map<String,Object> getLendDetail(Long id);
}

package com.atguigu.srb.core.service.impl;

import com.atguigu.srb.core.enums.LendStatusEnum;
import com.atguigu.srb.core.mapper.BorrowerMapper;
import com.atguigu.srb.core.mapper.LendMapper;
import com.atguigu.srb.core.pojo.entity.BorrowInfo;
import com.atguigu.srb.core.pojo.entity.Borrower;
import com.atguigu.srb.core.pojo.entity.Lend;
import com.atguigu.srb.core.pojo.vo.BorrowInfoApprovalVO;
import com.atguigu.srb.core.pojo.vo.BorrowerDetailVO;
import com.atguigu.srb.core.service.BorrowerService;
import com.atguigu.srb.core.service.DictService;
import com.atguigu.srb.core.service.LendService;
import com.atguigu.srb.core.util.LendNoUtils;
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.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 标的准备表 服务实现类
 * </p>
 *
 * @author Likejin
 * @since 2023-04-09
 */
@Service
public class LendServiceImpl extends ServiceImpl<LendMapper, Lend> implements LendService {

    @Resource
    private DictService dictService;

    @Resource
    private BorrowerMapper borrowerMapper;

    @Resource
    private BorrowerService borrowerService;

    /**
     * @param borrowInfoApprovalVO:
     * @param borrowInfo:
     * @return void
     * @author Likejin
     * @description 审批后生成新标的的流程
     * @date 2023/4/17 9:18
     */

    @Override
    public void createLend(BorrowInfoApprovalVO borrowInfoApprovalVO, BorrowInfo borrowInfo) {
        Lend lend = new Lend();

        //填充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));//初始化最低投款金额为100
        lend.setInvestAmount(new BigDecimal(0));//初始化已投金额为0
        lend.setInvestNum(0);//初始化已投人为0
        lend.setPublishDate(LocalDateTime.now());//初始化表弟发布时间

        //计算开始日期和结束日期
        String lendStartDateVo = borrowInfoApprovalVO.getLendStartDate();
        //计算起息日期
        //转换时间(字符串到LocalDate)
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate lendStartDate = LocalDate.parse(lendStartDateVo, dateTimeFormatter);
        lend.setLendStartDate(lendStartDate);
        //计算结束日期
        LocalDate lendEndDate = lendStartDate.plusMonths(borrowInfo.getPeriod());
        lend.setLendEndDate(lendEndDate);

        //描述
        lend.setLendInfo(borrowInfoApprovalVO.getLendInfo());

        //设置平台预期受益(年费费率转化为月化费率然后乘以借款月份)标的金额 * 年化/12 * 期数
        BigDecimal monthRate = lend.getServiceRate().divide(new BigDecimal(12), 8, BigDecimal.ROUND_DOWN);//小数点精确,抹零
        BigDecimal expectMount = lend.getAmount().multiply(monthRate.multiply(new BigDecimal(lend.getPeriod())));
        lend.setExpectAmount(expectMount);//预期受益

        lend.setRealAmount(new BigDecimal(0));//实际收益
        lend.setStatus(LendStatusEnum.INVEST_RUN.getStatus());//标的状态

        //标的不需审核通过,生成标的直接通过,直接审核通过的时间
        lend.setCheckTime(LocalDateTime.now());//审核通过时间
        //硬编码
        lend.setCheckAdminId(1L);//设置审核人

        //存入数据库
        baseMapper.insert(lend);
    }

    /**
     * @param :
     * @return List<Lend>
     * @author Likejin
     * @description 后台管理系统展示标的
     * @date 2023/4/17 9:50
     */

    @Override
    public List<Lend> selectList() {
        List<Lend> lendList = baseMapper.selectList(null);
        lendList.forEach(lend -> {
            //转换编码为字符串
            String returnMethod = dictService.getNameByParentDictCodeAndValue("returnMethod",lend.getReturnMethod());
            String status = LendStatusEnum.getMsgByStatus(lend.getStatus());

            lend.getParam().put("returnMethod",returnMethod);
            lend.getParam().put("status",status);
        });

        return lendList;
    }

    /**
     * @param id:
     * @return Map<String,Object>
     * @author Likejin
     * @description 获取标的详情
     * @date 2023/4/17 9:57
     */

    @Override
    public Map<String, Object> getLendDetail(Long id) {
        //查询标的对象lend
        Lend lend = baseMapper.selectById(id);
        //将lend数据组装编码为字符串
        String returnMethod = dictService.getNameByParentDictCodeAndValue("returnMethod", lend.getReturnMethod());
        String status = LendStatusEnum.getMsgByStatus(lend.getStatus());
        lend.getParam().put("returnMethod", returnMethod);
        lend.getParam().put("status", status);


        //根据user_id获取借款人对象(写过,借用前面的数据)
        QueryWrapper<Borrower> borrowerQueryWrapper = new QueryWrapper<Borrower>();
        borrowerQueryWrapper.eq("user_id", lend.getUserId());
        Borrower borrower = borrowerMapper.selectOne(borrowerQueryWrapper);

        //组装借款人对象
        BorrowerDetailVO borrowerDetailVO = borrowerService.getBorrowerDetailVOById(borrower.getId());

        //组装数据
        Map<String, Object> result = new HashMap<>();
        result.put("lend", lend);
        result.put("borrower", borrowerDetailVO);

        return result;

    }
}

  • 调用工具类实现业务编号的生成
package com.atguigu.srb.core.util;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;

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();
    }

}

⑤后端业务逻辑

  • 新增标的
    标的对应的表为lend表。
    在审批时增加lend表时可以获得审批表borrowInfoApprovalVO和具体的借款表BorrowInfo,通过这两个封装lend。注意其中计算预期受益,转换时间类型(前端传来字符串转换为时间类型)
  • 标的列表
    在获取标的列表时需要转换编码为字符串(Dict表)
  • 获取标的详情
    通过标的id获取标的id,先转换标的信息的编码,根据标的的user_id获取borrower借款人信息,获取借款人信息详情(之前做过),组装到map集合中

未更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值