微服务项目:尚融宝(52)(核心业务流程:投标(3))

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
简介: 微服务项目:尚融宝(52)(核心业务流程:投标(3))

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


一、后端接口



1、实现思路


投标时要在服务器端校验数据:

  • 标的状态必须为募资中
  • 标的不能超卖
  • 账户可用余额充足


2、创建VO


创建InvestVO


@Data
@ApiModel(description = "投标信息")
public class InvestVO {
    private Long lendId;
    //投标金额
    private String investAmount;
    //用户id
    private Long investUserId;
    //用户姓名
    private String investName;
}


3、Controller


LendItemController


@Api(tags = "标的的投资")
@RestController
@RequestMapping("/api/core/lendItem")
@Slf4j
public class LendItemController {
    @Resource
    LendItemService lendItemService;
    @ApiOperation("会员投资提交数据")
    @PostMapping("/auth/commitInvest")
    public R commitInvest(@RequestBody InvestVO investVO, HttpServletRequest request) {
        String token = request.getHeader("token");
        Long userId = JwtUtils.getUserId(token);
        String userName = JwtUtils.getUserName(token);
        investVO.setInvestUserId(userId);
        investVO.setInvestName(userName);
        //构建充值自动提交表单
        String formStr = lendItemService.commitInvest(investVO);
        return R.ok().data("formStr", formStr);
    }
}



4、Service


接口:LendItemService


String commitInvest(InvestVO investVO);


实现:LendItemServiceImpl


@Resource
private LendMapper lendMapper;
@Resource
private LendService lendService;
@Resource
private UserAccountService userAccountService;
@Resource
private UserBindService userBindService;
@Override
public String commitInvest(InvestVO investVO) {
    //输入校验==========================================
    Long lendId = investVO.getLendId();
    //获取标的信息
    Lend lend = lendMapper.selectById(lendId);
    //标的状态必须为募资中
    Assert.isTrue(
        lend.getStatus().intValue() == LendStatusEnum.INVEST_RUN.getStatus().intValue(),
        ResponseEnum.LEND_INVEST_ERROR);
    //标的不能超卖:(已投金额 + 本次投资金额 )>=标的金额(超卖)
    BigDecimal sum = lend.getInvestAmount().add(new BigDecimal(investVO.getInvestAmount()));
    Assert.isTrue(sum.doubleValue() <= lend.getAmount().doubleValue(),
                  ResponseEnum.LEND_FULL_SCALE_ERROR);
    //账户可用余额充足:当前用户的余额 >= 当前用户的投资金额(可以投资)
    Long investUserId = investVO.getInvestUserId();
    BigDecimal amount = userAccountService.getAccount(investUserId);//获取当前用户的账户余额
    Assert.isTrue(amount.doubleValue() >= Double.parseDouble(investVO.getInvestAmount()),
                  ResponseEnum.NOT_SUFFICIENT_FUNDS_ERROR);
    //在商户平台中生成投资信息==========================================
    //标的下的投资信息
    LendItem lendItem = new LendItem();
    lendItem.setInvestUserId(investUserId);//投资人id
    lendItem.setInvestName(investVO.getInvestName());//投资人名字
    String lendItemNo = LendNoUtils.getLendItemNo();
    lendItem.setLendItemNo(lendItemNo); //投资条目编号(一个Lend对应一个或多个LendItem)
    lendItem.setLendId(investVO.getLendId());//对应的标的id
    lendItem.setInvestAmount(new BigDecimal(investVO.getInvestAmount())); //此笔投资金额
    lendItem.setLendYearRate(lend.getLendYearRate());//年化
    lendItem.setInvestTime(LocalDateTime.now()); //投资时间
    lendItem.setLendStartDate(lend.getLendStartDate()); //开始时间
    lendItem.setLendEndDate(lend.getLendEndDate()); //结束时间
    //预期收益
    BigDecimal expectAmount = lendService.getInterestCount(
        lendItem.getInvestAmount(),
        lendItem.getLendYearRate(),
        lend.getPeriod(),
        lend.getReturnMethod());
    lendItem.setExpectAmount(expectAmount);
    //实际收益
    lendItem.setRealAmount(new BigDecimal(0));
    lendItem.setStatus(0);//默认状态:刚刚创建
    baseMapper.insert(lendItem);
    //组装投资相关的参数,提交到汇付宝资金托管平台==========================================
    //在托管平台同步用户的投资信息,修改用户的账户资金信息==========================================
    //获取投资人的绑定协议号
    String bindCode = userBindService.getBindCodeByUserId(investUserId);
    //获取借款人的绑定协议号
    String benefitBindCode = userBindService.getBindCodeByUserId(lend.getUserId());
    //封装提交至汇付宝的参数
    Map<String, Object> paramMap = new HashMap<>();
    paramMap.put("agentId", HfbConst.AGENT_ID);
    paramMap.put("voteBindCode", bindCode);
    paramMap.put("benefitBindCode",benefitBindCode);
    paramMap.put("agentProjectCode", lend.getLendNo());//项目标号
    paramMap.put("agentProjectName", lend.getTitle());
    //在资金托管平台上的投资订单的唯一编号,要和lendItemNo保持一致。
    paramMap.put("agentBillNo", lendItemNo);//订单编号
    paramMap.put("voteAmt", investVO.getInvestAmount());
    paramMap.put("votePrizeAmt", "0");
    paramMap.put("voteFeeAmt", "0");
    paramMap.put("projectAmt", lend.getAmount()); //标的总金额
    paramMap.put("note", "");
    paramMap.put("notifyUrl", HfbConst.INVEST_NOTIFY_URL); //检查常量是否正确
    paramMap.put("returnUrl", HfbConst.INVEST_RETURN_URL);
    paramMap.put("timestamp", RequestHelper.getTimestamp());
    String sign = RequestHelper.getSign(paramMap);
    paramMap.put("sign", sign);
    //构建充值自动提交表单
    String formStr = FormHelper.buildForm(HfbConst.INVEST_URL, paramMap);
    return formStr;
}



