提交 8a0e33b8 编写于 作者: 郝先瑞

refactor: 订单重构优化

上级 054697e1
package com.youlai.mall.oms; package com.youlai.mall.oms;
import com.youlai.mall.pms.api.SkuFeignClient;
import com.youlai.mall.ums.api.MemberFeignClient; import com.youlai.mall.ums.api.MemberFeignClient;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
...@@ -11,8 +11,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; ...@@ -11,8 +11,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableDiscoveryClient @EnableDiscoveryClient
@EnableFeignClients(basePackageClasses = { MemberFeignClient.class, GoodsFeignClient.class}) @EnableFeignClients(basePackageClasses = { MemberFeignClient.class, SkuFeignClient.class})
@EnableRabbit
@EnableTransactionManagement @EnableTransactionManagement
public class OmsApplication { public class OmsApplication {
......
...@@ -7,7 +7,7 @@ import com.youlai.common.result.Result; ...@@ -7,7 +7,7 @@ import com.youlai.common.result.Result;
import com.youlai.common.web.util.JwtUtils; import com.youlai.common.web.util.JwtUtils;
import com.youlai.mall.oms.enums.PayTypeEnum; import com.youlai.mall.oms.enums.PayTypeEnum;
import com.youlai.mall.oms.pojo.dto.OrderConfirmDTO; import com.youlai.mall.oms.pojo.dto.OrderConfirmDTO;
import com.youlai.mall.oms.pojo.dto.OrderSubmitDTO; import com.youlai.mall.oms.pojo.form.OrderSubmitForm;
import com.youlai.mall.oms.pojo.entity.OmsOrder; import com.youlai.mall.oms.pojo.entity.OmsOrder;
import com.youlai.mall.oms.pojo.query.OrderPageQuery; import com.youlai.mall.oms.pojo.query.OrderPageQuery;
import com.youlai.mall.oms.pojo.vo.OrderConfirmVO; import com.youlai.mall.oms.pojo.vo.OrderConfirmVO;
...@@ -59,8 +59,8 @@ public class OrderController { ...@@ -59,8 +59,8 @@ public class OrderController {
@ApiOperation("订单提交") @ApiOperation("订单提交")
@PostMapping("/_submit") @PostMapping("/_submit")
public Result submit(@Valid @RequestBody OrderSubmitDTO orderSubmitDTO) { public Result submit(@Valid @RequestBody OrderSubmitForm orderSubmitForm) {
OrderSubmitVO result = orderService.submit(orderSubmitDTO); OrderSubmitVO result = orderService.submit(orderSubmitForm);
return Result.success(result); return Result.success(result);
} }
......
...@@ -12,13 +12,15 @@ import org.springframework.stereotype.Component; ...@@ -12,13 +12,15 @@ import org.springframework.stereotype.Component;
import java.io.IOException; import java.io.IOException;
/** /**
* @author hxr * 订单超时取消
* @date 2021-03-16 *
* @author haoxr
* @date 2021/3/16
*/ */
@Component @Component
@Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class OrderListener { public class OrderListener {
private final IOrderService orderService; private final IOrderService orderService;
......
...@@ -7,40 +7,47 @@ import java.io.Serializable; ...@@ -7,40 +7,47 @@ import java.io.Serializable;
/** /**
* 购物车商品传输层实体 * 购物车商品传输层实体
*/ */
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
@Data @Data
public class CartItemDTO implements Serializable { public class CartItemDTO implements Serializable {
/**
* 商品库存ID
*/
private Long skuId; private Long skuId;
/** /**
* 商品库存单元名称 * 商品库存名称
*/ */
private String skuName; private String skuName;
/** /**
* 商品库存单元编码 * 商品编码
*/ */
private String skuSn; private String skuSn;
/** /**
* 商品库存单元图片 * 商品图片
*/ */
private String picUrl; private String picUrl;
private Integer count; // 商品数量 /**
* 商品数量
*/
private Integer count;
/** /**
* 加入购物车价格,因会变动,不能作为订单计算因子,订单验价时需重新获取商品价格即可 * 加入购物车时价格,因会变动,不能作为订单计算因子,订单提交时需验价
*/ */
private Long price; private Long price;
/**
* 优惠券金额
*/
private Long coupon; private Long coupon;
/**
* 是否选中
*/
private Boolean checked; private Boolean checked;
/** /**
...@@ -51,6 +58,6 @@ public class CartItemDTO implements Serializable { ...@@ -51,6 +58,6 @@ public class CartItemDTO implements Serializable {
/** /**
* 商品名称 * 商品名称
*/ */
private String goodsName; private String spuName;
} }
...@@ -3,10 +3,7 @@ package com.youlai.mall.oms.pojo.entity; ...@@ -3,10 +3,7 @@ package com.youlai.mall.oms.pojo.entity;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.youlai.common.base.BaseEntity; import com.youlai.common.base.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
/** /**
...@@ -18,17 +15,13 @@ import lombok.experimental.Accessors; ...@@ -18,17 +15,13 @@ import lombok.experimental.Accessors;
*/ */
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class OmsOrderItem extends BaseEntity { public class OmsOrderItem extends BaseEntity {
/**
* id
*/
@TableId(type = IdType.AUTO) @TableId(type = IdType.AUTO)
private Long id; private Long id;
/** /**
* order_id * 订单ID
*/ */
private Long orderId; private Long orderId;
/** /**
...@@ -38,57 +31,36 @@ public class OmsOrderItem extends BaseEntity { ...@@ -38,57 +31,36 @@ public class OmsOrderItem extends BaseEntity {
/** /**
* 商品sku编号 * 商品sku编号
*/ */
private String skuCode; private String skuSn;
/**
* 商品名称
*/
private String skuName; private String skuName;
/** /**
* 商品sku图片 * 商品sku图片
*/ */
private String skuPic; private String picUrl;
/**
* 商品sku价格(分)
*/
private Long skuPrice;
/**
* 商品购买的数量
*/
private Integer skuQuantity;
/**
* 商品sku总价格(分)
*/
private Long skuTotalPrice;
/**
* spu_id
*/
private Long spuId;
/**
* spu_name
*/
private String spuName;
/**
* spu_pic
*/
private String spuPic;
/**
* 品牌id
*/
private Long brandId;
/** /**
* 品牌名称 * 商品单价(单位:分)
*/ */
private String brandName; private Long price;
/** /**
* 商品分类id * 商品数量
*/ */
private Long categoryId; private Integer count;
/** /**
* 商品分类名称 * 商品总金额(单位:分)
*/ */
private String categoryName; private Long totalAmount;
/** /**
* 逻辑删除【0->正常;1->已删除】 * 逻辑删除(0:正常;1:已删除)
*/ */
private Integer deleted; private Integer deleted;
......
package com.youlai.mall.oms.pojo.dto; package com.youlai.mall.oms.pojo.form;
import com.youlai.mall.oms.pojo.dto.OrderItemDTO;
import com.youlai.mall.ums.pojo.entity.UmsAddress; import com.youlai.mall.ums.pojo.entity.UmsAddress;
import lombok.Data; import lombok.Data;
...@@ -7,30 +8,51 @@ import javax.validation.constraints.Size; ...@@ -7,30 +8,51 @@ import javax.validation.constraints.Size;
import java.util.List; import java.util.List;
/** /**
* 订单提交表单对象
*
* @author huawei * @author huawei
* @desc 订单提交
* @email huawei_code@163.com * @email huawei_code@163.com
* @date 2021/1/16 * @date 2021/1/16
*/ */
@Data @Data
public class OrderSubmitDTO { public class OrderSubmitForm {
// 提交订单确认页面签发的令牌 /**
* 提交订单确认页面签发的令牌
*/
private String orderToken; private String orderToken;
private List<OrderItemDTO> orderItems; /**
* 订单总金额-用于验价(单位:分)
*/
private Long totalAmount;
// 验价前台传值 /**
private Long totalPrice; * 支付金额(单位:分)
*/
private Long payAmount;
/**
* 订单的商品明细
*/
private List<OrderItemDTO> orderItems;
// 收货地址 // 收货地址
private UmsAddress deliveryAddress;
@Size(max = 500, message = "订单备注长度不能超过500") @Size(max = 500, message = "订单备注长度不能超过500")
private String remark; private String remark;
/**
* 优惠券ID
*/
private String couponId; private String couponId;
private Long payAmount;
/**
* 收获地址
*/
private UmsAddress deliveryAddress;
} }
...@@ -9,7 +9,7 @@ import java.util.List; ...@@ -9,7 +9,7 @@ import java.util.List;
@Data @Data
public class OrderConfirmVO extends BaseVO { public class OrderConfirmVO {
private String orderToken; private String orderToken;
......
package com.youlai.mall.oms.pojo.vo; package com.youlai.mall.oms.pojo.vo;
import com.youlai.common.base.BaseVO;
import lombok.Data; import lombok.Data;
/** /**
* 订单创建响应视图对象
*
* @author huawei * @author huawei
* @desc 订单创建响应结果VO
* @email huawei_code@163.com * @email huawei_code@163.com
* @date 2021/1/21 * @date 2021/1/21
*/ */
@Data @Data
public class OrderSubmitVO extends BaseVO { public class OrderSubmitVO {
/** /**
* 订单ID * 订单ID
*/ */
......
package com.youlai.mall.oms.service; package com.youlai.mall.oms.service;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.github.binarywang.wxpay.bean.notify.SignatureHeader; import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
...@@ -12,7 +11,7 @@ import com.youlai.mall.oms.pojo.dto.OrderConfirmDTO; ...@@ -12,7 +11,7 @@ import com.youlai.mall.oms.pojo.dto.OrderConfirmDTO;
import com.youlai.mall.oms.pojo.query.OrderPageQuery; import com.youlai.mall.oms.pojo.query.OrderPageQuery;
import com.youlai.mall.oms.pojo.vo.OrderConfirmVO; import com.youlai.mall.oms.pojo.vo.OrderConfirmVO;
import com.youlai.mall.oms.pojo.vo.OrderSubmitVO; import com.youlai.mall.oms.pojo.vo.OrderSubmitVO;
import com.youlai.mall.oms.pojo.dto.OrderSubmitDTO; import com.youlai.mall.oms.pojo.form.OrderSubmitForm;
/** /**
* 订单业务接口 * 订单业务接口
...@@ -31,12 +30,7 @@ public interface IOrderService extends IService<OmsOrder> { ...@@ -31,12 +30,7 @@ public interface IOrderService extends IService<OmsOrder> {
/** /**
* 订单提交 * 订单提交
*/ */
OrderSubmitVO submit(OrderSubmitDTO orderSubmitDTO) ; OrderSubmitVO submit(OrderSubmitForm orderSubmitForm) ;
/**
* 订单提交
*/
OrderSubmitVO submitTcc(OrderSubmitDTO orderSubmitDTO) ;
/** /**
* 订单支付 * 订单支付
......
package com.youlai.mall.oms.service.impl; package com.youlai.mall.oms.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import com.youlai.common.result.ResultCode; import com.youlai.common.result.ResultCode;
import com.youlai.common.web.exception.BizException; import com.youlai.common.web.exception.BizException;
...@@ -7,8 +8,12 @@ import com.youlai.common.web.util.JwtUtils; ...@@ -7,8 +8,12 @@ import com.youlai.common.web.util.JwtUtils;
import com.youlai.mall.oms.constant.OmsConstants; import com.youlai.mall.oms.constant.OmsConstants;
import com.youlai.mall.oms.pojo.dto.CartItemDTO; import com.youlai.mall.oms.pojo.dto.CartItemDTO;
import com.youlai.mall.oms.service.ICartService; import com.youlai.mall.oms.service.ICartService;
import com.youlai.mall.pms.api.SkuFeignClient;
import com.youlai.mall.pms.pojo.dto.SkuInfoDTO;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.data.redis.core.BoundHashOperations; import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -33,7 +38,7 @@ import java.util.concurrent.CompletableFuture; ...@@ -33,7 +38,7 @@ import java.util.concurrent.CompletableFuture;
public class CartServiceImpl implements ICartService { public class CartServiceImpl implements ICartService {
private RedisTemplate redisTemplate; private RedisTemplate redisTemplate;
private GoodsFeignClient skuFeignService; private SkuFeignClient skuFeignService;
@Override @Override
public List<CartItemDTO> listCartItemByMemberId(Long memberId) { public List<CartItemDTO> listCartItemByMemberId(Long memberId) {
...@@ -78,22 +83,16 @@ public class CartServiceImpl implements ICartService { ...@@ -78,22 +83,16 @@ public class CartServiceImpl implements ICartService {
// 购物车不存在该商品,添加商品至购物车 // 购物车不存在该商品,添加商品至购物车
cartItem = new CartItemDTO(); cartItem = new CartItemDTO();
CompletableFuture<Void> cartItemCompletableFuture = CompletableFuture.runAsync(() -> { CompletableFuture<Void> cartItemCompletableFuture = CompletableFuture.runAsync(() -> {
AppSkuDetailVO sku = skuFeignService.getSkuById(skuId).getData(); SkuInfoDTO skuInfo = skuFeignService.getSkuInfo(skuId).getData();
if (sku != null) { if (skuInfo != null) {
cartItem.setSkuId(sku.getId()); BeanUtil.copyProperties(skuInfo,cartItem);
cartItem.setCount(1); cartItem.setCount(1);
cartItem.setPrice(sku.getPrice());
cartItem.setPicUrl(sku.getPicUrl());
cartItem.setSkuName(sku.getName());
cartItem.setStock(sku.getStock());
cartItem.setSkuSn(sku.getSn());
cartItem.setGoodsName(sku.getSpuName());
cartItem.setChecked(true); cartItem.setChecked(true);
} }
}); });
CompletableFuture.allOf(cartItemCompletableFuture).join(); CompletableFuture.allOf(cartItemCompletableFuture).join();
Assert.isTrue(cartItem.getSkuId() != null && cartItem.getSkuId() > 0,"商品不存在"); Assert.isTrue(cartItem.getSkuId() != null,"商品不存在");
cartHashOperations.put(hKey, cartItem); cartHashOperations.put(hKey, cartItem);
return true; return true;
} }
......
...@@ -5,6 +5,7 @@ import cn.hutool.core.collection.CollectionUtil; ...@@ -5,6 +5,7 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
...@@ -29,20 +30,20 @@ import com.youlai.mall.oms.enums.OrderStatusEnum; ...@@ -29,20 +30,20 @@ import com.youlai.mall.oms.enums.OrderStatusEnum;
import com.youlai.mall.oms.enums.OrderTypeEnum; import com.youlai.mall.oms.enums.OrderTypeEnum;
import com.youlai.mall.oms.enums.PayTypeEnum; import com.youlai.mall.oms.enums.PayTypeEnum;
import com.youlai.mall.oms.mapper.OrderMapper; import com.youlai.mall.oms.mapper.OrderMapper;
import com.youlai.mall.oms.pojo.dto.CartItemDTO;
import com.youlai.mall.oms.pojo.dto.OrderConfirmDTO; import com.youlai.mall.oms.pojo.dto.OrderConfirmDTO;
import com.youlai.mall.oms.pojo.dto.OrderItemDTO; import com.youlai.mall.oms.pojo.dto.OrderItemDTO;
import com.youlai.mall.oms.pojo.dto.OrderSubmitDTO;
import com.youlai.mall.oms.pojo.dto.CartItemDTO;
import com.youlai.mall.oms.pojo.entity.OmsOrder; import com.youlai.mall.oms.pojo.entity.OmsOrder;
import com.youlai.mall.oms.pojo.entity.OmsOrderItem; import com.youlai.mall.oms.pojo.entity.OmsOrderItem;
import com.youlai.mall.oms.pojo.form.OrderSubmitForm;
import com.youlai.mall.oms.pojo.query.OrderPageQuery; import com.youlai.mall.oms.pojo.query.OrderPageQuery;
import com.youlai.mall.oms.pojo.vo.OrderConfirmVO; import com.youlai.mall.oms.pojo.vo.OrderConfirmVO;
import com.youlai.mall.oms.pojo.vo.OrderSubmitVO; import com.youlai.mall.oms.pojo.vo.OrderSubmitVO;
import com.youlai.mall.oms.service.ICartService; import com.youlai.mall.oms.service.ICartService;
import com.youlai.mall.oms.service.IOrderItemService; import com.youlai.mall.oms.service.IOrderItemService;
import com.youlai.mall.oms.service.IOrderService; import com.youlai.mall.oms.service.IOrderService;
import com.youlai.mall.oms.tcc.service.SeataTccOrderService;
import com.youlai.mall.pms.api.SkuFeignClient; import com.youlai.mall.pms.api.SkuFeignClient;
import com.youlai.mall.pms.pojo.dto.CheckPriceDTO;
import com.youlai.mall.pms.pojo.dto.SkuInfoDTO; import com.youlai.mall.pms.pojo.dto.SkuInfoDTO;
import com.youlai.mall.pms.pojo.dto.app.LockStockDTO; import com.youlai.mall.pms.pojo.dto.app.LockStockDTO;
import com.youlai.mall.ums.api.MemberAddressFeignClient; import com.youlai.mall.ums.api.MemberAddressFeignClient;
...@@ -52,7 +53,6 @@ import com.youlai.mall.ums.pojo.entity.UmsMember; ...@@ -52,7 +53,6 @@ import com.youlai.mall.ums.pojo.entity.UmsMember;
import io.seata.spring.annotation.GlobalTransactional; import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.assertj.core.api.Assertions;
import org.redisson.api.RLock; import org.redisson.api.RLock;
import org.redisson.api.RedissonClient; import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.core.RabbitTemplate;
...@@ -87,16 +87,29 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme ...@@ -87,16 +87,29 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
private final MemberFeignClient memberFeignClient; private final MemberFeignClient memberFeignClient;
private final BusinessNoGenerator businessNoGenerator; private final BusinessNoGenerator businessNoGenerator;
private final SkuFeignClient skuFeignClient; private final SkuFeignClient skuFeignClient;
private final SeataTccOrderService seataTccOrderService;
private final RedissonClient redissonClient; private final RedissonClient redissonClient;
private final WxPayService wxPayService; private final WxPayService wxPayService;
/**
* 订单分页列表
*
* @param queryParams
* @return
*/
@Override
public IPage<OmsOrder> listOrdersWithPage(OrderPageQuery queryParams) {
Page<OmsOrder> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
List<OmsOrder> list = this.baseMapper.listUsersWithPage(page, queryParams);
page.setRecords(list);
return page;
}
/** /**
* 订单确认 * 订单确认
*/ */
@Override @Override
public OrderConfirmVO confirm(OrderConfirmDTO orderConfirmDTO) { public OrderConfirmVO confirm(OrderConfirmDTO orderConfirmDTO) {
log.info("=======================订单确认=======================\n订单确认信息:{}", orderConfirmDTO); log.info("订单确认:{}", orderConfirmDTO);
OrderConfirmVO orderConfirmVO = new OrderConfirmVO(); OrderConfirmVO orderConfirmVO = new OrderConfirmVO();
Long memberId = JwtUtils.getUserId(); Long memberId = JwtUtils.getUserId();
...@@ -104,14 +117,14 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme ...@@ -104,14 +117,14 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
CompletableFuture<Void> orderItemsCompletableFuture = CompletableFuture.runAsync(() -> { CompletableFuture<Void> orderItemsCompletableFuture = CompletableFuture.runAsync(() -> {
List<OrderItemDTO> orderItems = new ArrayList<>(); List<OrderItemDTO> orderItems = new ArrayList<>();
Long skuId = orderConfirmDTO.getSkuId(); Long skuId = orderConfirmDTO.getSkuId();
if (skuId != null) { // 直接购买商品 if (skuId != null) { // 直接购买
Result<SkuInfoDTO> getSkuInfoResult = skuFeignClient.getSkuInfo(orderConfirmDTO.getSkuId()); Result<SkuInfoDTO> getSkuInfoResult = skuFeignClient.getSkuInfo(orderConfirmDTO.getSkuId());
Assert.isTrue(Result.isSuccess(getSkuInfoResult), "获取商品信息失败"); Assert.isTrue(Result.isSuccess(getSkuInfoResult), "获取商品信息失败");
SkuInfoDTO skuInfoDTO = getSkuInfoResult.getData(); SkuInfoDTO skuInfoDTO = getSkuInfoResult.getData();
OrderItemDTO orderItemDTO = new OrderItemDTO(); OrderItemDTO orderItemDTO = new OrderItemDTO();
BeanUtil.copyProperties(skuInfoDTO, orderItemDTO); BeanUtil.copyProperties(skuInfoDTO, orderItemDTO);
orderItems.add(orderItemDTO); orderItems.add(orderItemDTO);
} else { // 购物车中商品结算 } else { // 购物车结算
List<CartItemDTO> cartItems = cartService.listCartItemByMemberId(memberId); List<CartItemDTO> cartItems = cartService.listCartItemByMemberId(memberId);
List<OrderItemDTO> items = cartItems.stream() List<OrderItemDTO> items = cartItems.stream()
.filter(CartItemDTO::getChecked) .filter(CartItemDTO::getChecked)
...@@ -149,142 +162,74 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme ...@@ -149,142 +162,74 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
*/ */
@Override @Override
@GlobalTransactional @GlobalTransactional
public OrderSubmitVO submit(OrderSubmitDTO submitDTO) { public OrderSubmitVO submit(OrderSubmitForm orderSubmitForm) {
log.info("=======================订单提交=======================\n订单提交信息:{}", submitDTO); log.info("订单提交数据:{}", JSONUtil.toJsonStr(orderSubmitForm));
// 订单校验
List<OrderItemDTO> orderItems = orderSubmitForm.getOrderItems();
Assert.isTrue(CollectionUtil.isNotEmpty(orderItems), "订单没有商品");
// 订单重复提交校验 // 订单重复提交校验
String orderToken = submitDTO.getOrderToken(); String orderToken = orderSubmitForm.getOrderToken();
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(RELEASE_LOCK_LUA_SCRIPT, Long.class); DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(RELEASE_LOCK_LUA_SCRIPT, Long.class);
Long execute = this.redisTemplate.execute(redisScript, Collections.singletonList(ORDER_TOKEN_PREFIX + orderToken), orderToken); Long execute = this.redisTemplate.execute(redisScript, Collections.singletonList(ORDER_TOKEN_PREFIX + orderToken), orderToken);
Assert.isTrue(execute.equals(1l), "订单不可重复提交"); Assert.isTrue(execute.equals(1l), "订单不可重复提交");
List<OrderItemDTO> orderItems = submitDTO.getOrderItems();
Assert.isTrue(CollectionUtil.isNotEmpty(orderItems), "订单商品为空");
// 订单验价 // 订单验价
Long currentTotalPrice = orderItems.stream().map(item -> { Long orderTotalAmount = orderSubmitForm.getTotalAmount();
SkuInfoDTO sku = skuFeignClient.getSkuInfo(item.getSkuId()).getData(); boolean checkResult = checkOrderPrice(orderTotalAmount, orderItems);
if (sku != null) { Assert.isTrue(checkResult, "当前页面已过期,请重新刷新页面再提交");
return sku.getPrice() * item.getCount();
}
return 0L;
}).reduce(0L, Long::sum);
Assert.isTrue(currentTotalPrice.compareTo(submitDTO.getTotalPrice()) == 0, "当前页面已过期,请重新刷新页面再提交"); // 锁定库存
// 校验库存是否足够和锁库存
List<LockStockDTO> skuLockList = orderItems.stream() List<LockStockDTO> skuLockList = orderItems.stream()
.map(item -> LockStockDTO.builder().skuId(item.getSkuId()) .map(item -> LockStockDTO.builder().skuId(item.getSkuId())
.count(item.getCount()) .count(item.getCount())
.orderToken(orderToken) .orderToken(orderToken)
.build()) .build())
.collect(Collectors.toList()); .collect(Collectors.toList());
// 锁定库存
Result lockResult = skuFeignClient.lockStock(skuLockList); Result lockResult = skuFeignClient.lockStock(skuLockList);
Assert.isTrue(Result.isSuccess(lockResult), "锁定商品库存失败:{}", lockResult.getMsg()); Assert.isTrue(Result.isSuccess(lockResult), "锁定商品库存失败:{}", lockResult.getMsg());
// 创建订单(状态:待支付) // 创建订单
OmsOrder order = new OmsOrder(); OmsOrder order = new OmsOrder().setOrderSn(orderToken) // 把orderToken赋值给订单编号
order.setOrderSn(orderToken) // 把orderToken赋值给订单编号【!】
.setStatus(OrderStatusEnum.PENDING_PAYMENT.getCode()) .setStatus(OrderStatusEnum.PENDING_PAYMENT.getCode())
.setSourceType(OrderTypeEnum.APP.getCode()) .setSourceType(OrderTypeEnum.APP.getCode())
.setMemberId(JwtUtils.getUserId()) .setMemberId(JwtUtils.getUserId())
.setRemark(submitDTO.getRemark()) .setRemark(orderSubmitForm.getRemark())
.setPayAmount(submitDTO.getPayAmount()) .setPayAmount(orderSubmitForm.getPayAmount())
.setTotalQuantity(orderItems.stream().map(OrderItemDTO::getCount).reduce(0, Integer::sum)) .setTotalQuantity(orderItems.stream().map(OrderItemDTO::getCount).reduce(0, Integer::sum))
.setTotalAmount(orderItems.stream().map(item -> item.getPrice() * item.getCount()).reduce(0L, Long::sum)); .setTotalAmount(orderItems.stream().map(item -> item.getPrice() * item.getCount()).reduce(0L, Long::sum));
this.save(order); boolean result = this.save(order);
// 创建订单商品
List<OmsOrderItem> orderItemList = orderItems.stream().map(item -> OmsOrderItem.builder()
.orderId(order.getId())
.skuId(item.getSkuId())
.skuName(item.getSkuName())
.skuPrice(item.getPrice())
.skuPic(item.getPic())
.skuQuantity(item.getCount())
.skuTotalPrice(item.getCount() * item.getPrice())
.skuCode(item.getSkuCode())
.build()).collect(Collectors.toList());
orderItemService.saveBatch(orderItemList);
// 将订单放入延时队列,超时未支付由交换机order.exchange切换到死信队列完成系统自动关单
log.info("订单超时取消RabbitMQ消息发送,订单SN:{}", orderToken);
rabbitTemplate.convertAndSend("order.exchange", "order.create", orderToken);
OrderSubmitVO submitVO = new OrderSubmitVO();
submitVO.setOrderId(order.getId());
submitVO.setOrderSn(order.getOrderSn());
log.info("订单提交响应:{}", submitVO);
return submitVO;
}
@Override // 添加订单明细
@GlobalTransactional(rollbackFor = Exception.class) if (result) {
public OrderSubmitVO submitTcc(OrderSubmitDTO submitDTO) { List<OmsOrderItem> orderItemList = orderItems.stream().map(orderFormItem -> {
log.info("=======================订单提交=======================\n订单提交信息:{}", submitDTO); OmsOrderItem omsOrderItem = new OmsOrderItem();
// 订单重复提交校验 BeanUtil.copyProperties(orderFormItem, omsOrderItem);
String orderToken = submitDTO.getOrderToken(); omsOrderItem.setOrderId(order.getId());
// DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(RELEASE_LOCK_LUA_SCRIPT, Long.class); omsOrderItem.setTotalAmount(orderFormItem.getPrice() * orderFormItem.getCount());
// Long result = this.redisTemplate.execute(redisScript, Collections.singletonList(ORDER_TOKEN_PREFIX + orderToken), orderToken); return omsOrderItem;
// }).collect(Collectors.toList());
// if (!ObjectUtil.equals(result, RELEASE_LOCK_SUCCESS_RESULT)) { result = orderItemService.saveBatch(orderItemList);
// throw new BizException("订单不可重复提交"); if (result) {
// } // 订单超时取消
rabbitTemplate.convertAndSend("order.exchange", "order.create", orderToken);
List<OrderItemDTO> orderItems = submitDTO.getOrderItems();
if (CollectionUtil.isEmpty(orderItems)) {
throw new BizException("订单没有商品,请选择商品后提交");
}
// 订单验价
Long currentTotalPrice = orderItems.stream().map(item -> {
AppSkuDetailVO sku = goodsFeignClient.getSkuById(item.getSkuId()).getData();
if (sku != null) {
return sku.getPrice() * item.getCount();
} }
return 0L;
}).reduce(0L, Long::sum);
if (currentTotalPrice.compareTo(submitDTO.getTotalPrice()) != 0) {
throw new BizException("页面已过期,请重新刷新页面再提交");
}
// 校验库存是否足够和锁库存
List<LockStockDTO> skuLockList = orderItems.stream()
.map(item -> LockStockDTO.builder().skuId(item.getSkuId())
.count(item.getCount())
.orderToken(orderToken)
.build())
.collect(Collectors.toList());
Result<?> lockResult = skuFeignClient.lockStock(skuLockList);
if (!Result.success().getCode().equals(lockResult.getCode())) {
throw new BizException(Result.failed().getMsg());
} }
// TCC模式创建订单(状态:待支付) Assert.isTrue(result, "订单提交失败");
OmsOrder order = seataTccOrderService.prepareSubmitOrder(null, submitDTO);
// 将订单放入延时队列,超时未支付由交换机order.exchange切换到死信队列完成系统自动关单
log.info("订单超时取消RabbitMQ消息发送,订单SN:{}", orderToken);
rabbitTemplate.convertAndSend("order.exchange", "order.create", orderToken);
// 成功响应返回值构建
OrderSubmitVO submitVO = new OrderSubmitVO(); OrderSubmitVO submitVO = new OrderSubmitVO();
submitVO.setOrderId(order.getId()); submitVO.setOrderId(order.getId());
submitVO.setOrderSn(order.getOrderSn()); submitVO.setOrderSn(order.getOrderSn());
log.info("订单提交响应:{}", submitVO);
return submitVO; return submitVO;
} }
/** /**
* 订单支付 * 订单支付
* *
* @param orderId
* @param appId
* @return * @return
*/ */
@Override @Override
@SuppressWarnings("unchecked")
@GlobalTransactional(rollbackFor = Exception.class) @GlobalTransactional(rollbackFor = Exception.class)
public <T> T pay(Long orderId, String appId, PayTypeEnum payTypeEnum) { public <T> T pay(Long orderId, String appId, PayTypeEnum payTypeEnum) {
OmsOrder order = this.getById(orderId); OmsOrder order = this.getById(orderId);
...@@ -315,11 +260,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme ...@@ -315,11 +260,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
// 扣减库存 // 扣减库存
Result<?> deductStockResult = skuFeignClient.deductStock(order.getOrderSn()); Result<?> deductStockResult = skuFeignClient.deductStock(order.getOrderSn());
if (!Result.isSuccess(deductStockResult)) { if (!Result.isSuccess(deductStockResult)) {
throw new BizException("扣减商品库存失败"); throw new BizException("扣减商品库存失败");
} }
return result; return result;
} catch (InterruptedException e) { } catch (InterruptedException e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
...@@ -336,6 +279,12 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme ...@@ -336,6 +279,12 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
} }
private Boolean balancePay(OmsOrder order) { private Boolean balancePay(OmsOrder order) {
// 扣减余额 // 扣减余额
Long payAmount = order.getPayAmount(); Long payAmount = order.getPayAmount();
...@@ -403,7 +352,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme ...@@ -403,7 +352,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
@Override @Override
public boolean closeOrder(String orderToken) { public boolean closeOrder(String orderToken) {
log.info("=======================订单关闭,订单SN:{}=======================", orderToken); log.info("订单超时取消,orderToken:{}", orderToken);
OmsOrder order = this.getOne(new LambdaQueryWrapper<OmsOrder>() OmsOrder order = this.getOne(new LambdaQueryWrapper<OmsOrder>()
.eq(OmsOrder::getOrderSn, orderToken)); .eq(OmsOrder::getOrderSn, orderToken));
if (order == null || !OrderStatusEnum.PENDING_PAYMENT.getCode().equals(order.getStatus())) { if (order == null || !OrderStatusEnum.PENDING_PAYMENT.getCode().equals(order.getStatus())) {
...@@ -425,7 +374,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme ...@@ -425,7 +374,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
@Override @Override
public boolean cancelOrder(Long id) { public boolean cancelOrder(Long id) {
log.info("=======================订单取消,订单ID:{}=======================", id); log.info("订单超时取消,订单ID:{}", id);
OmsOrder order = this.getById(id); OmsOrder order = this.getById(id);
if (order == null) { if (order == null) {
throw new BizException("订单不存在"); throw new BizException("订单不存在");
...@@ -516,18 +465,29 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme ...@@ -516,18 +465,29 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
} }
/** /**
* 订单分页列表 * 订单验价
* *
* @param queryParams * @param orderTotalAmount 订单总金额
* @param orderItems 订单商品明细
* @return * @return
*/ */
@Override private boolean checkOrderPrice(Long orderTotalAmount, List<OrderItemDTO> orderItems) {
public IPage<OmsOrder> listOrdersWithPage(OrderPageQuery queryParams) { CheckPriceDTO checkPriceDTO = new CheckPriceDTO();
Page<OmsOrder> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize()); List<CheckPriceDTO.CheckSku> checkSkus = orderItems.stream().map(orderFormItem -> {
List<OmsOrder> list = this.baseMapper.listUsersWithPage(page, queryParams); CheckPriceDTO.CheckSku checkSku = new CheckPriceDTO.CheckSku();
page.setRecords(list); checkSku.setSkuId(orderFormItem.getSkuId());
return page; checkSku.setCount(orderFormItem.getCount());
return checkSku;
}).collect(Collectors.toList());
checkPriceDTO.setOrderTotalAmount(orderTotalAmount); // 订单总金额
checkPriceDTO.setCheckSkus(checkSkus); // 订单的商品明细
// 调用验价接口,比较订单总金额和商品明细总金额,不一致则说明商品价格变动
Result<Boolean> checkPriceResult = skuFeignClient.checkPrice(checkPriceDTO);
boolean result = Result.isSuccess(checkPriceResult) && Boolean.TRUE.equals(checkPriceResult.getData());
return result;
} }
} }
package com.youlai.mall.oms.tcc.idempotent;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
/**
* @Author DaniR
* @Description TCC幂等工具类
* @Date 2021/7/15 20:38
**/
public class IdempotentUtil {
private static Table<Class<?>,String,Long> map= HashBasedTable.create();
public static void addMarker(Class<?> clazz,String xid,Long marker){
map.put(clazz,xid,marker);
}
public static Long getMarker(Class<?> clazz,String xid){
return map.get(clazz,xid);
}
public static void removeMarker(Class<?> clazz,String xid){
map.remove(clazz,xid);
}
}
\ No newline at end of file
package com.youlai.mall.oms.tcc.service;
import com.youlai.mall.oms.pojo.dto.OrderSubmitDTO;
import com.youlai.mall.oms.pojo.entity.OmsOrder;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import io.seata.rm.tcc.api.LocalTCC;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
@LocalTCC
public interface SeataTccOrderService {
@TwoPhaseBusinessAction(name = "prepareSubmitOrder", commitMethod = "commitSubmitOrder", rollbackMethod = "rollbackSubmitOrder")
OmsOrder prepareSubmitOrder(BusinessActionContext businessActionContext,
@BusinessActionContextParameter(paramName = "orderSubmitDTO") OrderSubmitDTO orderSubmitDTO);
boolean commitSubmitOrder(BusinessActionContext businessActionContext);
boolean rollbackSubmitOrder(BusinessActionContext businessActionContext);
}
package com.youlai.mall.oms.tcc.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.youlai.common.web.util.JwtUtils;
import com.youlai.mall.oms.enums.OrderStatusEnum;
import com.youlai.mall.oms.enums.OrderTypeEnum;
import com.youlai.mall.oms.mapper.OrderMapper;
import com.youlai.mall.oms.pojo.dto.OrderItemDTO;
import com.youlai.mall.oms.pojo.dto.OrderSubmitDTO;
import com.youlai.mall.oms.pojo.entity.OmsOrder;
import com.youlai.mall.oms.pojo.entity.OmsOrderItem;
import com.youlai.mall.oms.service.IOrderItemService;
import com.youlai.mall.oms.tcc.idempotent.IdempotentUtil;
import com.youlai.mall.oms.tcc.service.SeataTccOrderService;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Slf4j
@Component
public class SeataTccOrderServiceImpl implements SeataTccOrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private IOrderItemService orderItemService;
@Transactional
@Override
public OmsOrder prepareSubmitOrder(BusinessActionContext businessActionContext, OrderSubmitDTO orderSubmitDTO) {
log.info("==========创建 订单 第一阶段,事务组Xid:{} ==========", businessActionContext.getXid());
List<OrderItemDTO> orderItems = orderSubmitDTO.getOrderItems();
String orderToken = orderSubmitDTO.getOrderToken();
// 创建订单(状态:待支付)
OmsOrder order = new OmsOrder();
order.setOrderSn(orderToken)
.setStatus(OrderStatusEnum.PENDING_PAYMENT.getCode())
.setSourceType(OrderTypeEnum.APP.getCode())
.setMemberId(JwtUtils.getUserId())
.setRemark(orderSubmitDTO.getRemark())
.setPayAmount(orderSubmitDTO.getPayAmount())
.setTotalQuantity(orderItems.stream().map(item -> item.getCount()).reduce(0, (x, y) -> x + y))
.setTotalAmount(orderItems.stream().map(item -> item.getPrice() * item.getCount()).reduce(0l, (x, y) -> x + y));
orderMapper.insert(order);
int i = 1 / 0;
// 创建订单商品
List<OmsOrderItem> orderItemList = orderItems.stream().map(item -> OmsOrderItem.builder()
.orderId(order.getId())
.skuId(item.getSkuId())
.skuName(item.getSkuName())
.skuPrice(item.getPrice())
.skuPic(item.getPic())
.skuQuantity(item.getCount())
.skuTotalPrice(item.getCount() * item.getPrice())
.skuCode(item.getSkuCode())
.build()).collect(Collectors.toList());
orderItemService.saveBatch(orderItemList);
log.info("保存订单:{} 成功", order.getOrderSn());
IdempotentUtil.addMarker(getClass(), businessActionContext.getXid(), System.currentTimeMillis());
return order;
}
@Override
@Transactional
public boolean commitSubmitOrder(BusinessActionContext businessActionContext) {
if (Objects.isNull(IdempotentUtil.getMarker(getClass(), businessActionContext.getXid()))) {
return true;
}
IdempotentUtil.removeMarker(getClass(), businessActionContext.getXid());
return true;
}
@Override
@Transactional
public boolean rollbackSubmitOrder(BusinessActionContext businessActionContext) {
if (Objects.isNull(IdempotentUtil.getMarker(getClass(), businessActionContext.getXid()))) {
return true;
}
JSONObject jsonObject = (JSONObject) businessActionContext.getActionContext("orderSubmitDTO");
OrderSubmitDTO orderSubmitDTO = new OrderSubmitDTO();
BeanUtil.copyProperties(jsonObject, orderSubmitDTO);
OmsOrder omsOrder = orderMapper.selectOne(new LambdaQueryWrapper<OmsOrder>().eq(OmsOrder::getOrderSn, orderSubmitDTO.getOrderToken()));
if (Objects.nonNull(omsOrder)) {
orderItemService.remove(new LambdaQueryWrapper<OmsOrderItem>().eq(OmsOrderItem::getOrderId, omsOrder.getId()));
orderMapper.deleteById(omsOrder.getId());
}
IdempotentUtil.removeMarker(getClass(), businessActionContext.getXid());
return true;
}
}
package com.youlai.mall.pms.api; package com.youlai.mall.pms.api;
import com.youlai.common.result.Result; import com.youlai.common.result.Result;
import com.youlai.mall.pms.pojo.dto.CheckPriceDTO;
import com.youlai.mall.pms.pojo.dto.SkuInfoDTO; import com.youlai.mall.pms.pojo.dto.SkuInfoDTO;
import com.youlai.mall.pms.pojo.dto.app.LockStockDTO; import com.youlai.mall.pms.pojo.dto.app.LockStockDTO;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List; import java.util.List;
@FeignClient(value = "mall-pms",contextId = "sku") @FeignClient(value = "mall-pms", contextId = "sku")
public interface SkuFeignClient { public interface SkuFeignClient {
/** /**
...@@ -33,7 +35,15 @@ public interface SkuFeignClient { ...@@ -33,7 +35,15 @@ public interface SkuFeignClient {
* 扣减库存 * 扣减库存
*/ */
@PutMapping("/app-api/v1/sku/_deduct") @PutMapping("/app-api/v1/sku/_deduct")
Result deductStock(@RequestParam String orderToken); Result deductStock(@RequestParam String orderToken);
/**
* 商品验价
*
* @param checkPriceDTO
* @return
*/
@PutMapping("/app-api/v1/sku/price/_check")
Result<Boolean> checkPrice(@RequestBody CheckPriceDTO checkPriceDTO);
} }
package com.youlai.mall.pms.pojo.dto;
import lombok.Data;
import java.util.List;
/**
* 商品验价传输层实体
*
* @author <a href="mailto:xianrui0365@163.com">haoxr</a>
* @date 2022/2/7 22:52
*/
@Data
public class CheckPriceDTO {
/**
* 订单商品总金额
*/
private Long orderTotalAmount;
/**
* 订单商品明细
*/
private List<CheckSku> checkSkus;
/**
* 订单商品明细
*/
@Data
public static class CheckSku {
/**
* 商品ID
*/
private Long skuId;
/**
* 商品数量
*/
private Integer count;
}
}
...@@ -13,6 +13,7 @@ import lombok.Data; ...@@ -13,6 +13,7 @@ import lombok.Data;
*/ */
@Data @Data
public class PmsSku extends BaseEntity { public class PmsSku extends BaseEntity {
@TableId(type = IdType.AUTO) @TableId(type = IdType.AUTO)
private Long id; private Long id;
......
...@@ -3,54 +3,40 @@ package com.youlai.mall.pms.controller.admin; ...@@ -3,54 +3,40 @@ package com.youlai.mall.pms.controller.admin;
import com.youlai.common.result.Result; import com.youlai.common.result.Result;
import com.youlai.mall.pms.pojo.entity.PmsSku; import com.youlai.mall.pms.pojo.entity.PmsSku;
import com.youlai.mall.pms.service.IPmsSkuService; import com.youlai.mall.pms.service.IPmsSkuService;
import io.swagger.annotations.Api; import io.swagger.annotations.*;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
/** /**
* @author <a href="mailto:xianrui0365@163.com">haoxr</a> * @author <a href="mailto:xianrui0365@163.com">haoxr</a>
* @date 2022/2/8
*/ */
@Api(tags = "「系统端」库存信息") @Api(tags = "「系统端」库存信息")
@RestController @RestController
@RequestMapping("/api/v1/inventories") @RequestMapping("/api/v1/sku")
@RequiredArgsConstructor @RequiredArgsConstructor
public class StockController { public class StockController {
private final IPmsSkuService iPmsSkuService; private final IPmsSkuService skuService;
@ApiOperation(value = "商品库存详情") @ApiOperation(value = "商品库存详情")
@ApiImplicitParam(name = "id", value = "商品ID", required = true, paramType = "path", dataType = "Long") @ApiImplicitParam(name = "id", value = "商品ID", required = true, paramType = "path", dataType = "Long")
@GetMapping("/{id}") @GetMapping("/{skuId}")
public Result detail(@PathVariable Long id) { public Result detail(
PmsSku sku = iPmsSkuService.getById(id); @PathVariable Long skuId
) {
PmsSku sku = skuService.getById(skuId);
return Result.success(sku); return Result.success(sku);
} }
@ApiOperation(value = "修改库存") @ApiOperation(value = "修改库存")
@ApiImplicitParams({ @PutMapping(value = "/{skuId}")
@ApiImplicitParam(name = "id", value = "商品ID", required = true, paramType = "path", dataType = "Long"), public Result update(
@ApiImplicitParam(name = "sku", value = "实体JSON对象", required = true, paramType = "body", dataType = "PmsSku") @ApiParam("商品库存单元ID") @PathVariable Long skuId,
}) @RequestBody PmsSku sku
@PutMapping(value = "/{id}") ) {
public Result update(@PathVariable Long id, @RequestBody PmsSku sku) { boolean status = skuService.updateById(sku);
boolean status = iPmsSkuService.updateById(sku);
return Result.judge(status); return Result.judge(status);
} }
@ApiOperation(value = "修改商品库存")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "商品ID", required = true, paramType = "path", dataType = "Long"),
@ApiImplicitParam(name = "num", value = "库存数量", required = true, paramType = "query", dataType = "Long")
})
@PatchMapping("/{id}/stock")
public Result updateStock(@PathVariable Long id, @RequestParam Integer num) {
PmsSku sku = iPmsSkuService.getById(id);
sku.setStock(sku.getStock() + num);
boolean result = iPmsSkuService.updateById(sku);
return Result.judge(result);
}
} }
package com.youlai.mall.pms.controller.app; package com.youlai.mall.pms.controller.app;
import com.youlai.common.result.Result; import com.youlai.common.result.Result;
import com.youlai.mall.pms.pojo.dto.CheckPriceDTO;
import com.youlai.mall.pms.pojo.dto.SkuInfoDTO; import com.youlai.mall.pms.pojo.dto.SkuInfoDTO;
import com.youlai.mall.pms.pojo.dto.app.LockStockDTO; import com.youlai.mall.pms.pojo.dto.app.LockStockDTO;
import com.youlai.mall.pms.service.IPmsSkuService; import com.youlai.mall.pms.service.IPmsSkuService;
...@@ -23,27 +24,19 @@ public class SkuController { ...@@ -23,27 +24,19 @@ public class SkuController {
private final IPmsSkuService skuService; private final IPmsSkuService skuService;
@ApiOperation(value = "获取商品库存详情")
@GetMapping("/{skuId}")
public Result<AppSkuDetailVO> getSkuDetail(@PathVariable Long skuId) {
AppSkuDetailVO sku = skuService.getSkuById(skuId);
return Result.success(sku);
}
@ApiOperation(value = "获取商品库存信息") @ApiOperation(value = "获取商品库存信息")
@GetMapping("/{skuId}") @GetMapping("/{skuId}")
public Result<SkuInfoDTO> getSkuInfo( public Result<SkuInfoDTO> getSkuInfo(
@ApiParam("商品库存单元ID") @PathVariable Long skuId @ApiParam("商品库存单元ID") @PathVariable Long skuId
) { ) {
SkuInfoDTO skuInfo = skuService.getSkuInfo(skuId); SkuInfoDTO skuInfo = skuService.getSkuInfo(skuId);
return Result.success(skuInfo); return Result.success(skuInfo);
} }
@ApiOperation("获取商品库存数量") @ApiOperation("获取商品库存数量")
@GetMapping("/{skuId}/stock_num") @GetMapping("/{skuId}/stock_num")
public Result<Integer> getStockNum( public Result<Integer> getStockNum(
@ApiParam("商品库存单元ID") @PathVariable Long skuId @ApiParam("商品库存单元ID") @PathVariable Long skuId
) { ) {
Integer stockNum = skuService.getStockNum(skuId); Integer stockNum = skuService.getStockNum(skuId);
return Result.success(stockNum); return Result.success(stockNum);
...@@ -68,4 +61,11 @@ public class SkuController { ...@@ -68,4 +61,11 @@ public class SkuController {
boolean result = skuService.deductStock(orderToken); boolean result = skuService.deductStock(orderToken);
return Result.judge(result); return Result.judge(result);
} }
@ApiOperation(value = "商品验价")
@PostMapping("/price/_check")
public Result<Boolean> checkPrice(@RequestBody CheckPriceDTO checkPriceDTO) {
boolean result = skuService.checkPrice(checkPriceDTO);
return Result.judge(result);
}
} }
...@@ -3,8 +3,8 @@ package com.youlai.mall.pms.controller.app; ...@@ -3,8 +3,8 @@ package com.youlai.mall.pms.controller.app;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.youlai.common.result.Result; import com.youlai.common.result.Result;
import com.youlai.mall.pms.pojo.query.SpuPageQuery; import com.youlai.mall.pms.pojo.query.SpuPageQuery;
import com.youlai.mall.pms.pojo.vo.AppSpuPageVO; import com.youlai.mall.pms.pojo.vo.GoodsPageVO;
import com.youlai.mall.pms.pojo.vo.AppSpuDetailVO; import com.youlai.mall.pms.pojo.vo.GoodsDetailVO;
import com.youlai.mall.pms.service.IPmsSpuService; import com.youlai.mall.pms.service.IPmsSpuService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
...@@ -27,18 +27,18 @@ public class SpuController { ...@@ -27,18 +27,18 @@ public class SpuController {
@ApiOperation(value = "商品分页列表") @ApiOperation(value = "商品分页列表")
@GetMapping("/page") @GetMapping("/page")
public Result<List<AppSpuPageVO>> listSpuWithPage(SpuPageQuery queryParams) { public Result<List<GoodsPageVO>> listGoodsWithPage(SpuPageQuery queryParams) {
IPage<AppSpuPageVO> result = iPmsSpuService.listAppSpuWithPage(queryParams); IPage<GoodsPageVO> result = iPmsSpuService.listAppSpuWithPage(queryParams);
return Result.success(result.getRecords(), result.getTotal()); return Result.success(result.getRecords(), result.getTotal());
} }
@ApiOperation(value = "获取商品详情") @ApiOperation(value = "获取商品详情")
@GetMapping("/{spuId}") @GetMapping("/{spuId}")
public Result<AppSpuDetailVO> getSpuDetail( public Result<GoodsDetailVO> getGoodsDetail(
@ApiParam("商品ID") @PathVariable Long spuId @ApiParam("商品ID") @PathVariable Long spuId
) { ) {
AppSpuDetailVO appSpuDetailVO = iPmsSpuService.getAppSpuDetail(spuId); GoodsDetailVO goodsDetailVO = iPmsSpuService.getAppSpuDetail(spuId);
return Result.success(appSpuDetailVO); return Result.success(goodsDetailVO);
} }
} }
...@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; ...@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.youlai.mall.pms.pojo.entity.PmsSpu; import com.youlai.mall.pms.pojo.entity.PmsSpu;
import com.youlai.mall.pms.pojo.query.SpuPageQuery; import com.youlai.mall.pms.pojo.query.SpuPageQuery;
import com.youlai.mall.pms.pojo.vo.AppSpuPageVO; import com.youlai.mall.pms.pojo.vo.GoodsPageVO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List; import java.util.List;
...@@ -25,7 +25,7 @@ public interface PmsSpuMapper extends BaseMapper<PmsSpu> { ...@@ -25,7 +25,7 @@ public interface PmsSpuMapper extends BaseMapper<PmsSpu> {
* @param queryParams * @param queryParams
* @return * @return
*/ */
List<AppSpuPageVO> listAppSpuWithPage(Page<AppSpuPageVO> page, SpuPageQuery queryParams); List<GoodsPageVO> listAppSpuWithPage(Page<GoodsPageVO> page, SpuPageQuery queryParams);
List<PmsSpu> list(Page<PmsSpu> page, String name, Long categoryId); List<PmsSpu> list(Page<PmsSpu> page, String name, Long categoryId);
......
...@@ -14,7 +14,7 @@ import java.util.List; ...@@ -14,7 +14,7 @@ import java.util.List;
*/ */
@Data @Data
@ApiModel("商品详情") @ApiModel("商品详情")
public class AppSpuDetailVO { public class GoodsDetailVO {
@ApiModelProperty("商品基本信息") @ApiModelProperty("商品基本信息")
private GoodsInfo goodsInfo; private GoodsInfo goodsInfo;
...@@ -103,7 +103,7 @@ public class AppSpuDetailVO { ...@@ -103,7 +103,7 @@ public class AppSpuDetailVO {
private Long price; private Long price;
@ApiModelProperty("库存") @ApiModelProperty("库存")
private Integer stock; private Integer stockNum;
@ApiModelProperty("商品图片URL") @ApiModelProperty("商品图片URL")
private String picUrl; private String picUrl;
......
...@@ -12,7 +12,7 @@ import lombok.Data; ...@@ -12,7 +12,7 @@ import lombok.Data;
*/ */
@ApiModel("商品分页对象") @ApiModel("商品分页对象")
@Data @Data
public class AppSpuPageVO { public class GoodsPageVO {
@ApiModelProperty("商品ID") @ApiModelProperty("商品ID")
private Long id; private Long id;
......
...@@ -2,6 +2,7 @@ package com.youlai.mall.pms.service; ...@@ -2,6 +2,7 @@ package com.youlai.mall.pms.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.youlai.common.result.Result; import com.youlai.common.result.Result;
import com.youlai.mall.pms.pojo.dto.CheckPriceDTO;
import com.youlai.mall.pms.pojo.dto.SkuInfoDTO; import com.youlai.mall.pms.pojo.dto.SkuInfoDTO;
import com.youlai.mall.pms.pojo.entity.PmsSku; import com.youlai.mall.pms.pojo.entity.PmsSku;
import com.youlai.mall.pms.pojo.dto.app.LockStockDTO; import com.youlai.mall.pms.pojo.dto.app.LockStockDTO;
...@@ -54,5 +55,11 @@ public interface IPmsSkuService extends IService<PmsSku> { ...@@ -54,5 +55,11 @@ public interface IPmsSkuService extends IService<PmsSku> {
boolean deductStock(String orderToken); boolean deductStock(String orderToken);
/**
* 商品验价
*
* @param checkPriceDTO
* @return
*/
boolean checkPrice(CheckPriceDTO checkPriceDTO);
} }
...@@ -6,9 +6,8 @@ import com.baomidou.mybatisplus.extension.service.IService; ...@@ -6,9 +6,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.youlai.mall.pms.pojo.dto.admin.GoodsFormDTO; import com.youlai.mall.pms.pojo.dto.admin.GoodsFormDTO;
import com.youlai.mall.pms.pojo.entity.PmsSpu; import com.youlai.mall.pms.pojo.entity.PmsSpu;
import com.youlai.mall.pms.pojo.query.SpuPageQuery; import com.youlai.mall.pms.pojo.query.SpuPageQuery;
import com.youlai.mall.pms.pojo.vo.AppSpuDetailVO; import com.youlai.mall.pms.pojo.vo.GoodsDetailVO;
import com.youlai.mall.pms.pojo.vo.AppSpuPageVO; import com.youlai.mall.pms.pojo.vo.GoodsPageVO;
import com.youlai.mall.pms.pojo.vo.admin.GoodsDetailVO;
import java.util.List; import java.util.List;
...@@ -26,7 +25,7 @@ public interface IPmsSpuService extends IService<PmsSpu> { ...@@ -26,7 +25,7 @@ public interface IPmsSpuService extends IService<PmsSpu> {
* @param queryParams * @param queryParams
* @return * @return
*/ */
IPage<AppSpuPageVO> listAppSpuWithPage(SpuPageQuery queryParams); IPage<GoodsPageVO> listAppSpuWithPage(SpuPageQuery queryParams);
/** /**
...@@ -35,7 +34,7 @@ public interface IPmsSpuService extends IService<PmsSpu> { ...@@ -35,7 +34,7 @@ public interface IPmsSpuService extends IService<PmsSpu> {
* @param spuId * @param spuId
* @return * @return
*/ */
AppSpuDetailVO getAppSpuDetail(Long spuId); GoodsDetailVO getAppSpuDetail(Long spuId);
/** /**
...@@ -43,7 +42,7 @@ public interface IPmsSpuService extends IService<PmsSpu> { ...@@ -43,7 +42,7 @@ public interface IPmsSpuService extends IService<PmsSpu> {
* @param id * @param id
* @return * @return
*/ */
GoodsDetailVO getGoodsById(Long id); com.youlai.mall.pms.pojo.vo.admin.GoodsDetailVO getGoodsById(Long id);
IPage<PmsSpu> list(Page<PmsSpu> page, String name,Long categoryId); IPage<PmsSpu> list(Page<PmsSpu> page, String name,Long categoryId);
......
...@@ -10,6 +10,7 @@ import com.youlai.common.result.Result; ...@@ -10,6 +10,7 @@ import com.youlai.common.result.Result;
import com.youlai.common.web.exception.BizException; import com.youlai.common.web.exception.BizException;
import com.youlai.mall.pms.common.constant.PmsConstants; import com.youlai.mall.pms.common.constant.PmsConstants;
import com.youlai.mall.pms.mapper.PmsSkuMapper; import com.youlai.mall.pms.mapper.PmsSkuMapper;
import com.youlai.mall.pms.pojo.dto.CheckPriceDTO;
import com.youlai.mall.pms.pojo.dto.SkuInfoDTO; import com.youlai.mall.pms.pojo.dto.SkuInfoDTO;
import com.youlai.mall.pms.pojo.dto.app.LockStockDTO; import com.youlai.mall.pms.pojo.dto.app.LockStockDTO;
import com.youlai.mall.pms.pojo.entity.PmsSku; import com.youlai.mall.pms.pojo.entity.PmsSku;
...@@ -159,6 +160,37 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme ...@@ -159,6 +160,37 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
return true; return true;
} }
/**
* 商品验价
*
* @param checkPriceDTO
* @return
*/
@Override
public boolean checkPrice(CheckPriceDTO checkPriceDTO) {
Long orderTotalAmount = checkPriceDTO.getOrderTotalAmount(); // 订单总金额
// 计算商品总金额
List<CheckPriceDTO.CheckSku> checkOrderItems = checkPriceDTO.getCheckSkus();
if (CollectionUtil.isNotEmpty(checkOrderItems)) {
List<Long> skuIds = checkOrderItems.stream()
.map(orderItem -> orderItem.getSkuId()).collect(Collectors.toList());
List<PmsSku> skuList = this.list(new LambdaQueryWrapper<PmsSku>().in(PmsSku::getId, skuIds)
.select(PmsSku::getId, PmsSku::getPrice));
// 商品总金额
Long skuTotalAmount = checkOrderItems.stream().map(checkOrderItem -> {
Long skuId = checkOrderItem.getSkuId();
PmsSku pmsSku = skuList.stream().filter(sku -> sku.getId().equals(skuId)).findFirst().orElse(null);
if (pmsSku != null) {
return pmsSku.getPrice() * checkOrderItem.getCount();
}
return 0L;
}).reduce(0L, Long::sum);
return orderTotalAmount.compareTo(skuTotalAmount) == 0;
}
return false;
}
/** /**
* 获取商品库存信息 * 获取商品库存信息
...@@ -168,20 +200,9 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme ...@@ -168,20 +200,9 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
*/ */
@Override @Override
public SkuInfoDTO getSkuInfo(Long skuId) { public SkuInfoDTO getSkuInfo(Long skuId) {
SkuInfoDTO skuInfo= this.baseMapper.getSkuInfo(skuId); SkuInfoDTO skuInfo = this.baseMapper.getSkuInfo(skuId);
return skuInfo; return skuInfo;
} }
/* private final SeataTccSkuService seataTccSkuService;
@Override
@GlobalTransactional
public Boolean lockStockTcc(List<LockStockDTO> skuLockList) {
seataTccSkuService.prepareSkuLockList(null, skuLockList);
String orderToken = skuLockList.get(0).getOrderToken();
redisTemplate.opsForValue().set(PmsConstants.LOCKED_STOCK_PREFIX + orderToken, JSONUtil.toJsonStr(skuLockList));
return true;
}*/
} }
...@@ -18,10 +18,9 @@ import com.youlai.mall.pms.pojo.entity.PmsSku; ...@@ -18,10 +18,9 @@ import com.youlai.mall.pms.pojo.entity.PmsSku;
import com.youlai.mall.pms.pojo.entity.PmsSpu; import com.youlai.mall.pms.pojo.entity.PmsSpu;
import com.youlai.mall.pms.pojo.entity.PmsSpuAttributeValue; import com.youlai.mall.pms.pojo.entity.PmsSpuAttributeValue;
import com.youlai.mall.pms.pojo.query.SpuPageQuery; import com.youlai.mall.pms.pojo.query.SpuPageQuery;
import com.youlai.mall.pms.pojo.vo.AppSpuDetailVO; import com.youlai.mall.pms.pojo.vo.GoodsDetailVO;
import com.youlai.mall.pms.pojo.vo.AppSpuPageVO; import com.youlai.mall.pms.pojo.vo.GoodsPageVO;
import com.youlai.mall.pms.pojo.vo.ProductHistoryVO; import com.youlai.mall.pms.pojo.vo.ProductHistoryVO;
import com.youlai.mall.pms.pojo.vo.admin.GoodsDetailVO;
import com.youlai.mall.pms.service.IPmsSkuService; import com.youlai.mall.pms.service.IPmsSkuService;
import com.youlai.mall.pms.service.IPmsSpuAttributeValueService; import com.youlai.mall.pms.service.IPmsSpuAttributeValueService;
import com.youlai.mall.pms.service.IPmsSpuService; import com.youlai.mall.pms.service.IPmsSpuService;
...@@ -55,9 +54,9 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme ...@@ -55,9 +54,9 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
* @return * @return
*/ */
@Override @Override
public IPage<AppSpuPageVO> listAppSpuWithPage(SpuPageQuery queryParams) { public IPage<GoodsPageVO> listAppSpuWithPage(SpuPageQuery queryParams) {
Page<AppSpuPageVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize()); Page<GoodsPageVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
List<AppSpuPageVO> list = this.baseMapper.listAppSpuWithPage(page, queryParams); List<GoodsPageVO> list = this.baseMapper.listAppSpuWithPage(page, queryParams);
page.setRecords(list); page.setRecords(list);
return page; return page;
} }
...@@ -69,14 +68,14 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme ...@@ -69,14 +68,14 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
* @return * @return
*/ */
@Override @Override
public AppSpuDetailVO getAppSpuDetail(Long spuId) { public GoodsDetailVO getAppSpuDetail(Long spuId) {
PmsSpu pmsSpu = this.getById(spuId); PmsSpu pmsSpu = this.getById(spuId);
Assert.isTrue(pmsSpu != null, "商品不存在"); Assert.isTrue(pmsSpu != null, "商品不存在");
AppSpuDetailVO appSpuDetailVO = new AppSpuDetailVO(); GoodsDetailVO goodsDetailVO = new GoodsDetailVO();
// 商品基本信息 // 商品基本信息
AppSpuDetailVO.GoodsInfo goodsInfo = new AppSpuDetailVO.GoodsInfo(); GoodsDetailVO.GoodsInfo goodsInfo = new GoodsDetailVO.GoodsInfo();
BeanUtil.copyProperties(pmsSpu, goodsInfo, "album"); BeanUtil.copyProperties(pmsSpu, goodsInfo, "album");
List<String> album = new ArrayList<>(); List<String> album = new ArrayList<>();
...@@ -88,19 +87,19 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme ...@@ -88,19 +87,19 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
album.addAll(Arrays.asList(pmsSpu.getAlbum())); album.addAll(Arrays.asList(pmsSpu.getAlbum()));
goodsInfo.setAlbum(album); goodsInfo.setAlbum(album);
} }
appSpuDetailVO.setGoodsInfo(goodsInfo); goodsDetailVO.setGoodsInfo(goodsInfo);
// 商品属性列表 // 商品属性列表
List<AppSpuDetailVO.Attribute> attributeList = spuAttributeValueService.list(new LambdaQueryWrapper<PmsSpuAttributeValue>() List<GoodsDetailVO.Attribute> attributeList = spuAttributeValueService.list(new LambdaQueryWrapper<PmsSpuAttributeValue>()
.eq(PmsSpuAttributeValue::getType, AttributeTypeEnum.ATTRIBUTE.getValue()) .eq(PmsSpuAttributeValue::getType, AttributeTypeEnum.ATTRIBUTE.getValue())
.eq(PmsSpuAttributeValue::getSpuId, spuId) .eq(PmsSpuAttributeValue::getSpuId, spuId)
.select(PmsSpuAttributeValue::getId, PmsSpuAttributeValue::getName, PmsSpuAttributeValue::getValue) .select(PmsSpuAttributeValue::getId, PmsSpuAttributeValue::getName, PmsSpuAttributeValue::getValue)
).stream().map(item -> { ).stream().map(item -> {
AppSpuDetailVO.Attribute attribute = new AppSpuDetailVO.Attribute(); GoodsDetailVO.Attribute attribute = new GoodsDetailVO.Attribute();
BeanUtil.copyProperties(item, attribute); BeanUtil.copyProperties(item, attribute);
return attribute; return attribute;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
appSpuDetailVO.setAttributeList(attributeList); goodsDetailVO.setAttributeList(attributeList);
// 商品规格列表 // 商品规格列表
...@@ -110,7 +109,7 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme ...@@ -110,7 +109,7 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
.select(PmsSpuAttributeValue::getId, PmsSpuAttributeValue::getName, PmsSpuAttributeValue::getValue) .select(PmsSpuAttributeValue::getId, PmsSpuAttributeValue::getName, PmsSpuAttributeValue::getValue)
); );
List<AppSpuDetailVO.Specification> specList = new ArrayList<>(); List<GoodsDetailVO.Specification> specList = new ArrayList<>();
// 规格Map [key:"颜色",value:[{id:1,value:"黑"},{id:2,value:"白"}]] // 规格Map [key:"颜色",value:[{id:1,value:"黑"},{id:2,value:"白"}]]
Map<String, List<PmsSpuAttributeValue>> specValueMap = specSourceList.stream() Map<String, List<PmsSpuAttributeValue>> specValueMap = specSourceList.stream()
.collect(Collectors.groupingBy(PmsSpuAttributeValue::getName)); .collect(Collectors.groupingBy(PmsSpuAttributeValue::getName));
...@@ -120,11 +119,11 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme ...@@ -120,11 +119,11 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
List<PmsSpuAttributeValue> specValueSourceList = entry.getValue(); List<PmsSpuAttributeValue> specValueSourceList = entry.getValue();
// 规格映射处理 // 规格映射处理
AppSpuDetailVO.Specification spec = new AppSpuDetailVO.Specification(); GoodsDetailVO.Specification spec = new GoodsDetailVO.Specification();
spec.setName(specName); spec.setName(specName);
if (CollectionUtil.isNotEmpty(specValueSourceList)) { if (CollectionUtil.isNotEmpty(specValueSourceList)) {
List<AppSpuDetailVO.Specification.Value> specValueList = specValueSourceList.stream().map(item -> { List<GoodsDetailVO.Specification.Value> specValueList = specValueSourceList.stream().map(item -> {
AppSpuDetailVO.Specification.Value specValue = new AppSpuDetailVO.Specification.Value(); GoodsDetailVO.Specification.Value specValue = new GoodsDetailVO.Specification.Value();
specValue.setId(item.getId()); specValue.setId(item.getId());
specValue.setValue(item.getValue()); specValue.setValue(item.getValue());
return specValue; return specValue;
...@@ -133,16 +132,17 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme ...@@ -133,16 +132,17 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
specList.add(spec); specList.add(spec);
} }
} }
appSpuDetailVO.setSpecList(specList); goodsDetailVO.setSpecList(specList);
// 商品SKU列表 // 商品SKU列表
List<PmsSku> skuSourceList = skuService.list(new LambdaQueryWrapper<PmsSku>().eq(PmsSku::getSpuId, spuId)); List<PmsSku> skuSourceList = skuService.list(new LambdaQueryWrapper<PmsSku>().eq(PmsSku::getSpuId, spuId));
if (CollectionUtil.isNotEmpty(skuSourceList)) { if (CollectionUtil.isNotEmpty(skuSourceList)) {
List<AppSpuDetailVO.Sku> skuList = skuSourceList.stream().map(item -> { List<GoodsDetailVO.Sku> skuList = skuSourceList.stream().map(item -> {
AppSpuDetailVO.Sku sku = new AppSpuDetailVO.Sku(); GoodsDetailVO.Sku sku = new GoodsDetailVO.Sku();
BeanUtil.copyProperties(item, sku); BeanUtil.copyProperties(item, sku);
return sku; return sku;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
appSpuDetailVO.setSkuList(skuList); goodsDetailVO.setSkuList(skuList);
} }
// 添加用户浏览历史记录 // 添加用户浏览历史记录
...@@ -154,7 +154,7 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme ...@@ -154,7 +154,7 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
vo.setPicUrl(goodsInfo.getAlbum() != null ? goodsInfo.getAlbum().get(0) : null); vo.setPicUrl(goodsInfo.getAlbum() != null ? goodsInfo.getAlbum().get(0) : null);
memberFeignClient.addProductViewHistory(vo); memberFeignClient.addProductViewHistory(vo);
} }
return appSpuDetailVO; return goodsDetailVO;
} }
...@@ -165,8 +165,8 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme ...@@ -165,8 +165,8 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
* @return * @return
*/ */
@Override @Override
public GoodsDetailVO getGoodsById(Long id) { public com.youlai.mall.pms.pojo.vo.admin.GoodsDetailVO getGoodsById(Long id) {
GoodsDetailVO goodsDetailVO = new GoodsDetailVO(); com.youlai.mall.pms.pojo.vo.admin.GoodsDetailVO goodsDetailVO = new com.youlai.mall.pms.pojo.vo.admin.GoodsDetailVO();
PmsSpu spu = this.getById(id); PmsSpu spu = this.getById(id);
Assert.isTrue(spu != null, "商品不存在"); Assert.isTrue(spu != null, "商品不存在");
......
...@@ -68,7 +68,7 @@ public class SeataTccSkuServiceImpl implements SeataTccSkuService { ...@@ -68,7 +68,7 @@ public class SeataTccSkuServiceImpl implements SeataTccSkuService {
); );
// 提示订单哪些商品库存不足 // 提示订单哪些商品库存不足
List<Long> ids = unlockSkuList.stream().map(LockStockDTO::getSkuId).collect(Collectors.toList()); List<Long> ids = unlockSkuList.stream().map(LockStockDTO::getSkuId).collect(Collectors.toList());
throw new BizException("商品" + ids.toString() + "库存不足"); throw new BizException("商品" + ids + "库存不足");
} }
IdempotentUtil.addMarker(getClass(), businessActionContext.getXid(), System.currentTimeMillis()); IdempotentUtil.addMarker(getClass(), businessActionContext.getXid(), System.currentTimeMillis());
return true; return true;
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
<!--「移动端」商品分页列表--> <!--「移动端」商品分页列表-->
<select id="listAppSpuWithPage" resultType="com.youlai.mall.pms.pojo.vo.AppSpuPageVO"> <select id="listAppSpuWithPage" resultType="com.youlai.mall.pms.pojo.vo.GoodsPageVO">
SELECT SELECT
id, id,
NAME, NAME,
......
package com.youlai.mall.sms.pojo.to; package com.youlai.mall.sms.pojo.to;
import com.youlai.mall.pms.pojo.dto.SkuInfoDTO;
import lombok.Data; import lombok.Data;
import lombok.ToString; import lombok.ToString;
/** /**
* 秒杀商品Redis存储
*
* @author huawei * @author huawei
* @desc 秒杀商品Redis存储 TO
* @email huawei_code@163.com * @email huawei_code@163.com
* @date 2021/3/7 * @date 2021/3/7
*/ */
...@@ -65,6 +67,6 @@ public class SeckillSkuRedisTO { ...@@ -65,6 +67,6 @@ public class SeckillSkuRedisTO {
/** /**
* 秒杀商品详情 * 秒杀商品详情
*/ */
private AppSkuDetailVO skuInfo; private SkuInfoDTO skuInfo;
} }
package com.youlai.mall.sms.pojo.vo; package com.youlai.mall.sms.pojo.vo;
import com.youlai.mall.pms.pojo.dto.SkuInfoDTO;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
...@@ -68,5 +69,5 @@ public class SmsSeckillSkuVO { ...@@ -68,5 +69,5 @@ public class SmsSeckillSkuVO {
/** /**
* 秒杀商品详情 * 秒杀商品详情
*/ */
private AppSkuDetailVO skuInfo; private SkuInfoDTO skuInfo;
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册