【电商项目】---订单模块

电玩女神 2022-12-26 10:11 375阅读 0赞

前言

订单模块开发:创建订单,取消订单


复杂订单状态设计

在这里插入图片描述
在这里插入图片描述

聚合支付中心

在这里插入图片描述

  • 提交订单-支付方式

    @ApiOperation(value = “用户下单”, notes = “用户下单”, httpMethod = “POST”)

    1. @PostMapping("/create")
    2. public ZCWJSONResult create(
    3. @RequestBody SubmitOrderBO submitOrderBO,
    4. HttpServletRequest request,
    5. HttpServletResponse response) {
    6. if (submitOrderBO.getPayMethod() != PayMethod.WEIXIN.type
    7. && submitOrderBO.getPayMethod() != PayMethod.ALIPAY.type ) {
    8. return ZCWJSONResult.errorMsg("支付方式不支持!");
    9. }

    // System.out.println(submitOrderBO.toString());

    1. // 1. 创建订单
    2. OrderVO orderVO = orderService.createOrder(submitOrderBO);
    3. String orderId = orderVO.getOrderId();
    4. // 2. 创建订单以后,移除购物车中已结算(已提交)的商品
    5. /** * 1001 * 2002 -> 用户购买 * 3003 -> 用户购买 * 4004 */
    6. // TODO 整合redis之后,完善购物车中的已结算商品清除,并且同步到前端的cookie

    // CookieUtils.setCookie(request, response, FOODIE_SHOPCART, “”, true);

    1. // 3. 向支付中心发送当前订单,用于保存支付中心的订单数据
    2. MerchantOrdersVO merchantOrdersVO = orderVO.getMerchantOrdersVO();
    3. merchantOrdersVO.setReturnUrl(payReturnUrl);
    4. // 为了方便测试购买,所以所有的支付金额都统一改为1分钱
    5. merchantOrdersVO.setAmount(1);
    6. HttpHeaders headers = new HttpHeaders();
    7. headers.setContentType(MediaType.APPLICATION_JSON);
    8. headers.add("imoocUserId","imooc");
    9. headers.add("password","imooc");
    10. HttpEntity<MerchantOrdersVO> entity =
    11. new HttpEntity<>(merchantOrdersVO, headers);
    12. ResponseEntity<ZCWJSONResult> responseEntity =
    13. restTemplate.postForEntity(paymentUrl,
    14. entity,
    15. ZCWJSONResult.class);
    16. ZCWJSONResult paymentResult = responseEntity.getBody();
    17. if (paymentResult.getStatus() != 200) {
    18. logger.error("发送错误:{}", paymentResult.getMsg());
    19. return ZCWJSONResult.errorMsg("支付中心订单创建失败,请联系管理员!");
    20. }
    21. return ZCWJSONResult.ok(orderId);
    22. }

    /* 用于创建订单的BO对象 */
    public class SubmitOrderBO {

    1. private String userId;
    2. private String itemSpecIds;
    3. private String addressId;
    4. private Integer payMethod;
    5. private String leftMsg;
    6. public String getUserId() {
    7. return userId;
    8. }
    9. public void setUserId(String userId) {
    10. this.userId = userId;
    11. }
    12. public String getItemSpecIds() {
    13. return itemSpecIds;
    14. }
    15. public void setItemSpecIds(String itemSpecIds) {
    16. this.itemSpecIds = itemSpecIds;
    17. }
    18. public String getAddressId() {
    19. return addressId;
    20. }
    21. public void setAddressId(String addressId) {
    22. this.addressId = addressId;
    23. }
    24. public Integer getPayMethod() {
    25. return payMethod;
    26. }
    27. public void setPayMethod(Integer payMethod) {
    28. this.payMethod = payMethod;
    29. }
    30. public String getLeftMsg() {
    31. return leftMsg;
    32. }
    33. public void setLeftMsg(String leftMsg) {
    34. this.leftMsg = leftMsg;
    35. }
    36. @Override
    37. public String toString() {
    38. return "SubmitOrderBO{" +
    39. "userId='" + userId + '\'' +
    40. ", itemSpecIds='" + itemSpecIds + '\'' +
    41. ", addressId='" + addressId + '\'' +
    42. ", payMethod=" + payMethod +
    43. ", leftMsg='" + leftMsg + '\'' +
    44. '}';
    45. }

    }

    import com.fasterxml.jackson.annotation.JsonIgnore;
    import com.fasterxml.jackson.databind.ObjectMapper;

    /* @Title: ZCWJSONResult.java @Package com.zcw.utils @Description: 自定义响应数据结构 本类可提供给 H5/ios/安卓/公众号/小程序 使用 前端接受此类数据(json object)后,可自行根据业务去实现相关功能 200:表示成功 500:表示错误,错误信息在msg字段中 501:bean验证错误,不管多少个错误都以map形式返回 502:拦截器拦截到用户token出错 555:异常抛出信息 556: 用户qq校验异常 @Copyright: Copyright (c) 2020 @Company: www.zcw.com @author Zhaocunwei @version V1.0 */
    public class ZCWJSONResult {

    1. // 定义jackson对象
    2. private static final ObjectMapper MAPPER = new ObjectMapper();
    3. // 响应业务状态
    4. private Integer status;
    5. // 响应消息
    6. private String msg;
    7. // 响应中的数据
    8. private Object data;
    9. @JsonIgnore
    10. private String ok; // 不使用
    11. public static ZCWJSONResult build(Integer status, String msg, Object data) {
    12. return new ZCWJSONResult(status, msg, data);
    13. }
    14. public static ZCWJSONResult build(Integer status, String msg, Object data, String ok) {
    15. return new ZCWJSONResult(status, msg, data, ok);
    16. }
    17. public static ZCWJSONResult ok(Object data) {
    18. return new ZCWJSONResult(data);
    19. }
    20. public static ZCWJSONResult ok() {
    21. return new ZCWJSONResult(null);
    22. }
    23. public static ZCWJSONResult errorMsg(String msg) {
    24. return new ZCWJSONResult(500, msg, null);
    25. }
    26. public static ZCWJSONResult errorMap(Object data) {
    27. return new ZCWJSONResult(501, "error", data);
    28. }
    29. public static ZCWJSONResult errorTokenMsg(String msg) {
    30. return new ZCWJSONResult(502, msg, null);
    31. }
    32. public static ZCWJSONResult errorException(String msg) {
    33. return new ZCWJSONResult(555, msg, null);
    34. }
    35. public static ZCWJSONResult errorUserQQ(String msg) {
    36. return new ZCWJSONResult(556, msg, null);
    37. }
    38. public ZCWJSONResult() {
    39. }
    40. public ZCWJSONResult(Integer status, String msg, Object data) {
    41. this.status = status;
    42. this.msg = msg;
    43. this.data = data;
    44. }
    45. public ZCWJSONResult(Integer status, String msg, Object data, String ok) {
    46. this.status = status;
    47. this.msg = msg;
    48. this.data = data;
    49. this.ok = ok;
    50. }
    51. public ZCWJSONResult(Object data) {
    52. this.status = 200;
    53. this.msg = "OK";
    54. this.data = data;
    55. }
    56. public Boolean isOK() {
    57. return this.status == 200;
    58. }
    59. public Integer getStatus() {
    60. return status;
    61. }
    62. public void setStatus(Integer status) {
    63. this.status = status;
    64. }
    65. public String getMsg() {
    66. return msg;
    67. }
    68. public void setMsg(String msg) {
    69. this.msg = msg;
    70. }
    71. public Object getData() {
    72. return data;
    73. }
    74. public void setData(Object data) {
    75. this.data = data;
    76. }
    77. public String getOk() {
    78. return ok;
    79. }
    80. public void setOk(String ok) {
    81. this.ok = ok;
    82. }

    }

    /* @Description: 支付方式 枚举 */
    public enum PayMethod {

    1. WEIXIN(1, "微信"),
    2. ALIPAY(2, "支付宝");
    3. public final Integer type;
    4. public final String value;
    5. PayMethod(Integer type, String value){
    6. this.type = type;
    7. this.value = value;
    8. }

    }

