认清现实,放弃幻想,准备斗争
一、平台放款
1、需求描述
标的募资时间到,平台会操作放款或撤标,如果达到放款条件则操作放款
说明:撤标过程与放款过程一致,处理业务相对简单,只是将出借金额返回给出借人即可,可以自行完成
2、相关数据库表
还款人还款记录:lend_return
投资人回款记录:lend_item_return
3、参考文档
参考《汇付宝商户账户技术文档》3.11满标放款
二、具体步骤
step1:放款
放款是一个同步接口,如果放款返回成功,那么我们要处理平台业务
step2:处理业务如下
(1)标的状态和标的平台收益
(2)给借款账号转入金额
(3)增加借款交易流水
(4)解冻并扣除投资人资金
(5)增加投资人交易流水
(6)生成借款人还款计划和出借人回款计划
管理平台放款
1、Controller
AdminLendController
@ApiOperation("放款") @GetMapping("/makeLoan/{id}") public R makeLoan( @ApiParam(value = "标的id", required = true) @PathVariable("id") Long id) { lendService.makeLoan(id); return R.ok().message("放款成功"); }
2、满标放款
接口:LendService
/** * 满标放款 * @param lendId */ void makeLoan(Long lendId);
实现:LendServiceImpl
@Resource private UserInfoMapper userInfoMapper; @Resource private UserAccountMapper userAccountMapper; @Resource private LendItemService lendItemService; @Resource private TransFlowService transFlowService; @Transactional(rollbackFor = Exception.class) @Override public void makeLoan(Long lendId) { //获取标的信息 Lend lend = baseMapper.selectById(lendId); //放款接口调用 Map<String, Object> paramMap = new HashMap<>(); paramMap.put("agentId", HfbConst.AGENT_ID); paramMap.put("agentProjectCode", lend.getLendNo());//标的编号 String agentBillNo = LendNoUtils.getLoanNo();//放款编号 paramMap.put("agentBillNo", agentBillNo); //平台收益,放款扣除,借款人借款实际金额=借款金额-平台收益 //月年化 BigDecimal monthRate = lend.getServiceRate().divide(new BigDecimal(12), 8, BigDecimal.ROUND_DOWN); //平台实际收益 = 已投金额 * 月年化 * 标的期数 BigDecimal realAmount = lend.getInvestAmount().multiply(monthRate).multiply(new BigDecimal(lend.getPeriod())); paramMap.put("mchFee", realAmount); //商户手续费(平台实际收益) paramMap.put("timestamp", RequestHelper.getTimestamp()); String sign = RequestHelper.getSign(paramMap); paramMap.put("sign", sign); log.info("放款参数:" + JSONObject.toJSONString(paramMap)); //发送同步远程调用 JSONObject result = RequestHelper.sendRequest(paramMap, HfbConst.MAKE_LOAD_URL); log.info("放款结果:" + result.toJSONString()); //放款失败 if (!"0000".equals(result.getString("resultCode"))) { throw new BusinessException(result.getString("resultMsg")); } //更新标的信息 lend.setRealAmount(realAmount); lend.setStatus(LendStatusEnum.PAY_RUN.getStatus()); lend.setPaymentTime(LocalDateTime.now()); baseMapper.updateById(lend); //获取借款人信息 Long userId = lend.getUserId(); UserInfo userInfo = userInfoMapper.selectById(userId); String bindCode = userInfo.getBindCode(); //给借款账号转入金额 BigDecimal total = new BigDecimal(result.getString("voteAmt")); userAccountMapper.updateAccount(bindCode, total, new BigDecimal(0)); //新增借款人交易流水 TransFlowBO transFlowBO = new TransFlowBO( agentBillNo, bindCode, total, TransTypeEnum.BORROW_BACK, "借款放款到账,编号:" + lend.getLendNo());//项目编号 transFlowService.saveTransFlow(transFlowBO); //获取投资列表信息 List<LendItem> lendItemList = lendItemService.selectByLendId(lendId, 1); lendItemList.stream().forEach(item -> { //获取投资人信息 Long investUserId = item.getInvestUserId(); UserInfo investUserInfo = userInfoMapper.selectById(investUserId); String investBindCode = investUserInfo.getBindCode(); //投资人账号冻结金额转出 BigDecimal investAmount = item.getInvestAmount(); //投资金额 userAccountMapper.updateAccount(investBindCode, new BigDecimal(0), investAmount.negate()); //新增投资人交易流水 TransFlowBO investTransFlowBO = new TransFlowBO( LendNoUtils.getTransNo(), investBindCode, investAmount, TransTypeEnum.INVEST_UNLOCK, "冻结资金转出,出借放款,编号:" + lend.getLendNo());//项目编号 transFlowService.saveTransFlow(investTransFlowBO); }); //放款成功生成借款人还款计划和投资人回款计划 // TODO }
3、根据lendId获取投资记录
接口:LendItemService
List<LendItem> selectByLendId(Long lendId, Integer status);
实现:LendItemServiceImpl
@Override public List<LendItem> selectByLendId(Long lendId, Integer status) { QueryWrapper<LendItem> queryWrapper = new QueryWrapper(); queryWrapper.eq("lend_id", lendId); queryWrapper.eq("status", status); List<LendItem> lendItemList = baseMapper.selectList(queryWrapper); return lendItemList; }
前端整合
srb-admin
1、定义api
创建 src/api/core/lend.js
makeLoan(id) { return request({ url: `/admin/core/lend/makeLoan/${id}`, method: 'get' }) }
2、页面模板
src/views/core/lend/list.vue
<el-button v-if="scope.row.status == 1" type="warning" size="mini" @click="makeLoan(scope.row.id)"> 放款 </el-button>
3、页面脚本
src/views/core/lend/list.vue
makeLoan(id) { this.$confirm('确定放款吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }) .then(() => { return lendApi.makeLoan(id) }) .then(response => { //放款成功则重新获取数据列表 this.fetchData() this.$message({ type: 'success', message: response.message }) }) .catch(error => { console.log('取消', error) if (error === 'cancel') { this.$message({ type: 'info', message: '已取消放款' }) } }) }