3.02 创建订单操作详细-订单创建与回滚 (创建订单操作详细)
步骤1:
创建orders订单表,子订单表和订单状态表对应的pojo和mappperOrders和OrderItemsMapperOrderItems和OrderItemsMapperOrderStatus和OrderStatusMapper
步骤2:创建OrderService和对应的实现类
public interface OrderService {/*** 用于创建订单相关信息* @param submitOrderBO*/public OrderVO createOrder(SubmitOrderBO submitOrderBO);
}package com.one.service.order.impl;
import com.one.bo.SubmitOrderBO;
import com.one.enums.OrderStatusEnum;
import com.one.enums.YesOrNo;
import com.one.mapper.OrderItemsMapper;
import com.one.mapper.OrderStatusMapper;
import com.one.mapper.OrdersMapper;
import com.one.pojo.*;
import com.one.service.address.AddressService;
import com.one.service.item.ItemService;
import com.one.service.order.OrderService;
import com.one.vo.MerchantOrdersVO;
import com.one.vo.OrderVO;
import org.n3r.idworker.Sid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;@Service
public class OrderServiceImpl implements OrderService {@Autowiredprivate OrdersMapper ordersMapper;@Autowiredprivate OrderItemsMapper orderItemsMapper;@Autowiredprivate OrderStatusMapper orderStatusMapper;@Autowiredprivate AddressService addressService;@Autowiredprivate ItemService itemService;@Autowiredprivate Sid sid;@Transactional(propagation = Propagation.REQUIRED)@Overridepublic OrderVO createOrder(SubmitOrderBO submitOrderBO) {String userId = submitOrderBO.getUserId();String addressId = submitOrderBO.getAddressId();String itemSpecIds = submitOrderBO.getItemSpecIds();Integer payMethod = submitOrderBO.getPayMethod();String leftMsg = submitOrderBO.getLeftMsg();// 包邮费用设置为0Integer postAmount = 0;String orderId = sid.nextShort();UserAddress address = addressService.queryUserAddres(userId, addressId);// 1. 新订单数据保存Orders newOrder = new Orders();newOrder.setId(orderId);newOrder.setUserId(userId);newOrder.setReceiverName(address.getReceiver());newOrder.setReceiverMobile(address.getMobile());newOrder.setReceiverAddress(address.getProvince() + " " + address.getCity() + " " + address.getDistrict() + " " + address.getDetail());newOrder.setPostAmount(postAmount);newOrder.setPayMethod(payMethod);newOrder.setLeftMsg(leftMsg);newOrder.setIsComment(YesOrNo.NO.type);newOrder.setIsDelete(YesOrNo.NO.type);newOrder.setCreatedTime(new Date());newOrder.setUpdatedTime(new Date());// 2. 循环根据itemSpecIds保存订单商品信息表String itemSpecIdArr[] = itemSpecIds.split(",");Integer totalAmount = 0; // 商品原价累计Integer realPayAmount = 0; // 优惠后的实际支付价格累计for (String itemSpecId : itemSpecIdArr) {// TODO 整合redis后,商品购买的数量重新从redis的购物车中获取int buyCounts = 1;// 2.1 根据规格id,查询规格的具体信息,主要获取价格ItemsSpec itemSpec = itemService.queryItemSpecById(itemSpecId);totalAmount += itemSpec.getPriceNormal() * buyCounts;realPayAmount += itemSpec.getPriceDiscount() * buyCounts;// 2.2 根据商品id,获得商品信息以及商品图片String itemId = itemSpec.getItemId();Items item = itemService.queryItemById(itemId);String imgUrl = itemService.queryItemMainImgById(itemId);// 2.3 循环保存子订单数据到数据库String subOrderId = sid.nextShort();OrderItems subOrderItem = new OrderItems();subOrderItem.setId(subOrderId);subOrderItem.setOrderId(orderId);subOrderItem.setItemId(itemId);subOrderItem.setItemName(item.getItemName());subOrderItem.setItemImg(imgUrl);subOrderItem.setBuyCounts(buyCounts);subOrderItem.setItemSpecId(itemSpecId);subOrderItem.setItemSpecName(itemSpec.getName());subOrderItem.setPrice(itemSpec.getPriceDiscount());orderItemsMapper.insert(subOrderItem);// 2.4 在用户提交订单以后,规格表中需要扣除库存itemService.decreaseItemSpecStock(itemSpecId, buyCounts);}newOrder.setTotalAmount(totalAmount);newOrder.setRealPayAmount(realPayAmount);ordersMapper.insert(newOrder);// 3. 保存订单状态表OrderStatus waitPayOrderStatus = new OrderStatus();waitPayOrderStatus.setOrderId(orderId);waitPayOrderStatus.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);waitPayOrderStatus.setCreatedTime(new Date());orderStatusMapper.insert(waitPayOrderStatus);// 4. 构建商户订单,用于传给支付中心MerchantOrdersVO merchantOrdersVO = new MerchantOrdersVO();merchantOrdersVO.setMerchantOrderId(orderId);merchantOrdersVO.setMerchantUserId(userId);merchantOrdersVO.setAmount(realPayAmount + postAmount);merchantOrdersVO.setPayMethod(payMethod);// 5. 构建自定义订单voOrderVO orderVO = new OrderVO();orderVO.setOrderId(orderId);orderVO.setMerchantOrdersVO(merchantOrdersVO);return orderVO;}
}
步骤3:创建订单使用的的操作方法
3.1接口ItemService中:
/*** 根据商品规格id获取规格对象的具体信息* @param specId* @return*/public ItemsSpec queryItemSpecById(String specId);/*** 根据商品id获得商品图片主图url* @param itemId* @return*/public String queryItemMainImgById(String itemId);/*** 减少库存* @param specId* @param buyCounts*/public void decreaseItemSpecStock(String specId, int buyCounts);
3.2接口ItemService实现类
@Transactional(propagation = Propagation.SUPPORTS)@Overridepublic ItemsSpec queryItemSpecById(String specId) {return itemsSpecMapper.selectByPrimaryKey(specId);}@Transactional(propagation = Propagation.SUPPORTS)@Overridepublic String queryItemMainImgById(String itemId) {ItemsImg itemsImg = new ItemsImg();itemsImg.setItemId(itemId);itemsImg.setIsMain(YesOrNo.YES.type);ItemsImg result = itemsImgMapper.selectOne(itemsImg);return result != null ? result.getUrl() : "";}@Transactional(propagation = Propagation.REQUIRED)@Overridepublic void decreaseItemSpecStock(String specId, int buyCounts) {int result = itemsMapperCustom.decreaseItemSpecStock(specId, buyCounts);if (result != 1) {throw new RuntimeException("订单创建失败,原因:库存不足!");}}
3.3 mapper接口中ItemsMapperCustom类:
public int decreaseItemSpecStock(@Param("specId") String specId, @Param("pendingCounts") int pendingCounts);<update id="decreaseItemSpecStock">updateitems_specsetstock = stock - #{pendingCounts}whereid = #{specId}andstock >= #{pendingCounts}</update>
步骤4:创建对应的bo类和枚举
public enum PayMethod {WEIXIN(1, "微信"),ALIPAY(2, "支付宝");public final Integer type;public final String value;PayMethod(Integer type, String value){this.type = type;this.value = value;}
}
public enum OrderStatusEnum {WAIT_PAY(10, "待付款"),WAIT_DELIVER(20, "已付款,待发货"),WAIT_RECEIVE(30, "已发货,待收货"),SUCCESS(40, "交易成功"),CLOSE(50, "交易关闭");public final Integer type;public final String value;OrderStatusEnum(Integer type, String value){this.type = type;this.value = value;}
}
public class SubmitOrderBO {private String userId;private String itemSpecIds;private String addressId;private Integer payMethod;private String leftMsg;
}
步骤5:创建controller类
package com.one.controller.order;
import com.one.bo.SubmitOrderBO;
import com.one.controller.BaseController;
import com.one.enums.PayMethod;
import com.one.service.order.OrderService;
import com.one.utils.JSONResult;
import com.one.vo.OrderVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Api(value = "订单相关", tags = {"订单相关的api接口"})
@RequestMapping("orders")
@RestController
public class OrdersController extends BaseController {final static Logger logger = LoggerFactory.getLogger(OrdersController.class);@Autowiredprivate OrderService orderService;@ApiOperation(value = "用户下单", notes = "用户下单", httpMethod = "POST")@PostMapping("/create")public JSONResult create(@RequestBody SubmitOrderBO submitOrderBO, HttpServletRequest request, HttpServletResponse response) {if (submitOrderBO.getPayMethod() != PayMethod.WEIXIN.type && submitOrderBO.getPayMethod() != PayMethod.ALIPAY.type ) {return JSONResult.errorMsg("支付方式不支持!");}// 1. 创建订单OrderVO orderVO = orderService.createOrder(submitOrderBO);String orderId = orderVO.getOrderId();// 2. 创建订单以后,移除购物车中已结算(已提交)的商品// 3. 向支付中心发送当前订单,用于保存支付中心的订单数据return JSONResult.ok(orderId);}
}
相关文章:
3.02 创建订单操作详细-订单创建与回滚 (创建订单操作详细)
步骤1: 创建orders订单表,子订单表和订单状态表对应的pojo和mappperOrders和OrderItemsMapperOrderItems和OrderItemsMapperOrderStatus和OrderStatusMapper步骤2:创建OrderService和对应的实现类 public interface OrderService {/*** 用于创建订单相关…...
需求放缓、价格战升级、利润率持续恶化对小鹏汽车造成了严重影响
来源:猛兽财经 作者:猛兽财经 收入和每股收益不及预期,亏损创记录 财报显示,小鹏汽车(XPEV)2023年第二季度收入为50.6亿元人民币(合7亿美元),略低于预期,而且还产生了比预期更大的亏…...
《算法通关之路》chapter19解题技巧和面试技巧
《算法通关之路》学习笔记,记录一下自己的刷题过程,详细的内容请大家购买作者的书籍查阅。 1 看限制条件 1.1数据规模 有的题目数据规模较小,那么暴力法就可行;如果暴力法不行,那么再稍微加一个诸如缓存和剪枝的优化…...
什么是TF-A项目的长期支持?
安全之安全(security)博客目录导读 问题:Trusted Firmware-A社区每六个月发布一次代码。然而,对于生产中的平台,该策略在维护、重要软件修复的向后兼容性、获得最新的安全缓解措施和整体产品生命周期管理方面不具备可扩展性。 开源软件项目&…...
【LinuxC】时间、时区,相关命令、函数
文章目录 一、序1.1 时间和时区1.11 时间1.12 时区 1.2 查看时间时区的命令1.21 Windows1.22 Linux 二、C语言函数2.1 通用2.11 函数简介2.12 数据类型简介 2.2 windows 和 Linux特有函数2.3 C语言示例 一、序 1.1 时间和时区 1.11 时间 时间是一种用来描述物体运动变化的量…...
mac清理垃圾的软件有哪些?这三款我最推荐
没错,Mac电脑真的好用,但是清理系统垃圾可不是件容易的事。由于Mac系统的封闭性,系统的缓存垃圾常常隐藏得让人发现不了。不过,别担心!有一些专业的Mac清理软件可以帮你解决这一系列问题,让清理垃圾变得轻松…...
复习Day11:链表part04: 206. 反转链表、92. 反转链表II、25. K 个一组翻转链表、148. 排序链表
我用的方法是在leetcode再过一遍例题,明显会的就复制粘贴,之前没写出来就重写,然后从拓展题目中找题目来写。辅以Labuladong的文章看。然后刷题不用CLion了,使用leetcode自带的IDE模拟面试环境。 哈希表章节的题目思路很清晰&…...
一年一度的国庆节又结束了
这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…...
雷达干扰和烧穿范围简介
一、干扰信号比 J/S或J-to-S是从目标发射的干扰信号接收的功率(J)与从目标的雷达反向散射接收的功率的比率。 二、烧穿范围 通过电子攻击(J)可以首先检测到目标回波信号(S)的雷达到目标的距离。 三、自保护干扰 也称为主瓣干扰(雷达回波源和干扰机并置)。 烧穿范围…...
“秋天第一只大闸蟹”背后,看见京东一体化供应链
京东似乎正在从一个大闸蟹的物流服务商、销售商,转变为一个大闸蟹的“供货商”。 作者|斗斗 编辑|皮爷 出品|产业家 阳澄湖连续几天的降雨,使得通往蟹塘的路异常难走。 长期驻扎此地的京东相关负责人蹲在蟹塘边的小路上,指着蟹塘说道…...
大模型Java编码能力评估
大模型如火如荼发展,不能只看热闹,也需要躬身入局。要想评估大模型的能力,必须有一个评估方法和评估数据集。下面就梳理下当前大模型是如何评估代码能力的 权威评估 opencompass: https://opencompass.org.cn/datalearner: https://www.dat…...
javascript选择框和选择文本的创建与增加以及设置选中项
<script type"text/javascript">//得到选中项的索引,文本和值函数function getselected(selectedIndex){var selectboxdocument.forms[0].elements["location"];var indexselectbox[selectedIndex];var selectedOptionselectbox.options[…...
汽车驾驶任务的隐马尔可夫模型识别方法研究
汽车驾驶任务的隐马尔可夫模型识别方法研究 一、Introduction 自动驾驶汽车经过了几十年的发展,是目前国内外汽车行业中的重要研究方向。自 动驾驶汽车的智能化需要车辆能够有类“人”的行为,在决策策略上可以满足人的心理 需求。人在驾驶过程中&#…...
Java编程题(完数)
题目 一个正整数的因子是所有可以整除它的正整数。而一个数如果恰好等于除它本身外的因子之和,这个数就称为完数。例如61+2+3(6的因子是1,2,3)。 现在,你要写一个程序,读入两个正整数n和m(1<n<m<…...
国庆day6
国庆day6 汇编语言的组成 伪操作 不参与程序的执行,但是用于告诉编译器程序该怎么编译 如: .text .global .end .if .else .endif .data汇编指令 汇编器将一条汇编指令编译成一条机器码,在内存里一…...
力扣 -- 873. 最长的斐波那契子序列的长度
解题步骤: 参考代码: class Solution { public:int lenLongestFibSubseq(vector<int>& nums) {int nnums.size();unordered_map<int,int> hash;for(int i0;i<n;i){hash[nums[i]]i;}int ret2;vector<vector<int>> dp(n,v…...
【程序员必看】计算机网络,快速了解网络层次、常用协议和物理设备!
文章目录 0 引言1 基础知识的定义1.1 计算机网络层次1.2 网络供应商 ISP1.3 猫、路由器、交换机1.4 IP协议1.5 TCP、UDP协议1.6 HTTP、HTTPS、FTP协议1.7 Web、Web浏览器、Web服务器1.8 以太网和WLAN1.9 Socket (网络套接字) 2 总结 0 引言 在学习的过程…...
1.软件测试基础
一、软件测试概念 1.什么是软件 软件是计算机程序,是由计算机代码编写的一系列指令和数据,可以实现各种功能。它指的是计算机系统中的应用程序,包括操作系统、应用软件、驱动程序等。软件可以通过编程语言编写和开发,并可以安装…...
综合布线系统概述
对于现代化的大楼,其内部信息传输通道系统(综合布线系统) 已不仅仅要求能支持一般的语音传输,还应能够支持多种计算机网络 协议及多种厂商设备的信息互连,可适应各种灵活的,容错的组网方 案,…...
Labview 实战 99乘法表
基于新手小白,使用Labview实现99乘法表,敢于发表自己的一点方法,还请各位大侠放过! 如下: 运行效果如下: 思路为:将要显示出来的数据,全部转换为字符串形式,再塞入到数组…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