5、UserBindService


创建一个通用的Service方法,以方便调用,根据userId获取用户绑定账号

接口:UserBindService


String getBindCodeByUserId(Long userId);



实现:UserBindServiceImpl


@Override
public String getBindCodeByUserId(Long userId){
    QueryWrapper<UserBind> userBindQueryWrapper = new QueryWrapper<>();
    userBindQueryWrapper.eq("user_id", userId);
    UserBind userBind = baseMapper.selectOne(userBindQueryWrapper);
    String bindCode = userBind.getBindCode();
    return bindCode;
}



cf5692cb24854b5ebf69f8153d44dc31.png


今日分享


计算机发展的四个阶段和计算机时代的开始


⑴计算机发展的分代按照不同的规范有不同的分法。

通常是按计算机中硬件所采用的电子逻辑器件划分成电子管、晶体管、中小规模集成电路、大规模超大规模集成电路四个阶段;

也有一种观点把计算机的发展大致分为四个时期,即大型机时期、小型机时期、 PC 时期(或客户 / 服务器、 PC/ 服务器)时期和 Internet 或以网络为中心)时期。


⑵通常 所说的计算机时代 ” 从何时开始?


认为 1951 年,世界上第一台商品化批量生产的计算机 UNIVA C-I 投产,计算机从此从实验室走向社会,由单纯为军事服务进入为社会公众服务,被认为是计算机时代的真正开始。


相关文章
|
27天前
|
Java Maven Android开发
微服务——SpringBoot使用归纳——Spring Boot开发环境搭建和项目启动
本文介绍了Spring Boot开发环境的搭建和项目启动流程。主要内容包括:jdk的配置(IDEA、STS/eclipse设置方法)、Spring Boot工程的构建方式(IDEA快速构建、官方构建工具start.spring.io使用)、maven配置(本地maven路径与阿里云镜像设置)以及编码配置(IDEA和eclipse中的编码设置)。通过这些步骤,帮助开发者顺利完成Spring Boot项目的初始化和运行准备。
98 0
微服务——SpringBoot使用归纳——Spring Boot开发环境搭建和项目启动
|
27天前
|
Java 测试技术 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
本课主要讲解Spring Boot项目中的属性配置方法。在实际开发中,测试与生产环境的配置往往不同,因此不应将配置信息硬编码在代码中,而应使用配置文件管理,如`application.yml`。例如,在微服务架构下,可通过配置文件设置调用其他服务的地址(如订单服务端口8002),并利用`@Value`注解在代码中读取这些配置值。这种方式使项目更灵活,便于后续修改和维护。
26 0
|
27天前
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录——使用Logger在项目中打印日志
本文介绍了如何在项目中使用Logger打印日志。通过SLF4J和Logback,可设置不同日志级别(如DEBUG、INFO、WARN、ERROR)并支持占位符输出动态信息。示例代码展示了日志在控制器中的应用,说明了日志配置对问题排查的重要性。附课程源码下载链接供实践参考。
69 0
|
27天前
|
Java 数据库 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——指定项目配置文件
在实际项目中,开发环境和生产环境的配置往往不同。为简化配置切换,可通过创建 `application-dev.yml` 和 `application-pro.yml` 分别管理开发与生产环境配置,如设置不同端口(8001/8002)。在 `application.yml` 中使用 `spring.profiles.active` 指定加载的配置文件,实现环境快速切换。本节还介绍了通过配置类读取参数的方法,适用于微服务场景,提升代码可维护性。课程源码可从 [Gitee](https://gitee.com/eson15/springboot_study) 下载。
51 0
|
27天前
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
在微服务架构中,随着业务复杂度增加,项目可能需要调用多个微服务。为避免使用`@Value`注解逐一引入配置的繁琐,可通过定义配置类(如`MicroServiceUrl`)并结合`@ConfigurationProperties`注解实现批量管理。此方法需在配置文件中设置微服务地址(如订单、用户、购物车服务),并通过`@Component`将配置类纳入Spring容器。最后,在Controller中通过`@Resource`注入配置类即可便捷使用,提升代码可维护性。
33 0
|
7月前
|
消息中间件 监控 开发工具
微服务(三)-实现自动刷新配置(不重启项目情况下)
微服务(三)-实现自动刷新配置(不重启项目情况下)
|
9月前
|
负载均衡 Java 开发者
如何在Spring Boot项目中实现微服务架构?
如何在Spring Boot项目中实现微服务架构?
|
9月前
|
消息中间件 负载均衡 Java
最容易学会的springboot gralde spring cloud 多模块微服务项目
最容易学会的springboot gralde spring cloud 多模块微服务项目
|
11月前
|
监控 数据可视化 安全
智慧工地SaaS可视化平台源码,PC端+APP端,支持二开,项目使用,微服务+Java++vue+mysql
环境实时数据、动态监测报警,实时监控施工环境状态,有针对性地预防施工过程中的环境污染问题,打造文明生态施工,创造绿色的生态环境。
113 0
智慧工地SaaS可视化平台源码,PC端+APP端,支持二开,项目使用,微服务+Java++vue+mysql
|
11月前
|
Java Maven 微服务
微服务项目-将普通文件夹设为模块与添加services窗口
微服务项目-将普通文件夹设为模块与添加services窗口
73 0