【业务功能篇99】微服务-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.rhkb.cn/news/131397.html

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

相关文章

【ESP32】带 log 记录的 malloc 动态申请内存,用于debug 调试查找报错原因

本文章以ESP32为依托&#xff0c;旨在解决在【嵌入式工程】开发过程中&#xff0c;在动态申请内存这部分&#xff0c;由于 malloc 之后&#xff0c;忘记 free 释放&#xff0c;造成内存溢出导致 MCU重启的问题 &#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好…

linux安装nacos2.2.0

1、使用docker拉取镜像&#xff1a;docker pull nacos/nacos-server:v2.2.0 2、下载官方配置文件&#xff1a;https://github.com/alibaba/nacos/releases 3、修改配置文件的数据库连接信息&#xff0c;修改完成后将配置文件移至挂载目录/home/shixp/docker/nacos/conf&#xf…

统计表和流程分析,也能同屏呈现_三叠云

表单统计&流程分析 路径 表单设计 >> 表单设置 >> 拓展设置 >> 表单统计 功能简介 新增表单统计、流程分析功能&#xff08;Beta版&#xff09;。可在当前列表&#xff0c;直接看到表单的统计表和流程分析数据统计图表。 1. 统计表&#xff1a;统计…

实时美颜的背后:视频直播美颜SDK的算法与原理

美颜技术的应用范围已经广泛扩展&#xff0c;从自拍照片到视频直播&#xff0c;都可以看到它的踪迹。然而&#xff0c;视频直播的实时性要求比静态图像高得多。要实现实时美颜&#xff0c;必须克服许多技术挑战。这就是视频直播美颜SDK的用武之地。 一、实时美颜的挑战 实时…

如何使用CMD恢复删除的分区?

分区删除后可以恢复吗&#xff1f; 磁盘分区旨在二级存储上创建一个或多个区域&#xff0c;然后你可以单独管理每个区域&#xff0c;这些区域就是分区。因此&#xff0c;对新安装的存储设备进行分区是很重要的环节&#xff0c;只有分区后才可以在这些设备上创建文件并保存数…

Spring Boot 下载文件(word/excel等)文件名中文乱码问题|构建打包不存在模版文件(templates等)

Spring Boot 下载文件(word/excel等)文件名中文乱码问题&#xff5c;构建打包不存在模版文件(templates等) 准备文件&#xff0c;这里我放在resource下的templates路径 在pom中配置构建打包的资源&#xff0c;更新maven 如果使用了assembly打包插件这样配置可能仍不生效&#…

理财是什么?怎样学习理财?

大家好&#xff0c;我是财富智星&#xff0c;今天跟大家分享一下理财是什么&#xff1f;怎样学习理财的方法。 一、理财的基本原则 1、理财应注重投资而不是投机&#xff0c;要与时间为友。 让我们先考虑以下问题&#xff1a;什么样的回报才算是真正的高回报&#xff1f;假设有…

2023年一级建造师建设工程经济真题

2023年一级建造师建设工程经济真题 1.根据《建设工程工程量清单计价规范》规定&#xff0c;代表专业工程的项目编码是 ()。 A、1&#xff0c;2 B、3&#xff0c;4 C、5&#xff0c;6 D、7&#xff0c;8&#xff0c;9 【答案】B 2.某公司希望所投资项目在第5年末回收1000万…

LoGoNet:基于局部到全局跨模态融合的精确 3D 目标检测

论文地址&#xff1a;https://arxiv.org/abs/2303.03595 论文代码&#xff1a;https://github.com/sankin97/LoGoNet 论文背景 激光雷达传感器点云通常是稀疏的&#xff0c;无法提供足够的上下文来区分远处的区域&#xff0c;从而造成性能次优。 激光雷达-摄像机融合方法在三…

[NLP] LLM---扩充词表LLama2-构建中文tokenization

