【业务功能篇98】微服务-springcloud-springboot-电商订单模块-生成订单服务-锁定库存

八、生成订单

image.png

一个是需要生成订单信息一个是需要生成订单项信息。具体的核心代码为

/*** 创建订单的方法* @param vo* @return*/private OrderCreateTO createOrder(OrderSubmitVO vo) {OrderCreateTO createTO = new OrderCreateTO();// 创建订单OrderEntity orderEntity = buildOrder(vo);createTO.setOrderEntity(orderEntity);// 创建OrderItemEntity 订单项List<OrderItemEntity> orderItemEntitys = buildOrderItems(orderEntity.getOrderSn());createTO.setOrderItemEntitys(orderItemEntitys);return createTO;}/*** 通过购物车中选中的商品来创建对应的购物项信息* @return*/private List<OrderItemEntity> buildOrderItems(String orderSN) {List<OrderItemEntity> orderItemEntitys = new ArrayList<>();// 获取购物车中的商品信息 选中的List<OrderItemVo> userCartItems = cartFeginService.getUserCartItems();if(userCartItems != null && userCartItems.size() > 0){// 统一根据SKUID查询出对应的SPU的信息List<Long> spuIds = new ArrayList<>();for (OrderItemEntity orderItemEntity : orderItemEntitys) {if(!spuIds.contains(orderItemEntity.getSpuId())){spuIds.add(orderItemEntity.getOrderId());}}// 远程调用商品服务获取到对应的SPU信息List<OrderItemSpuInfoVO> spuInfos = productService.getOrderItemSpuInfoBySpuId((Long[]) spuIds.toArray());Map<Long, OrderItemSpuInfoVO> map = spuInfos.stream().collect(Collectors.toMap(OrderItemSpuInfoVO::getId, item -> item));for (OrderItemVo userCartItem : userCartItems) {// 获取到商品信息对应的 SPU信息OrderItemSpuInfoVO spuInfo  = map.get(userCartItem.getSpuId());OrderItemEntity orderItemEntity = buildOrderItem(userCartItem,spuInfo);// 绑定对应的订单编号orderItemEntity.setOrderSn(orderSN);orderItemEntitys.add(orderItemEntity);}}return orderItemEntitys;}/*** 根据一个购物车中的商品创建对应的 订单项* @param userCartItem* @return*/private OrderItemEntity buildOrderItem(OrderItemVo userCartItem,OrderItemSpuInfoVO spuInfo) {OrderItemEntity entity = new OrderItemEntity();// SKU信息entity.setSkuId(userCartItem.getSkuId());entity.setSkuName(userCartItem.getTitle());entity.setSkuPic(userCartItem.getImage());entity.setSkuQuantity(userCartItem.getCount());List<String> skuAttr = userCartItem.getSkuAttr();String skuAttrStr = StringUtils.collectionToDelimitedString(skuAttr, ";");entity.setSkuAttrsVals(skuAttrStr);// SPU信息entity.setSpuId(spuInfo.getId());entity.setSpuBrand(spuInfo.getBrandName());entity.setCategoryId(spuInfo.getCatalogId());entity.setSpuPic(spuInfo.getImg());// 优惠信息 忽略// 积分信息entity.setGiftGrowth(userCartItem.getPrice().intValue());entity.setGiftIntegration(userCartItem.getPrice().intValue());return entity;}private OrderEntity buildOrder(OrderSubmitVO vo) {// 创建OrderEntityOrderEntity orderEntity = new OrderEntity();// 创建订单编号String orderSn = IdWorker.getTimeId();orderEntity.setOrderSn(orderSn);MemberVO memberVO = (MemberVO) AuthInterceptor.threadLocal.get();// 设置会员相关的信息orderEntity.setMemberId(memberVO.getId());orderEntity.setMemberUsername(memberVO.getUsername());// 根据收获地址ID获取收获地址的详细信息MemberAddressVo memberAddressVo = memberFeginService.getAddressById(vo.getAddrId());orderEntity.setReceiverCity(memberAddressVo.getCity());orderEntity.setReceiverDetailAddress(memberAddressVo.getDetailAddress());orderEntity.setReceiverName(memberAddressVo.getName());orderEntity.setReceiverPhone(memberAddressVo.getPhone());orderEntity.setReceiverPostCode(memberAddressVo.getPostCode());orderEntity.setReceiverRegion(memberAddressVo.getRegion());orderEntity.setReceiverProvince(memberAddressVo.getProvince());// 设置订单的状态orderEntity.setStatus(OrderConstant.OrderStateEnum.FOR_THE_PAYMENT.getCode());return orderEntity;}

锁定库存的操作,需要操作ware仓储服务。

   /*** 锁定库存的操作* @param vo* @return*/@Transactional@Overridepublic Boolean orderLockStock(WareSkuLockVO vo) {List<OrderItemVo> items = vo.getItems();// 首先找到具有库存的仓库List<SkuWareHasStock> collect = items.stream().map(item -> {SkuWareHasStock skuWareHasStock = new SkuWareHasStock();skuWareHasStock.setSkuId(item.getSkuId());List<WareSkuEntity> wareSkuEntities = this.baseMapper.listHashStock(item.getSkuId());skuWareHasStock.setWareSkuEntities(wareSkuEntities);skuWareHasStock.setNum(item.getCount());return skuWareHasStock;}).collect(Collectors.toList());// 尝试锁定库存for (SkuWareHasStock skuWareHasStock : collect) {Long skuId = skuWareHasStock.getSkuId();List<WareSkuEntity> wareSkuEntities = skuWareHasStock.wareSkuEntities;if(wareSkuEntities == null && wareSkuEntities.size() == 0){// 当前商品没有库存了throw new NoStockExecption(skuId);}// 当前需要锁定的商品的梳理Integer count = skuWareHasStock.getNum();Boolean skuStocked = false; // 表示当前SkuId的库存没有锁定完成for (WareSkuEntity wareSkuEntity : wareSkuEntities) {// 循环获取到对应的 仓库,然后需要锁定库存// 获取当前仓库能够锁定的库存数Integer canStock = wareSkuEntity.getStock() - wareSkuEntity.getStockLocked();if(count <= canStock){// 表示当前的skuId的商品的数量小于等于需要锁定的数量Integer i = this.baseMapper.lockSkuStock(skuId,wareSkuEntity.getWareId(),count);count = 0;skuStocked = true;}else{// 需要锁定的库存大于 可以锁定的库存 就按照已有的库存来锁定Integer i = this.baseMapper.lockSkuStock(skuId,wareSkuEntity.getWareId(),canStock);count = count - canStock;}if(count <= 0 ){// 表示所有的商品都锁定了break;}}if(count > 0){// 说明库存没有锁定完throw new NoStockExecption(skuId);}if(skuStocked == false){// 表示上一个商品的没有锁定库存成功throw new NoStockExecption(skuId);}}return true;}

没有库存或者锁定库存失败我们通过自定义的异常抛出

/*** 自定义异常:锁定库存失败的情况下产生的异常信*/
public class NoStockExecption extends RuntimeException{private Long skuId;public NoStockExecption(Long skuId){super("当前商品["+skuId+"]没有库存了");this.skuId = skuId;}public Long getSkuId() {return skuId;}public void setSkuId(Long skuId) {this.skuId = skuId;}
}

如果下订单操作成功(订单数据和订单项数据)我们就会操作锁库存的行为

image.png

锁定库存失败通过抛异常来使订单操作回滚

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/100395.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【启扬方案】启扬多尺寸安卓屏一体机,助力仓储物料管理系统智能化管理

随着企业供应链管理的不断发展&#xff0c;对仓储物料管理的要求日益提高。企业需要实时追踪和管理物料的流动&#xff0c;提高物流效率、降低库存成本和减少库存的风险。因此&#xff0c;仓储物料管理系统的实现成为必要的手段。 仓储物料管理系统一体机作为一种新型的物料管理…

AJAX学习笔记8 跨域问题及解决方案

AJAX学习笔记7 AJAX实现省市联动_biubiubiu0706的博客-CSDN博客 跨域:指一个域名的网页去请求另外一个域名资源.比如百度页面去请求京东页面资源. 同源与不同源三要素:协议,域名,端口 协议一致,域名一致,端口一致.才算是同源.其他一律不同源 新建项目测试: 1.window.open();…

Word 表格单元格无法垂直居中

Word使用 由于平时也需要用到word编写一些文档&#xff0c;但是咱们就是用的少&#xff0c;很多操作或者技巧不太清楚&#xff0c;很多小问题处理起来反而需要消耗很多时间&#xff0c;所以在这里记录平时遇到的一些问题。 表格无法垂直居中 类似于上图的情况&#xff0c;总之…

R-CNN

目标检测、语义分割 由于我们将区域建议与CNN相结合&#xff0c;我们将我们的方法称为R-CNN:带有CNN特征的区域。 目标检测系统由三个模块组成。第一种方法生成分类独立的区域提案。这些提议定义了可供我们的检测器使用的候选检测集合。第二个模块是一个大型卷积神经网络&…

[极客大挑战 2019]FinalSQL(bypass盲注)

这里是数字型注入&#xff0c;选择一个序号 fuzz ?id1这里过滤了很多东西 使用fuzzSQL字典&#xff0c;这是我自己定义编写的一个fuzz字典&#xff0c;内容较少 select from information . tables whereand " or | & union columns updatexml extractvalue databa…

Liquid Studio 2023.2 Crack

Liquid Studio 提供了用于XML和JSON开发 的高级工具包以及Web 服务测试、数据映射和数据转换工具。 开发环境包含一整套用于设计 XML 和 JSON 数据结构和模式的工具。这些工具提供编辑、验证和高级转换功能。对于新手或专家来说&#xff0c;直观的界面和全面的功能将帮助您节省…

<九> objectARX开发:读写Excel、json与txt格式文件

一、功能描述 在实际应用中,有时候我们需要通过文本格式或者表格等格式来传递数据,例如*.txt、Excel表格或者*.json文件。此时我们就需要想办法来读写这些数据。本节我们来说一下如何读写读写Excel、json与txt格式文件。 二、不同文件格式读写 2.1 读写Excel excel文件的读…

zemax简单非序列光学系统

切换到非序列模式&#xff1a; 建立一个标准面&#xff0c;设置为抛物面&#xff0c;反射 添加灯丝光源&#xff1a; 陈列光线条数是图中蓝色光线的数目&#xff0c;分析光线条数是后续计算用到的光线条数 匝数&#xff08;圈数&#xff09;和长度、曲率半径决定了灯丝光源的形…

立晶半导体Cubic Lattice Inc 专攻音频ADC,音频DAC,音频CODEC,音频CLASS D等CL7016

概述&#xff1a; CL7016是一款高保真USB Type-C兼容音频编解码芯片。可以录制和回放有24比特音乐和声音。内置回放通路信号动态压缩&#xff0c; 最大42db录音通路增益&#xff0c;PDM数字麦克风&#xff0c;和立体声无需电容耳机驱动放大器。 5V单电源供电。兼容USB 2.0全速工…

设计模式(1) - UML类图

1、前言 最近在阅读 Android 源码&#xff0c;时常碰到代码中有一些巧妙的写法&#xff0c;简单的如 MediaPlayerService 中的 IFactory&#xff0c;我知道它是工厂模式&#xff0c;但是却不十分清楚它为什么这么用&#xff1b;复杂点的像 NuPlayer 中的 DeferredActions 机制…

网络编程day6作业

完成网络聊天室编写 ser #define ERR_MSG(msg) do{\fprintf(stderr,"__%d__",__LINE__);\perror(msg);\ }while(0) #define IP "127.0.0.1" #define PORT 6666 //创建链表 Linklistptr list_create(); Linklistptr node_buy(datatype e); int list_inser…

matlab 计算矩阵的条件数

目录 一、概述1、算法概述2、主要函数3、参考文献二、代码实现三、结果展示四、参考链接本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、概述 1、算法概述 条件数法是目前应用最为广泛的一种病态诊断方法。一个方阵…