千峰商城-springboot项目搭建-79-保存订单接口实现
一、流程分析(基础版本):

二、数据库实现
1.数据库操作:
- 根据收货地址ID,获取收货地址信息(tkMapper)
- 根据购物车ID,查询购物车详情(需要关联查询商品名称、sku名称、库存、商品图片、商品价格)——>获取生成商品快照的参数
- 保存订单(tkMapper)
- 修改库存(tkMapper)
- 保存商品快照(tkMapper)
(1)库存
改造shoopingCart:
ShoppingCartVO:
private int skuStock;//库存
<resultMap id="ShoppingCartVOMap2" type="com.qfedu.fmmall.entity.ShoppingCartVO"> <!-- WARNING - @mbg.generated --> <id column="cart_id" jdbcType="INTEGER" property="cartId" /> <result column="product_id" jdbcType="VARCHAR" property="productId" /> <result column="sku_id" jdbcType="VARCHAR" property="skuId" /> <result column="user_id" jdbcType="VARCHAR" property="userId" /> <result column="cart_num" jdbcType="VARCHAR" property="cartNum" /> <result column="cart_time" jdbcType="VARCHAR" property="cartTime" /> <result column="product_price" jdbcType="DECIMAL" property="productPrice" /> <result column="sku_props" jdbcType="VARCHAR" property="skuProps" /> <result column="product_name" jdbcType="VARCHAR" property="productName" /> <result column="url" jdbcType="VARCHAR" property="productImg" /> <result column="original_price" jdbcType="VARCHAR" property="originalPrice" /> <result column="sell_price" jdbcType="VARCHAR" property="sellPrice" /> <result column="sku_name" jdbcType="VARCHAR" property="skuName" /> <result column="stock" property="skuStock" /> </resultMap> <select id="selectShopcartByCids" resultMap="ShoppingCartVOMap2"> SELECT c.cart_id, c.product_id, c.sku_id, c.user_id, c.cart_num, c.cart_time, c.product_price, c.sku_props, p.product_name, i.url, s.original_price, s.sell_price, s.sku_name, s.stock FROM shopping_cart c INNER JOIN product p INNER JOIN product_img i INNER JOIN product_sku s ON c.product_id=p.product_id AND i.item_id=p.product_id AND c.sku_id=s.sku_id WHERE i.is_main=1 and c.cart_id IN <foreach collection="cids" item="cid" separator="," open="(" close=")"> #{cid} </foreach> </select>
OrderService:
public interface OrderService { public ResultVO addOrder(); }
OrderServiceImpl:
@Service public class OrderServiceImpl implements OrderService { @Autowired private ShoppingCartMapper shoppingCartMapper; @Autowired private OrdersMapper ordersMapper; @Autowired private OrderItemMapper orderItemMapper; public ResultVO addOrder(String cids,Orders order) { //1.根据cids查询当前订单中关联的购物车记录详情(包括库存) String[] arr = cids.split(","); List<Integer> cidsList = new ArrayList<>(); for (int i=0; i<arr.length;i++){ cidsList.add(Integer.parseInt(arr[i])); } List<ShoppingCartVO> list = shoppingCartMapper.selectShopcartByCids(cidsList); //2.校验库存 boolean f = true; String untitled = ""; for (ShoppingCartVO sc:list){ if (Integer.parseInt( sc.getCartNum() )>sc.getSkuStock()){ f=false; //break; } //获取所有商品的名称,以“,”分割拼接成字符串 untitled = untitled + sc.getProductName() + ","; } if (f){ //3.表示用户充足----------保存订单 order.setUntitled(untitled); order.setCreateTime(new Date()); //生成订单编号 String orderId = UUID.randomUUID().toString().replace("-", ""); order.setOrderId(orderId); //4.保存订单 int i = ordersMapper.insert(order); if (i>0){ //生成商品快照 List<OrderItem> orderItems = new ArrayList<>(); for (ShoppingCartVO sc:list){ String itemId = System.currentTimeMillis()+""+ (new Random().nextInt(89999)+10000 ); OrderItem orderItem = new OrderItem(itemId, orderId, sc.getProductId(), sc.getProductName(), sc.getProductImg(), sc.getSkuId(), sc.getSkuName(),new BigDecimal(sc.getSellPrice()) , Integer.parseInt(sc.getCartNum()), new BigDecimal(sc.getSellPrice() * Integer.parseInt(sc.getCartNum())) , new Date(), new Date(), 0); orderItems.add(orderItem); } int j = orderItemMapper.insertList(orderItems); //扣减库存 } }else { //表示库存不足 return new ResultVO(ResStatus.NO,"库存不足,下单失败!",null); } return null; } }
(2)保存订单
OrderServiceImpl:
@Service public class OrderServiceImpl implements OrderService { @Autowired private ShoppingCartMapper shoppingCartMapper; @Autowired private OrdersMapper ordersMapper; @Autowired private OrderItemMapper orderItemMapper; @Autowired private ProductSkuMapper productSkuMapper; public ResultVO addOrder(String cids,Orders order) { //1.根据cids查询当前订单中关联的购物车记录详情(包括库存) String[] arr = cids.split(","); List<Integer> cidsList = new ArrayList<>(); for (int i=0; i<arr.length;i++){ cidsList.add(Integer.parseInt(arr[i])); } List<ShoppingCartVO> list = shoppingCartMapper.selectShopcartByCids(cidsList); //2.校验库存 boolean f = true; String untitled = ""; for (ShoppingCartVO sc:list){ if (Integer.parseInt( sc.getCartNum() )>sc.getSkuStock()){ f=false; //break; } //获取所有商品的名称,以“,”分割拼接成字符串 untitled = untitled + sc.getProductName() + ","; } if (f){ //3.表示用户充足----------保存订单 order.setUntitled(untitled); order.setCreateTime(new Date()); order.setStatus("1"); //生成订单编号 String orderId = UUID.randomUUID().toString().replace("-", ""); order.setOrderId(orderId); //4.保存订单 int i = ordersMapper.insert(order); //if (i>0){ //生成商品快照 //List<OrderItem> orderItems = new ArrayList<>(); for (ShoppingCartVO sc:list){ int cnum = Integer.parseInt(sc.getCartNum()); String itemId = System.currentTimeMillis()+""+ (new Random().nextInt(89999)+10000 ); OrderItem orderItem = new OrderItem(itemId, orderId, sc.getProductId(), sc.getProductName(), sc.getProductImg(), sc.getSkuId(), sc.getSkuName(),new BigDecimal(sc.getSellPrice()) , cnum, new BigDecimal(sc.getSellPrice() * cnum) , new Date(), new Date(), 0); //orderItems.add(orderItem); int m = orderItemMapper.insert(orderItem); } //int j = orderItemMapper.insertList(orderItems); //5.扣减库存 for (ShoppingCartVO sc:list){ String skuId = sc.getSkuId(); int newStock = sc.getSkuStock() - Integer.parseInt(sc.getCartNum()); // Example example = new Example(ProductSku.class); // Example.Criteria criteria = example.createCriteria(); // criteria.andEqualTo("skuId",skuId); // ProductSku productSku = productSkuMapper.selectByPrimaryKey(skuId); // //ProductSku productSku = new ProductSku(); // productSku.setStock(newStock); // int k = productSkuMapper.updateByPrimaryKey(productSku); ProductSku productSku = new ProductSku(); productSku.setSkuId(skuId); productSku.setStock(newStock); int k = productSkuMapper.updateByPrimaryKeySelective(productSku); } return new ResultVO(ResStatus.OK,"下单成功!",orderId); }else { //表示库存不足 return new ResultVO(ResStatus.NO,"库存不足,下单失败!",null); } } }
OrderController:
@RestController @CrossOrigin @RequestMapping("/order") @Api(value = "提供订单相关的操作接口",tags = "订单管理") public class OrderController { @Autowired private OrderService orderService; @PostMapping("/add") public ResultVO add(String cids,@RequestBody Orders order){ ResultVO resultVO = orderService.addOrder(cids, order); return resultVO; } }

(3)事务管理
OrderServiceImpl:
//保存订单业务 @Transactional //事务 public ResultVO addOrder(String cids,Orders order) { ... }
(4)删除购物车记录
OrderServiceImpl:
//6.删除购物车:当购物车中的记录购买成功后,购物车对应做删除操作 for (int cid:cidsList){ shoppingCartMapper.deleteByPrimaryKey(cid); }
OrderServiceImpl抛出sq异常:
@Service public class OrderServiceImpl implements OrderService { @Autowired private ShoppingCartMapper shoppingCartMapper; @Autowired private OrdersMapper ordersMapper; @Autowired private OrderItemMapper orderItemMapper; @Autowired private ProductSkuMapper productSkuMapper; //保存订单业务 @Transactional//事务 public ResultVO addOrder(String cids,Orders order) throws SQLException{ //1.根据cids查询当前订单中关联的购物车记录详情(包括库存) String[] arr = cids.split(","); List<Integer> cidsList = new ArrayList<>(); for (int i=0; i<arr.length;i++){ cidsList.add(Integer.parseInt(arr[i])); } List<ShoppingCartVO> list = shoppingCartMapper.selectShopcartByCids(cidsList); //2.校验库存 boolean f = true; String untitled = ""; for (ShoppingCartVO sc:list){ if (Integer.parseInt( sc.getCartNum() )>sc.getSkuStock()){ f=false; //break; } //获取所有商品的名称,以“,”分割拼接成字符串 untitled = untitled + sc.getProductName() + ","; } if (f){ //3.表示用户充足----------保存订单 order.setUntitled(untitled); order.setCreateTime(new Date()); order.setStatus("1"); //生成订单编号 String orderId = UUID.randomUUID().toString().replace("-", ""); order.setOrderId(orderId); //4.保存订单 ordersMapper.insert(order); //if (i>0){ //生成商品快照 //List<OrderItem> orderItems = new ArrayList<>(); for (ShoppingCartVO sc:list){ int cnum = Integer.parseInt(sc.getCartNum()); String itemId = System.currentTimeMillis()+""+ (new Random().nextInt(89999)+10000 ); OrderItem orderItem = new OrderItem(itemId, orderId, sc.getProductId(), sc.getProductName(), sc.getProductImg(), sc.getSkuId(), sc.getSkuName(),new BigDecimal(sc.getSellPrice()) , cnum, new BigDecimal(sc.getSellPrice() * cnum) , new Date(), new Date(), 0); //orderItems.add(orderItem); orderItemMapper.insert(orderItem); } //int j = orderItemMapper.insertList(orderItems); //5.扣减库存 for (ShoppingCartVO sc:list){ String skuId = sc.getSkuId(); int newStock = sc.getSkuStock() - Integer.parseInt(sc.getCartNum()); // Example example = new Example(ProductSku.class); // Example.Criteria criteria = example.createCriteria(); // criteria.andEqualTo("skuId",skuId); // ProductSku productSku = productSkuMapper.selectByPrimaryKey(skuId); // //ProductSku productSku = new ProductSku(); // productSku.setStock(newStock); // int k = productSkuMapper.updateByPrimaryKey(productSku); ProductSku productSku = new ProductSku(); productSku.setSkuId(skuId); productSku.setStock(newStock); productSkuMapper.updateByPrimaryKeySelective(productSku); } //6.删除购物车:当购物车中的记录购买成功后,购物车对应做删除操作 for (int cid:cidsList){ shoppingCartMapper.deleteByPrimaryKey(cid); } return new ResultVO(ResStatus.OK,"下单成功!",orderId); }else { //表示库存不足 return new ResultVO(ResStatus.NO,"库存不足,下单失败!",null); } } }
OrderController:
@RestController @CrossOrigin @RequestMapping("/order") @Api(value = "提供订单相关的操作接口",tags = "订单管理") public class OrderController { @Autowired private OrderService orderService; @PostMapping("/add") public ResultVO add(String cids,@RequestBody Orders order) { ResultVO resultVO = null; try { resultVO = orderService.addOrder(cids, order); }catch (SQLException e){ resultVO = new ResultVO(ResStatus.NO,"提交订单失败",null); } return resultVO; } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性