使用SentencePiece的除了从0开始训练大模型的土豪和大公司外&#xff0c;大部分应该都是使用其为当前开源的大模型扩充词表&#xff0c;比如为LLama扩充通用中文词表&#xff08;通用中文词表&#xff0c;或者 垂直领域词表&#xff09;。那这部分工作有没有意义呢&#xff1f;…

实验室电磁铁EM4的技术参数

锦正茂EM4电磁铁可以通过更换电磁铁极头在一定范围内改善磁场的大小和磁场的均匀度 &#xff0c;并且可以通过调整极头间距改变磁场的大小&#xff0c;该种类型的电磁铁能够很好的与客户设计的磁场平台兼容。主要用于磁滞现象研究、磁化系数测量、霍尔效应研究、磁光实验、磁场…

WebSocket的优缺点

WebSocket的优缺点 1. WebSocket概念 1.1 WebSocket优点 低延迟全双工长期运行双向实时通信 1.2 什么是心跳机制 为了保持WebSocket稳定的长连接,在建立连接后,服务器和客户端之间需要通过心跳包来保持连接状态,以防止连接因长时间没有数据传输而被切断. 心跳包是一直特殊…

学会使用MySQL数据库(1)数据库相关背景了解

目录 什么是数据库 客户端-服务器&#xff08;Client-Server&#xff09; 数据库分类 MySQL服务器安装 内存和外存 什么是数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 文件保存数据有以下几个缺点&#xff1a; 文件的安全性问题文件不利于数据查询…

Spring框架中的Resource接口是什么,以及它在加载和访问资源时的关键作用

文章目录 什么是 Resource 接口&#xff1f;使用 Resource 加载资源使用 Resource 访问文件系统资源总结 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 ✨收录专栏&#xff1a;Java框架 ✨文章内…

没出息的项目经理的5大表现

大家好&#xff0c;我是老原。 都说&#xff0c;30岁的项目经理凶猛如狼&#xff0c;40岁的项目经理狡猾如狐。 实际上&#xff0c;又有多少项目经理能做到这般。 有多少项目经理&#xff0c;兢兢业业工作个几年&#xff0c;最后还是守着一亩三分地&#xff0c;既没有升职加…

PMP认证可以用来干什么呢?

PMP(项目管理专业人士&#xff09;认证是一项国际上广为认可的专业认证&#xff0c;具有以下几个重要用途和好处&#xff1a; 1. 提升职业竞争力&#xff1a; PMP认证是项目管理领域具有权威性和声誉的认证之一。持有PMP认证可以证明你具备了相关知识、技能和经验&#xff0c…

【LeetCode75】第五十四题 咒语和药水的成功对数

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们两个数组&#xff0c;要我们找出第一个数组中每个元素能和另一个数组的元素匹配的数量。匹配的条件是乘积大于特定的值。 那么…

[SSM]MyBatisPlus拓展

五、拓展篇 5.1逻辑删除 在电商网站中&#xff0c;我们会上架很多商品&#xff0c;这些商品下架以后&#xff0c;我们如果将这些商品从数据库中删除&#xff0c;那么在年底统计商品的时候&#xff0c;这个商品要统计的&#xff0c;所以这个商品信息我们是不能删除的。 如果商城…

LC1798. 你能构造出连续值的最大数目(JAVA)

LC1798. 你能构造出连续值的最大数目 题目描述贪心算法代码演示 题目描述 难度 - 中等 Leetcode - 1798. 你能构造出连续值的最大数目 给你一个长度为 n 的整数数组 coins &#xff0c;它代表你拥有的 n 个硬币。第 i 个硬币的值为 coins[i] 。如果你从这些硬币中选出一部分硬币…

佛山融资融券(两融)开户利率最低能做到多少?5%!

佛山融资融券(两融)开户利率最低能做到多少?5%! 具体佛山融资融券(两融)开户利率最低能做到多少&#xff0c;需要根据不同的券商政策而定。不同的券商可能具有不同的优惠政策和开户条件&#xff0c;因此开户前应该仔细了解券商的政策和条件。 融资融券是投资者通过证券公司向…