创建订单-填充新订单数据

  1. public interface OrderService {
  2. /** * 用于创建订单相关信息 * @param submitOrderBO */
  3. public OrderVO createOrder(SubmitOrderBO submitOrderBO);
  4. /** * 修改订单状态 * @param orderId * @param orderStatus */
  5. public void updateOrderStatus(String orderId, Integer orderStatus);
  6. /** * 查询订单状态 * @param orderId * @return */
  7. public OrderStatus queryOrderStatusInfo(String orderId);
  8. /** * 关闭超时未支付订单 */
  9. public void closeOrder();
  10. }
  • impl

    @Service
    public class OrderServiceImpl implements OrderService {

    1. @Autowired
    2. private OrdersMapper ordersMapper;
    3. @Autowired
    4. private OrderItemsMapper orderItemsMapper;
    5. @Autowired
    6. private OrderStatusMapper orderStatusMapper;
    7. @Autowired
    8. private AddressService addressService;
    9. @Autowired
    10. private ItemService itemService;
    11. @Autowired
    12. private Sid sid;
    13. @Transactional(propagation = Propagation.REQUIRED)
    14. @Override
    15. public OrderVO createOrder(SubmitOrderBO submitOrderBO) {
    16. String userId = submitOrderBO.getUserId();
    17. String addressId = submitOrderBO.getAddressId();
    18. String itemSpecIds = submitOrderBO.getItemSpecIds();
    19. Integer payMethod = submitOrderBO.getPayMethod();
    20. String leftMsg = submitOrderBO.getLeftMsg();
    21. // 包邮费用设置为0
    22. Integer postAmount = 0;
    23. String orderId = sid.nextShort();
    24. UserAddress address = addressService.queryUserAddres(userId, addressId);
    25. // 1. 新订单数据保存
    26. Orders newOrder = new Orders();
    27. newOrder.setId(orderId);
    28. newOrder.setUserId(userId);
    29. newOrder.setReceiverName(address.getReceiver());
    30. newOrder.setReceiverMobile(address.getMobile());
    31. newOrder.setReceiverAddress(address.getProvince() + " "
    32. + address.getCity() + " "
    33. + address.getDistrict() + " "
    34. + address.getDetail());

    // newOrder.setTotalAmount();
    // newOrder.setRealPayAmount();

    1. newOrder.setPostAmount(postAmount);
    2. newOrder.setPayMethod(payMethod);
    3. newOrder.setLeftMsg(leftMsg);
    4. newOrder.setIsComment(YesOrNo.NO.type);
    5. newOrder.setIsDelete(YesOrNo.NO.type);
    6. newOrder.setCreatedTime(new Date());
    7. newOrder.setUpdatedTime(new Date());
  1. // 2. 循环根据itemSpecIds保存订单商品信息表
  2. String itemSpecIdArr[] = itemSpecIds.split(",");
  3. Integer totalAmount = 0; // 商品原价累计
  4. Integer realPayAmount = 0; // 优惠后的实际支付价格累计
  5. for (String itemSpecId : itemSpecIdArr) {
  6. // TODO 整合redis后,商品购买的数量重新从redis的购物车中获取
  7. int buyCounts = 1;
  8. // 2.1 根据规格id,查询规格的具体信息,主要获取价格
  9. ItemsSpec itemSpec = itemService.queryItemSpecById(itemSpecId);
  10. totalAmount += itemSpec.getPriceNormal() * buyCounts;
  11. realPayAmount += itemSpec.getPriceDiscount() * buyCounts;
  12. // 2.2 根据商品id,获得商品信息以及商品图片
  13. String itemId = itemSpec.getItemId();
  14. Items item = itemService.queryItemById(itemId);
  15. String imgUrl = itemService.queryItemMainImgById(itemId);
  16. // 2.3 循环保存子订单数据到数据库
  17. String subOrderId = sid.nextShort();
  18. OrderItems subOrderItem = new OrderItems();
  19. subOrderItem.setId(subOrderId);
  20. subOrderItem.setOrderId(orderId);
  21. subOrderItem.setItemId(itemId);
  22. subOrderItem.setItemName(item.getItemName());
  23. subOrderItem.setItemImg(imgUrl);
  24. subOrderItem.setBuyCounts(buyCounts);
  25. subOrderItem.setItemSpecId(itemSpecId);
  26. subOrderItem.setItemSpecName(itemSpec.getName());
  27. subOrderItem.setPrice(itemSpec.getPriceDiscount());
  28. orderItemsMapper.insert(subOrderItem);
  29. // 2.4 在用户提交订单以后,规格表中需要扣除库存
  30. itemService.decreaseItemSpecStock(itemSpecId, buyCounts);
  31. }
  32. newOrder.setTotalAmount(totalAmount);
  33. newOrder.setRealPayAmount(realPayAmount);
  34. ordersMapper.insert(newOrder);
  35. // 3. 保存订单状态表
  36. OrderStatus waitPayOrderStatus = new OrderStatus();
  37. waitPayOrderStatus.setOrderId(orderId);
  38. waitPayOrderStatus.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);
  39. waitPayOrderStatus.setCreatedTime(new Date());
  40. orderStatusMapper.insert(waitPayOrderStatus);
  41. // 4. 构建商户订单,用于传给支付中心
  42. MerchantOrdersVO merchantOrdersVO = new MerchantOrdersVO();
  43. merchantOrdersVO.setMerchantOrderId(orderId);
  44. merchantOrdersVO.setMerchantUserId(userId);
  45. merchantOrdersVO.setAmount(realPayAmount + postAmount);
  46. merchantOrdersVO.setPayMethod(payMethod);
  47. // 5. 构建自定义订单vo
  48. OrderVO orderVO = new OrderVO();
  49. orderVO.setOrderId(orderId);
  50. orderVO.setMerchantOrdersVO(merchantOrdersVO);
  51. return orderVO;
  52. }
  53. @Transactional(propagation = Propagation.REQUIRED)
  54. @Override
  55. public void updateOrderStatus(String orderId, Integer orderStatus) {
  56. OrderStatus paidStatus = new OrderStatus();
  57. paidStatus.setOrderId(orderId);
  58. paidStatus.setOrderStatus(orderStatus);
  59. paidStatus.setPayTime(new Date());
  60. orderStatusMapper.updateByPrimaryKeySelective(paidStatus);
  61. }
  62. @Transactional(propagation = Propagation.SUPPORTS)
  63. @Override
  64. public OrderStatus queryOrderStatusInfo(String orderId) {
  65. return orderStatusMapper.selectByPrimaryKey(orderId);
  66. }
  67. @Transactional(propagation = Propagation.REQUIRED)
  68. @Override
  69. public void closeOrder() {
  70. // 查询所有未付款订单,判断时间是否超时(1天),超时则关闭交易
  71. OrderStatus queryOrder = new OrderStatus();
  72. queryOrder.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);
  73. List<OrderStatus> list = orderStatusMapper.select(queryOrder);
  74. for (OrderStatus os : list) {
  75. // 获得订单创建时间
  76. Date createdTime = os.getCreatedTime();
  77. // 和当前时间进行对比
  78. int days = DateUtil.daysBetween(createdTime, new Date());
  79. if (days >= 1) {
  80. // 超过1天,关闭订单
  81. doCloseOrder(os.getOrderId());
  82. }
  83. }
  84. }
  85. @Transactional(propagation = Propagation.REQUIRED)
  86. void doCloseOrder(String orderId) {
  87. OrderStatus close = new OrderStatus();
  88. close.setOrderId(orderId);
  89. close.setOrderStatus(OrderStatusEnum.CLOSE.type);
  90. close.setCloseTime(new Date());
  91. orderStatusMapper.updateByPrimaryKeySelective(close);
  92. }
  93. }
  94. /** * @Desc: 是否 枚举 */
  95. public enum YesOrNo {
  96. NO(0, "否"),
  97. YES(1, "是");
  98. public final Integer type;
  99. public final String value;
  100. YesOrNo(Integer type, String value) {
  101. this.type = type;
  102. this.value = value;
  103. }
  104. }
  105. /** * @Description: 订单状态 枚举 */
  106. public enum OrderStatusEnum {
  107. WAIT_PAY(10, "待付款"),
  108. WAIT_DELIVER(20, "已付款,待发货"),
  109. WAIT_RECEIVE(30, "已发货,待收货"),
  110. SUCCESS(40, "交易成功"),
  111. CLOSE(50, "交易关闭");
  112. public final Integer type;
  113. public final String value;
  114. OrderStatusEnum(Integer type, String value){
  115. this.type = type;
  116. this.value = value;
  117. }
  118. }

