• 微服务项目:尚融宝(59)(核心业务流程:提现和还款(2))


    认清现实,放弃幻想,准备斗争

    需求

    放款成功后,会生成借款人的还款计划与出借人的回款计划,然后借款人按照还款计划日期操作还款即可。

    参考《汇付宝商户账户技术文档》3.14还款扣款,处理业务即可

    一、前端整合

    1、还款按钮

    pages/lend/_id.vue


       
            {{ lendReturn.status === 0 ? '还款' : '' }}
       

    2、脚本

    pages/lend/_id.vue

    1. commitReturn(lendReturnId) {
    2. this.$alert(
    3. '
      您即将前往汇付宝确认还款
      '
      ,
    4. '前往汇付宝资金托管平台',
    5. {
    6. dangerouslyUseHTMLString: true,
    7. confirmButtonText: '立即前往',
    8. callback: (action) => {
    9. if (action === 'confirm') {
    10. this.$axios
    11. .$post('/api/core/lendReturn/auth/commitReturn/' + lendReturnId)
    12. .then((response) => {
    13. document.write(response.data.formStr)
    14. })
    15. }
    16. },
    17. }
    18. )

    二、还款接口

    1、Controller

    LendReturnController

    1. @ApiOperation("用户还款")
    2. @PostMapping("/auth/commitReturn/{lendReturnId}")
    3. public R commitReturn(
    4. @ApiParam(value = "还款计划id", required = true)
    5. @PathVariable Long lendReturnId, HttpServletRequest request) {
    6. String token = request.getHeader("token");
    7. Long userId = JwtUtils.getUserId(token);
    8. String formStr = lendReturnService.commitReturn(lendReturnId, userId);
    9. return R.ok().data("formStr", formStr);
    10. }

    2、Service

    接口:LendReturnService

    String commitReturn(Long lendReturnId, Long userId);

    实现:LendReturnServiceImpl 

    1. @Resource
    2. private UserAccountService userAccountService;
    3. @Resource
    4. private LendMapper lendMapper;
    5. @Resource
    6. private UserBindService userBindService;
    7. @Resource
    8. private LendItemReturnService lendItemReturnService;
    9. @Transactional(rollbackFor = Exception.class)
    10. @Override
    11. public String commitReturn(Long lendReturnId, Long userId) {
    12. //获取还款记录
    13. LendReturn lendReturn = baseMapper.selectById(lendReturnId);
    14. //判断账号余额是否充足
    15. BigDecimal amount = userAccountService.getAccount(userId);
    16. Assert.isTrue(amount.doubleValue() >= lendReturn.getTotal().doubleValue(),
    17. ResponseEnum.NOT_SUFFICIENT_FUNDS_ERROR);
    18. //获取借款人code
    19. String bindCode = userBindService.getBindCodeByUserId(userId);
    20. //获取lend
    21. Long lendId = lendReturn.getLendId();
    22. Lend lend = lendMapper.selectById(lendId);
    23. Map paramMap = new HashMap<>();
    24. paramMap.put("agentId", HfbConst.AGENT_ID);
    25. //商户商品名称
    26. paramMap.put("agentGoodsName", lend.getTitle());
    27. //批次号
    28. paramMap.put("agentBatchNo",lendReturn.getReturnNo());
    29. //还款人绑定协议号
    30. paramMap.put("fromBindCode", bindCode);
    31. //还款总额
    32. paramMap.put("totalAmt", lendReturn.getTotal());
    33. paramMap.put("note", "");
    34. //还款明细
    35. List> lendItemReturnDetailList = lendItemReturnService.addReturnDetail(lendReturnId);
    36. paramMap.put("data", JSONObject.toJSONString(lendItemReturnDetailList));
    37. paramMap.put("voteFeeAmt", new BigDecimal(0));
    38. paramMap.put("notifyUrl", HfbConst.BORROW_RETURN_NOTIFY_URL);
    39. paramMap.put("returnUrl", HfbConst.BORROW_RETURN_RETURN_URL);
    40. paramMap.put("timestamp", RequestHelper.getTimestamp());
    41. String sign = RequestHelper.getSign(paramMap);
    42. paramMap.put("sign", sign);
    43. //构建自动提交表单
    44. String formStr = FormHelper.buildForm(HfbConst.BORROW_RETURN_URL, paramMap);
    45. return formStr;
    46. }

    3、还款明细Service

    根据还款id获取回款列表

    LendReturnService接口:

    List> addReturnDetail(Long lendReturnId);

    LendReturnServiceImpl实现: 

    1. @Resource
    2. private UserBindService userBindService;
    3. @Resource
    4. private LendItemMapper lendItemMapper;
    5. @Resource
    6. private LendMapper lendMapper;
    7. @Resource
    8. private LendReturnMapper lendReturnMapper;
    9. /**
    10. * 添加还款明细
    11. * @param lendReturnId
    12. */
    13. @Override
    14. public List> addReturnDetail(Long lendReturnId) {
    15. //获取还款记录
    16. LendReturn lendReturn = lendReturnMapper.selectById(lendReturnId);
    17. //获取标的信息
    18. Lend lend = lendMapper.selectById(lendReturn.getLendId());
    19. //根据还款id获取回款列表
    20. List lendItemReturnList = this.selectLendItemReturnList(lendReturnId);
    21. List> lendItemReturnDetailList = new ArrayList<>();
    22. for(LendItemReturn lendItemReturn : lendItemReturnList) {
    23. LendItem lendItem = lendItemMapper.selectById(lendItemReturn.getLendItemId());
    24. String bindCode = userBindService.getBindCodeByUserId(lendItem.getInvestUserId());
    25. Map map = new HashMap<>();
    26. //项目编号
    27. map.put("agentProjectCode", lend.getLendNo());
    28. //出借编号
    29. map.put("voteBillNo", lendItem.getLendItemNo());
    30. //收款人(出借人)
    31. map.put("toBindCode", bindCode);
    32. //还款金额
    33. map.put("transitAmt", lendItemReturn.getTotal());
    34. //还款本金
    35. map.put("baseAmt", lendItemReturn.getPrincipal());
    36. //还款利息
    37. map.put("benifitAmt", lendItemReturn.getInterest());
    38. //商户手续费
    39. map.put("feeAmt", new BigDecimal("0"));
    40. lendItemReturnDetailList.add(map);
    41. }
    42. return lendItemReturnDetailList;
    43. }

    根据还款计划id获取对应的回款计划列表

    接口:

    List selectLendItemReturnList(Long lendReturnId);

    实现: 

    1. @Override
    2. public List selectLendItemReturnList(Long lendReturnId) {
    3. QueryWrapper queryWrapper = new QueryWrapper<>();
    4. queryWrapper.eq("lend_return_id", lendReturnId);
    5. List lendItemReturnList = baseMapper.selectList(queryWrapper);
    6. return lendItemReturnList;
    7. }

    三、回调接口

    1、Controller

    LendReturnController

    1. @ApiOperation("还款异步回调")
    2. @PostMapping("/notifyUrl")
    3. public String notifyUrl(HttpServletRequest request) {
    4. Map paramMap = RequestHelper.switchMap(request.getParameterMap());
    5. log.info("还款异步回调:" + JSON.toJSONString(paramMap));
    6. //校验签名
    7. if(RequestHelper.isSignEquals(paramMap)) {
    8. if("0001".equals(paramMap.get("resultCode"))) {
    9. lendReturnService.notify(paramMap);
    10. } else {
    11. log.info("还款异步回调失败:" + JSON.toJSONString(paramMap));
    12. return "fail";
    13. }
    14. } else {
    15. log.info("还款异步回调签名错误:" + JSON.toJSONString(paramMap));
    16. return "fail";
    17. }
    18. return "success";
    19. }

    2、Service

    接口:LendReturnService

    void notify(Map paramMap);

    实现:LendReturnServiceImpl 

    1. @Resource
    2. private TransFlowService transFlowService;
    3. @Resource
    4. private UserAccountMapper userAccountMapper;
    5. @Resource
    6. private LendItemReturnMapper lendItemReturnMapper;
    7. @Resource
    8. private LendItemMapper lendItemMapper;
    9. @Transactional(rollbackFor = Exception.class)
    10. @Override
    11. public void notify(Map paramMap) {
    12. log.info("还款成功");
    13. //还款编号
    14. String agentBatchNo = (String)paramMap.get("agentBatchNo");
    15. boolean result = transFlowService.isSaveTransFlow(agentBatchNo);
    16. if(result){
    17. log.warn("幂等性返回");
    18. return;
    19. }
    20. //获取还款数据
    21. String voteFeeAmt = (String)paramMap.get("voteFeeAmt");
    22. QueryWrapper lendReturnQueryWrapper = new QueryWrapper();
    23. lendReturnQueryWrapper.eq("return_no", agentBatchNo);
    24. LendReturn lendReturn = baseMapper.selectOne(lendReturnQueryWrapper);;
    25. //更新还款状态
    26. lendReturn.setStatus(1);
    27. lendReturn.setFee(new BigDecimal(voteFeeAmt));
    28. lendReturn.setRealReturnTime(LocalDateTime.now());
    29. baseMapper.updateById(lendReturn);
    30. //更新标的信息
    31. Lend lend = lendMapper.selectById(lendReturn.getLendId());
    32. //最后一次还款更新标的状态
    33. if(lendReturn.getLast()) {
    34. lend.setStatus(LendStatusEnum.PAY_OK.getStatus());
    35. lendMapper.updateById(lend);
    36. }
    37. //借款账号转出金额
    38. BigDecimal totalAmt = new BigDecimal((String)paramMap.get("totalAmt"));//还款金额
    39. String bindCode = userBindService.getBindCodeByUserId(lend.getUserId());
    40. userAccountMapper.updateAccount(bindCode, totalAmt.negate(), new BigDecimal(0));
    41. //借款人交易流水
    42. TransFlowBO transFlowBO = new TransFlowBO(
    43. agentBatchNo,
    44. bindCode,
    45. totalAmt,
    46. TransTypeEnum.RETURN_DOWN,
    47. "借款人还款扣减,项目编号:" + lend.getLendNo() + ",项目名称:" + lend.getTitle());
    48. transFlowService.saveTransFlow(transFlowBO);
    49. //获取回款明细
    50. List lendItemReturnList = lendItemReturnService.selectLendItemReturnList(lendReturn.getId());
    51. lendItemReturnList.forEach(item -> {
    52. //更新回款状态
    53. item.setStatus(1);
    54. item.setRealReturnTime(LocalDateTime.now());
    55. lendItemReturnMapper.updateById(item);
    56. //更新出借信息
    57. LendItem lendItem = lendItemMapper.selectById(item.getLendItemId());
    58. lendItem.setRealAmount(item.getInterest());
    59. lendItemMapper.updateById(lendItem);
    60. //投资账号转入金额
    61. String investBindCode = userBindService.getBindCodeByUserId(item.getInvestUserId());
    62. userAccountMapper.updateAccount(investBindCode, item.getTotal(), new BigDecimal(0));
    63. //投资账号交易流水
    64. TransFlowBO investTransFlowBO = new TransFlowBO(
    65. LendNoUtils.getReturnItemNo(),
    66. investBindCode,
    67. item.getTotal(),
    68. TransTypeEnum.INVEST_BACK,
    69. "还款到账,项目编号:" + lend.getLendNo() + ",项目名称:" + lend.getTitle());
    70. transFlowService.saveTransFlow(investTransFlowBO);
    71. });
    72. }

     上篇链接:

    微服务项目:尚融宝(58)(核心业务流程:提现和还款(1))_一个风轻云淡的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_62436868/article/details/127036047?spm=1001.2014.3001.5501

  • 相关阅读:
    链表-算法总结
    sgx支持数据库环境配置,编译,debug
    NCMMSC 2021丨长短视频多语种多模态识别挑战赛
    学习Android的第二十七天
    更好的print :嫌弃print太单调 那么来试试这几种方法吧
    SpringBoot项目结合mybatis generator自动生成代码
    uniapp 实现滑动元素删除效果
    Future源码一观-JUC系列
    达梦数据库答案
    Silky微服务框架之服务引擎
  • 原文地址:https://blog.csdn.net/m0_62436868/article/details/127043471