商品信息

  1. public interface ItemService {
  2. /** * 根据商品ID查询详情 * @param itemId * @return */
  3. public Items queryItemById(String itemId);
  4. /** * 根据商品id查询商品图片列表 * @param itemId * @return */
  5. public List<ItemsImg> queryItemImgList(String itemId);
  6. /** * 根据商品id查询商品规格 * @param itemId * @return */
  7. public List<ItemsSpec> queryItemSpecList(String itemId);
  8. /** * 根据商品id查询商品参数 * @param itemId * @return */
  9. public ItemsParam queryItemParam(String itemId);
  10. /** * 根据商品id查询商品的评价等级数量 * @param itemId */
  11. public CommentLevelCountsVO queryCommentCounts(String itemId);
  12. /** * 根据商品id查询商品的评价(分页) * @param itemId * @param level * @return */
  13. public PagedGridResult queryPagedComments(String itemId, Integer level,
  14. Integer page, Integer pageSize);
  15. /** * 搜索商品列表 * @param keywords * @param sort * @param page * @param pageSize * @return */
  16. public PagedGridResult searhItems(String keywords, String sort,
  17. Integer page, Integer pageSize);
  18. /** * 根据分类id搜索商品列表 * @param catId * @param sort * @param page * @param pageSize * @return */
  19. public PagedGridResult searhItems(Integer catId, String sort,
  20. Integer page, Integer pageSize);
  21. /** * 根据规格ids查询最新的购物车中商品数据(用于刷新渲染购物车中的商品数据) * @param specIds * @return */
  22. public List<ShopcartVO> queryItemsBySpecIds(String specIds);
  23. /** * 根据商品规格id获取规格对象的具体信息 * @param specId * @return */
  24. public ItemsSpec queryItemSpecById(String specId);
  25. /** * 根据商品id获得商品图片主图url * @param itemId * @return */
  26. public String queryItemMainImgById(String itemId);
  27. /** * 减少库存 * @param specId * @param buyCounts */
  28. public void decreaseItemSpecStock(String specId, int buyCounts);
  29. @Service
  30. public class ItemServiceImpl implements ItemService {
  31. @Autowired
  32. private ItemsMapper itemsMapper;
  33. @Autowired
  34. private ItemsImgMapper itemsImgMapper;
  35. @Autowired
  36. private ItemsSpecMapper itemsSpecMapper;
  37. @Autowired
  38. private ItemsParamMapper itemsParamMapper;
  39. @Autowired
  40. private ItemsCommentsMapper itemsCommentsMapper;
  41. @Autowired
  42. private ItemsMapperCustom itemsMapperCustom;
  43. @Transactional(propagation = Propagation.SUPPORTS)
  44. @Override
  45. public Items queryItemById(String itemId) {
  46. return itemsMapper.selectByPrimaryKey(itemId);
  47. }
  48. @Transactional(propagation = Propagation.SUPPORTS)
  49. @Override
  50. public List<ItemsImg> queryItemImgList(String itemId) {
  51. Example itemsImgExp = new Example(ItemsImg.class);
  52. Example.Criteria criteria = itemsImgExp.createCriteria();
  53. criteria.andEqualTo("itemId", itemId);
  54. return itemsImgMapper.selectByExample(itemsImgExp);
  55. }
  56. @Transactional(propagation = Propagation.SUPPORTS)
  57. @Override
  58. public List<ItemsSpec> queryItemSpecList(String itemId) {
  59. Example itemsSpecExp = new Example(ItemsSpec.class);
  60. Example.Criteria criteria = itemsSpecExp.createCriteria();
  61. criteria.andEqualTo("itemId", itemId);
  62. return itemsSpecMapper.selectByExample(itemsSpecExp);
  63. }
  64. @Transactional(propagation = Propagation.SUPPORTS)
  65. @Override
  66. public ItemsParam queryItemParam(String itemId) {
  67. Example itemsParamExp = new Example(ItemsParam.class);
  68. Example.Criteria criteria = itemsParamExp.createCriteria();
  69. criteria.andEqualTo("itemId", itemId);
  70. return itemsParamMapper.selectOneByExample(itemsParamExp);
  71. }
  72. @Transactional(propagation = Propagation.SUPPORTS)
  73. @Override
  74. public CommentLevelCountsVO queryCommentCounts(String itemId) {
  75. Integer goodCounts = getCommentCounts(itemId, CommentLevel.GOOD.type);
  76. Integer normalCounts = getCommentCounts(itemId, CommentLevel.NORMAL.type);
  77. Integer badCounts = getCommentCounts(itemId, CommentLevel.BAD.type);
  78. Integer totalCounts = goodCounts + normalCounts + badCounts;
  79. CommentLevelCountsVO countsVO = new CommentLevelCountsVO();
  80. countsVO.setTotalCounts(totalCounts);
  81. countsVO.setGoodCounts(goodCounts);
  82. countsVO.setNormalCounts(normalCounts);
  83. countsVO.setBadCounts(badCounts);
  84. return countsVO;
  85. }
  86. @Transactional(propagation = Propagation.SUPPORTS)
  87. Integer getCommentCounts(String itemId, Integer level) {
  88. ItemsComments condition = new ItemsComments();
  89. condition.setItemId(itemId);
  90. if (level != null) {
  91. condition.setCommentLevel(level);
  92. }
  93. return itemsCommentsMapper.selectCount(condition);
  94. }
  95. @Transactional(propagation = Propagation.SUPPORTS)
  96. @Override
  97. public PagedGridResult queryPagedComments(String itemId,
  98. Integer level,
  99. Integer page,
  100. Integer pageSize) {
  101. Map<String, Object> map = new HashMap<>();
  102. map.put("itemId", itemId);
  103. map.put("level", level);
  104. // mybatis-pagehelper
  105. /** * page: 第几页 * pageSize: 每页显示条数 */
  106. PageHelper.startPage(page, pageSize);
  107. List<ItemCommentVO> list = itemsMapperCustom.queryItemComments(map);
  108. for (ItemCommentVO vo : list) {
  109. vo.setNickname(DesensitizationUtil.commonDisplay(vo.getNickname()));
  110. }
  111. return setterPagedGrid(list, page);
  112. }
  113. private PagedGridResult setterPagedGrid(List<?> list, Integer page) {
  114. PageInfo<?> pageList = new PageInfo<>(list);
  115. PagedGridResult grid = new PagedGridResult();
  116. grid.setPage(page);
  117. grid.setRows(list);
  118. grid.setTotal(pageList.getPages());
  119. grid.setRecords(pageList.getTotal());
  120. return grid;
  121. }
  122. @Transactional(propagation = Propagation.SUPPORTS)
  123. @Override
  124. public PagedGridResult searhItems(String keywords, String sort, Integer page, Integer pageSize) {
  125. Map<String, Object> map = new HashMap<>();
  126. map.put("keywords", keywords);
  127. map.put("sort", sort);
  128. PageHelper.startPage(page, pageSize);
  129. List<SearchItemsVO> list = itemsMapperCustom.searchItems(map);
  130. return setterPagedGrid(list, page);
  131. }
  132. @Transactional(propagation = Propagation.SUPPORTS)
  133. @Override
  134. public PagedGridResult searhItems(Integer catId, String sort, Integer page, Integer pageSize) {
  135. Map<String, Object> map = new HashMap<>();
  136. map.put("catId", catId);
  137. map.put("sort", sort);
  138. PageHelper.startPage(page, pageSize);
  139. List<SearchItemsVO> list = itemsMapperCustom.searchItemsByThirdCat(map);
  140. return setterPagedGrid(list, page);
  141. }
  142. @Transactional(propagation = Propagation.SUPPORTS)
  143. @Override
  144. public List<ShopcartVO> queryItemsBySpecIds(String specIds) {
  145. String ids[] = specIds.split(",");
  146. List<String> specIdsList = new ArrayList<>();
  147. Collections.addAll(specIdsList, ids);
  148. return itemsMapperCustom.queryItemsBySpecIds(specIdsList);
  149. }
  150. @Transactional(propagation = Propagation.SUPPORTS)
  151. @Override
  152. public ItemsSpec queryItemSpecById(String specId) {
  153. return itemsSpecMapper.selectByPrimaryKey(specId);
  154. }
  155. @Transactional(propagation = Propagation.SUPPORTS)
  156. @Override
  157. public String queryItemMainImgById(String itemId) {
  158. ItemsImg itemsImg = new ItemsImg();
  159. itemsImg.setItemId(itemId);
  160. itemsImg.setIsMain(YesOrNo.YES.type);
  161. ItemsImg result = itemsImgMapper.selectOne(itemsImg);
  162. return result != null ? result.getUrl() : "";
  163. }
  164. @Transactional(propagation = Propagation.REQUIRED)
  165. @Override
  166. public void decreaseItemSpecStock(String specId, int buyCounts) {
  167. // synchronized 不推荐使用,集群下无用,性能低下
  168. // 锁数据库: 不推荐,导致数据库性能低下
  169. // 分布式锁 zookeeper redis
  170. // lockUtil.getLock(); -- 加锁
  171. // 1. 查询库存
  172. // int stock = 10;
  173. // 2. 判断库存,是否能够减少到0以下
  174. // if (stock - buyCounts < 0) {
  175. // 提示用户库存不够
  176. // 10 - 3 -3 - 5 = -1
  177. // }
  178. // lockUtil.unLock(); -- 解锁
  179. int result = itemsMapperCustom.decreaseItemSpecStock(specId, buyCounts);
  180. if (result != 1) {
  181. throw new RuntimeException("订单创建失败,原因:库存不足!");
  182. }
  183. }
  184. }

封装分页对象

  1. import java.util.List;
  2. /** * * @Title: PagedGridResult.java * @Package com.zcw.utils * @Description: 用来返回分页Grid的数据格式 * Copyright: Copyright (c) 2020 */
  3. public class PagedGridResult {
  4. private int page; // 当前页数
  5. private int total; // 总页数
  6. private long records; // 总记录数
  7. private List<?> rows; // 每行显示的内容
  8. public int getPage() {
  9. return page;
  10. }
  11. public void setPage(int page) {
  12. this.page = page;
  13. }
  14. public int getTotal() {
  15. return total;
  16. }
  17. public void setTotal(int total) {
  18. this.total = total;
  19. }
  20. public long getRecords() {
  21. return records;
  22. }
  23. public void setRecords(long records) {
  24. this.records = records;
  25. }
  26. public List<?> getRows() {
  27. return rows;
  28. }
  29. public void setRows(List<?> rows) {
  30. this.rows = rows;
  31. }
  32. }
  • 此语句执行时,会触发MySQL的乐观锁



    update
    items_spec
    set
    stock = stock - #{ pendingCounts}
    where
    id = #{ specId}
    and
    stock >= #{ pendingCounts}

    public int decreaseItemSpecStock(@Param(“specId”) String specId,

    1. @Param("pendingCounts") int pendingCounts);

发表评论

表情:
评论列表 (有 0 条评论,375人围观)

还没有评论,来说两句吧...

相关阅读

    相关 订单状态【1】

    当用户点击“一键购买”或者是从购物车里点击 “去结算” ,会跳转到 “核实订单信息”  页面,当全部核实以后点击“提交订单按钮”,此时会跳转到支付页面,并且订单提交成功, 此