mirror of
https://gitee.com/youlaitech/youlai-mall.git
synced 2024-12-22 12:48:59 +08:00
refactor: 订单重构优化
This commit is contained in:
parent
054697e11a
commit
8a0e33b8cc
@ -1,7 +1,7 @@
|
||||
package com.youlai.mall.oms;
|
||||
|
||||
import com.youlai.mall.pms.api.SkuFeignClient;
|
||||
import com.youlai.mall.ums.api.MemberFeignClient;
|
||||
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
@ -11,8 +11,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
|
||||
@EnableDiscoveryClient
|
||||
@EnableFeignClients(basePackageClasses = { MemberFeignClient.class, GoodsFeignClient.class})
|
||||
@EnableRabbit
|
||||
@EnableFeignClients(basePackageClasses = { MemberFeignClient.class, SkuFeignClient.class})
|
||||
@EnableTransactionManagement
|
||||
public class OmsApplication {
|
||||
|
||||
|
@ -7,7 +7,7 @@ import com.youlai.common.result.Result;
|
||||
import com.youlai.common.web.util.JwtUtils;
|
||||
import com.youlai.mall.oms.enums.PayTypeEnum;
|
||||
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.query.OrderPageQuery;
|
||||
import com.youlai.mall.oms.pojo.vo.OrderConfirmVO;
|
||||
@ -59,8 +59,8 @@ public class OrderController {
|
||||
|
||||
@ApiOperation("订单提交")
|
||||
@PostMapping("/_submit")
|
||||
public Result submit(@Valid @RequestBody OrderSubmitDTO orderSubmitDTO) {
|
||||
OrderSubmitVO result = orderService.submit(orderSubmitDTO);
|
||||
public Result submit(@Valid @RequestBody OrderSubmitForm orderSubmitForm) {
|
||||
OrderSubmitVO result = orderService.submit(orderSubmitForm);
|
||||
return Result.success(result);
|
||||
}
|
||||
|
||||
|
@ -12,13 +12,15 @@ import org.springframework.stereotype.Component;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author hxr
|
||||
* @date 2021-03-16
|
||||
* 订单超时取消
|
||||
*
|
||||
* @author haoxr
|
||||
* @date 2021/3/16
|
||||
*/
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class OrderListener {
|
||||
|
||||
private final IOrderService orderService;
|
||||
|
@ -7,40 +7,47 @@ import java.io.Serializable;
|
||||
/**
|
||||
* 购物车商品传输层实体
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
@Builder
|
||||
@Data
|
||||
public class CartItemDTO implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 商品库存ID
|
||||
*/
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 商品库存单元名称
|
||||
* 商品库存名称
|
||||
*/
|
||||
private String skuName;
|
||||
|
||||
/**
|
||||
* 商品库存单元编码
|
||||
* 商品编码
|
||||
*/
|
||||
private String skuSn;
|
||||
|
||||
/**
|
||||
* 商品库存单元图片
|
||||
* 商品图片
|
||||
*/
|
||||
private String picUrl;
|
||||
|
||||
private Integer count; // 商品数量
|
||||
/**
|
||||
* 商品数量
|
||||
*/
|
||||
private Integer count;
|
||||
|
||||
/**
|
||||
* 加入购物车价格,因会变动,不能作为订单计算因子,订单验价时需重新获取商品价格即可
|
||||
* 加入购物车时价格,因会变动,不能作为订单计算因子,订单提交时需验价
|
||||
*/
|
||||
private Long price;
|
||||
|
||||
/**
|
||||
* 优惠券金额
|
||||
*/
|
||||
private Long coupon;
|
||||
|
||||
/**
|
||||
* 是否选中
|
||||
*/
|
||||
private Boolean checked;
|
||||
|
||||
/**
|
||||
@ -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;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.youlai.common.base.BaseEntity;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
@ -18,17 +15,13 @@ import lombok.experimental.Accessors;
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class OmsOrderItem extends BaseEntity {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* order_id
|
||||
* 订单ID
|
||||
*/
|
||||
private Long orderId;
|
||||
/**
|
||||
@ -38,57 +31,36 @@ public class OmsOrderItem extends BaseEntity {
|
||||
/**
|
||||
* 商品sku编号
|
||||
*/
|
||||
private String skuCode;
|
||||
|
||||
private String skuSn;
|
||||
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
private String skuName;
|
||||
|
||||
/**
|
||||
* 商品sku图片
|
||||
*/
|
||||
private String skuPic;
|
||||
private String picUrl;
|
||||
|
||||
/**
|
||||
* 商品sku价格(分)
|
||||
* 商品单价(单位:分)
|
||||
*/
|
||||
private Long skuPrice;
|
||||
private Long price;
|
||||
|
||||
/**
|
||||
* 商品购买的数量
|
||||
* 商品数量
|
||||
*/
|
||||
private Integer skuQuantity;
|
||||
private Integer count;
|
||||
|
||||
/**
|
||||
* 商品sku总价格(分)
|
||||
* 商品总金额(单位:分)
|
||||
*/
|
||||
private Long skuTotalPrice;
|
||||
private Long totalAmount;
|
||||
|
||||
|
||||
/**
|
||||
* spu_id
|
||||
*/
|
||||
private Long spuId;
|
||||
/**
|
||||
* spu_name
|
||||
*/
|
||||
private String spuName;
|
||||
/**
|
||||
* spu_pic
|
||||
*/
|
||||
private String spuPic;
|
||||
/**
|
||||
* 品牌id
|
||||
*/
|
||||
private Long brandId;
|
||||
/**
|
||||
* 品牌名称
|
||||
*/
|
||||
private String brandName;
|
||||
/**
|
||||
* 商品分类id
|
||||
*/
|
||||
private Long categoryId;
|
||||
/**
|
||||
* 商品分类名称
|
||||
*/
|
||||
private String categoryName;
|
||||
/**
|
||||
* 逻辑删除【0->正常;1->已删除】
|
||||
* 逻辑删除(0:正常;1:已删除)
|
||||
*/
|
||||
private Integer deleted;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
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 lombok.Data;
|
||||
|
||||
@ -7,30 +8,51 @@ import javax.validation.constraints.Size;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 订单提交表单对象
|
||||
*
|
||||
* @author huawei
|
||||
* @desc 订单提交
|
||||
* @email huawei_code@163.com
|
||||
* @date 2021/1/16
|
||||
*/
|
||||
@Data
|
||||
public class OrderSubmitDTO {
|
||||
public class OrderSubmitForm {
|
||||
|
||||
// 提交订单确认页面签发的令牌
|
||||
/**
|
||||
* 提交订单确认页面签发的令牌
|
||||
*/
|
||||
private String orderToken;
|
||||
|
||||
/**
|
||||
* 订单总金额-用于验价(单位:分)
|
||||
*/
|
||||
private Long totalAmount;
|
||||
|
||||
|
||||
/**
|
||||
* 支付金额(单位:分)
|
||||
*/
|
||||
private Long payAmount;
|
||||
|
||||
/**
|
||||
* 订单的商品明细
|
||||
*/
|
||||
private List<OrderItemDTO> orderItems;
|
||||
|
||||
// 验价前台传值
|
||||
private Long totalPrice;
|
||||
|
||||
// 收货地址
|
||||
private UmsAddress deliveryAddress;
|
||||
|
||||
|
||||
@Size(max = 500, message = "订单备注长度不能超过500")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 优惠券ID
|
||||
*/
|
||||
private String couponId;
|
||||
|
||||
private Long payAmount;
|
||||
|
||||
/**
|
||||
* 收获地址
|
||||
*/
|
||||
private UmsAddress deliveryAddress;
|
||||
|
||||
}
|
@ -9,7 +9,7 @@ import java.util.List;
|
||||
|
||||
|
||||
@Data
|
||||
public class OrderConfirmVO extends BaseVO {
|
||||
public class OrderConfirmVO {
|
||||
|
||||
private String orderToken;
|
||||
|
||||
|
@ -1,16 +1,17 @@
|
||||
package com.youlai.mall.oms.pojo.vo;
|
||||
|
||||
import com.youlai.common.base.BaseVO;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 订单创建响应视图对象
|
||||
*
|
||||
* @author huawei
|
||||
* @desc 订单创建响应结果VO
|
||||
* @email huawei_code@163.com
|
||||
* @date 2021/1/21
|
||||
*/
|
||||
@Data
|
||||
public class OrderSubmitVO extends BaseVO {
|
||||
public class OrderSubmitVO {
|
||||
|
||||
/**
|
||||
* 订单ID
|
||||
*/
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.youlai.mall.oms.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
|
||||
@ -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.vo.OrderConfirmVO;
|
||||
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> {
|
||||
/**
|
||||
* 订单提交
|
||||
*/
|
||||
OrderSubmitVO submit(OrderSubmitDTO orderSubmitDTO) ;
|
||||
|
||||
/**
|
||||
* 订单提交
|
||||
*/
|
||||
OrderSubmitVO submitTcc(OrderSubmitDTO orderSubmitDTO) ;
|
||||
OrderSubmitVO submit(OrderSubmitForm orderSubmitForm) ;
|
||||
|
||||
/**
|
||||
* 订单支付
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.youlai.mall.oms.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.youlai.common.result.ResultCode;
|
||||
import com.youlai.common.web.exception.BizException;
|
||||
@ -7,8 +8,12 @@ import com.youlai.common.web.util.JwtUtils;
|
||||
import com.youlai.mall.oms.constant.OmsConstants;
|
||||
import com.youlai.mall.oms.pojo.dto.CartItemDTO;
|
||||
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.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.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -33,7 +38,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
public class CartServiceImpl implements ICartService {
|
||||
|
||||
private RedisTemplate redisTemplate;
|
||||
private GoodsFeignClient skuFeignService;
|
||||
private SkuFeignClient skuFeignService;
|
||||
|
||||
@Override
|
||||
public List<CartItemDTO> listCartItemByMemberId(Long memberId) {
|
||||
@ -78,22 +83,16 @@ public class CartServiceImpl implements ICartService {
|
||||
// 购物车不存在该商品,添加商品至购物车
|
||||
cartItem = new CartItemDTO();
|
||||
CompletableFuture<Void> cartItemCompletableFuture = CompletableFuture.runAsync(() -> {
|
||||
AppSkuDetailVO sku = skuFeignService.getSkuById(skuId).getData();
|
||||
if (sku != null) {
|
||||
cartItem.setSkuId(sku.getId());
|
||||
SkuInfoDTO skuInfo = skuFeignService.getSkuInfo(skuId).getData();
|
||||
if (skuInfo != null) {
|
||||
BeanUtil.copyProperties(skuInfo,cartItem);
|
||||
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);
|
||||
}
|
||||
});
|
||||
CompletableFuture.allOf(cartItemCompletableFuture).join();
|
||||
|
||||
Assert.isTrue(cartItem.getSkuId() != null && cartItem.getSkuId() > 0,"商品不存在");
|
||||
Assert.isTrue(cartItem.getSkuId() != null,"商品不存在");
|
||||
cartHashOperations.put(hKey, cartItem);
|
||||
return true;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
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.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
@ -29,20 +30,20 @@ import com.youlai.mall.oms.enums.OrderStatusEnum;
|
||||
import com.youlai.mall.oms.enums.OrderTypeEnum;
|
||||
import com.youlai.mall.oms.enums.PayTypeEnum;
|
||||
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.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.OmsOrderItem;
|
||||
import com.youlai.mall.oms.pojo.form.OrderSubmitForm;
|
||||
import com.youlai.mall.oms.pojo.query.OrderPageQuery;
|
||||
import com.youlai.mall.oms.pojo.vo.OrderConfirmVO;
|
||||
import com.youlai.mall.oms.pojo.vo.OrderSubmitVO;
|
||||
import com.youlai.mall.oms.service.ICartService;
|
||||
import com.youlai.mall.oms.service.IOrderItemService;
|
||||
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.pojo.dto.CheckPriceDTO;
|
||||
import com.youlai.mall.pms.pojo.dto.SkuInfoDTO;
|
||||
import com.youlai.mall.pms.pojo.dto.app.LockStockDTO;
|
||||
import com.youlai.mall.ums.api.MemberAddressFeignClient;
|
||||
@ -52,7 +53,6 @@ import com.youlai.mall.ums.pojo.entity.UmsMember;
|
||||
import io.seata.spring.annotation.GlobalTransactional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.redisson.api.RLock;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
@ -87,16 +87,29 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
||||
private final MemberFeignClient memberFeignClient;
|
||||
private final BusinessNoGenerator businessNoGenerator;
|
||||
private final SkuFeignClient skuFeignClient;
|
||||
private final SeataTccOrderService seataTccOrderService;
|
||||
private final RedissonClient redissonClient;
|
||||
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
|
||||
public OrderConfirmVO confirm(OrderConfirmDTO orderConfirmDTO) {
|
||||
log.info("=======================订单确认=======================\n订单确认信息:{}", orderConfirmDTO);
|
||||
log.info("订单确认:{}", orderConfirmDTO);
|
||||
OrderConfirmVO orderConfirmVO = new OrderConfirmVO();
|
||||
Long memberId = JwtUtils.getUserId();
|
||||
|
||||
@ -104,14 +117,14 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
||||
CompletableFuture<Void> orderItemsCompletableFuture = CompletableFuture.runAsync(() -> {
|
||||
List<OrderItemDTO> orderItems = new ArrayList<>();
|
||||
Long skuId = orderConfirmDTO.getSkuId();
|
||||
if (skuId != null) { // 直接购买商品
|
||||
if (skuId != null) { // 直接购买
|
||||
Result<SkuInfoDTO> getSkuInfoResult = skuFeignClient.getSkuInfo(orderConfirmDTO.getSkuId());
|
||||
Assert.isTrue(Result.isSuccess(getSkuInfoResult), "获取商品信息失败");
|
||||
SkuInfoDTO skuInfoDTO = getSkuInfoResult.getData();
|
||||
OrderItemDTO orderItemDTO = new OrderItemDTO();
|
||||
BeanUtil.copyProperties(skuInfoDTO, orderItemDTO);
|
||||
orderItems.add(orderItemDTO);
|
||||
} else { // 购物车中商品结算
|
||||
} else { // 购物车结算
|
||||
List<CartItemDTO> cartItems = cartService.listCartItemByMemberId(memberId);
|
||||
List<OrderItemDTO> items = cartItems.stream()
|
||||
.filter(CartItemDTO::getChecked)
|
||||
@ -149,142 +162,74 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
||||
*/
|
||||
@Override
|
||||
@GlobalTransactional
|
||||
public OrderSubmitVO submit(OrderSubmitDTO submitDTO) {
|
||||
log.info("=======================订单提交=======================\n订单提交信息:{}", submitDTO);
|
||||
public OrderSubmitVO submit(OrderSubmitForm orderSubmitForm) {
|
||||
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);
|
||||
Long execute = this.redisTemplate.execute(redisScript, Collections.singletonList(ORDER_TOKEN_PREFIX + orderToken), orderToken);
|
||||
Assert.isTrue(execute.equals(1l), "订单不可重复提交");
|
||||
|
||||
List<OrderItemDTO> orderItems = submitDTO.getOrderItems();
|
||||
Assert.isTrue(CollectionUtil.isNotEmpty(orderItems), "订单商品为空");
|
||||
|
||||
// 订单验价
|
||||
Long currentTotalPrice = orderItems.stream().map(item -> {
|
||||
SkuInfoDTO sku = skuFeignClient.getSkuInfo(item.getSkuId()).getData();
|
||||
if (sku != null) {
|
||||
return sku.getPrice() * item.getCount();
|
||||
}
|
||||
return 0L;
|
||||
}).reduce(0L, Long::sum);
|
||||
Long orderTotalAmount = orderSubmitForm.getTotalAmount();
|
||||
boolean checkResult = checkOrderPrice(orderTotalAmount, orderItems);
|
||||
Assert.isTrue(checkResult, "当前页面已过期,请重新刷新页面再提交");
|
||||
|
||||
Assert.isTrue(currentTotalPrice.compareTo(submitDTO.getTotalPrice()) == 0, "当前页面已过期,请重新刷新页面再提交");
|
||||
|
||||
// 校验库存是否足够和锁库存
|
||||
// 锁定库存
|
||||
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);
|
||||
Assert.isTrue(Result.isSuccess(lockResult), "锁定商品库存失败:{}", lockResult.getMsg());
|
||||
|
||||
// 创建订单(状态:待支付)
|
||||
OmsOrder order = new OmsOrder();
|
||||
order.setOrderSn(orderToken) // 把orderToken赋值给订单编号【!】
|
||||
// 创建订单
|
||||
OmsOrder order = new OmsOrder().setOrderSn(orderToken) // 把orderToken赋值给订单编号
|
||||
.setStatus(OrderStatusEnum.PENDING_PAYMENT.getCode())
|
||||
.setSourceType(OrderTypeEnum.APP.getCode())
|
||||
.setMemberId(JwtUtils.getUserId())
|
||||
.setRemark(submitDTO.getRemark())
|
||||
.setPayAmount(submitDTO.getPayAmount())
|
||||
.setRemark(orderSubmitForm.getRemark())
|
||||
.setPayAmount(orderSubmitForm.getPayAmount())
|
||||
.setTotalQuantity(orderItems.stream().map(OrderItemDTO::getCount).reduce(0, Integer::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)
|
||||
public OrderSubmitVO submitTcc(OrderSubmitDTO submitDTO) {
|
||||
log.info("=======================订单提交=======================\n订单提交信息:{}", submitDTO);
|
||||
// 订单重复提交校验
|
||||
String orderToken = submitDTO.getOrderToken();
|
||||
// DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(RELEASE_LOCK_LUA_SCRIPT, Long.class);
|
||||
// Long result = this.redisTemplate.execute(redisScript, Collections.singletonList(ORDER_TOKEN_PREFIX + orderToken), orderToken);
|
||||
//
|
||||
// if (!ObjectUtil.equals(result, RELEASE_LOCK_SUCCESS_RESULT)) {
|
||||
// throw new BizException("订单不可重复提交");
|
||||
// }
|
||||
|
||||
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();
|
||||
// 添加订单明细
|
||||
if (result) {
|
||||
List<OmsOrderItem> orderItemList = orderItems.stream().map(orderFormItem -> {
|
||||
OmsOrderItem omsOrderItem = new OmsOrderItem();
|
||||
BeanUtil.copyProperties(orderFormItem, omsOrderItem);
|
||||
omsOrderItem.setOrderId(order.getId());
|
||||
omsOrderItem.setTotalAmount(orderFormItem.getPrice() * orderFormItem.getCount());
|
||||
return omsOrderItem;
|
||||
}).collect(Collectors.toList());
|
||||
result = orderItemService.saveBatch(orderItemList);
|
||||
if (result) {
|
||||
// 订单超时取消
|
||||
rabbitTemplate.convertAndSend("order.exchange", "order.create", orderToken);
|
||||
}
|
||||
return 0L;
|
||||
}).reduce(0L, Long::sum);
|
||||
|
||||
if (currentTotalPrice.compareTo(submitDTO.getTotalPrice()) != 0) {
|
||||
throw new BizException("页面已过期,请重新刷新页面再提交");
|
||||
}
|
||||
Assert.isTrue(result, "订单提交失败");
|
||||
|
||||
// 校验库存是否足够和锁库存
|
||||
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模式创建订单(状态:待支付)
|
||||
OmsOrder order = seataTccOrderService.prepareSubmitOrder(null, submitDTO);
|
||||
// 将订单放入延时队列,超时未支付由交换机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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单支付
|
||||
*
|
||||
* @param orderId
|
||||
* @param appId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@GlobalTransactional(rollbackFor = Exception.class)
|
||||
public <T> T pay(Long orderId, String appId, PayTypeEnum payTypeEnum) {
|
||||
OmsOrder order = this.getById(orderId);
|
||||
@ -315,11 +260,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
||||
|
||||
// 扣减库存
|
||||
Result<?> deductStockResult = skuFeignClient.deductStock(order.getOrderSn());
|
||||
|
||||
if (!Result.isSuccess(deductStockResult)) {
|
||||
throw new BizException("扣减商品库存失败");
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (InterruptedException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@ -336,6 +279,12 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private Boolean balancePay(OmsOrder order) {
|
||||
// 扣减余额
|
||||
Long payAmount = order.getPayAmount();
|
||||
@ -403,7 +352,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
||||
|
||||
@Override
|
||||
public boolean closeOrder(String orderToken) {
|
||||
log.info("=======================订单关闭,订单SN:{}=======================", orderToken);
|
||||
log.info("订单超时取消,orderToken:{}", orderToken);
|
||||
OmsOrder order = this.getOne(new LambdaQueryWrapper<OmsOrder>()
|
||||
.eq(OmsOrder::getOrderSn, orderToken));
|
||||
if (order == null || !OrderStatusEnum.PENDING_PAYMENT.getCode().equals(order.getStatus())) {
|
||||
@ -425,7 +374,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
||||
|
||||
@Override
|
||||
public boolean cancelOrder(Long id) {
|
||||
log.info("=======================订单取消,订单ID:{}=======================", id);
|
||||
log.info("订单超时取消,订单ID:{}", id);
|
||||
OmsOrder order = this.getById(id);
|
||||
if (order == null) {
|
||||
throw new BizException("订单不存在");
|
||||
@ -516,18 +465,29 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单分页列表
|
||||
* 订单验价
|
||||
*
|
||||
* @param queryParams
|
||||
* @param orderTotalAmount 订单总金额
|
||||
* @param orderItems 订单商品明细
|
||||
* @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;
|
||||
private boolean checkOrderPrice(Long orderTotalAmount, List<OrderItemDTO> orderItems) {
|
||||
CheckPriceDTO checkPriceDTO = new CheckPriceDTO();
|
||||
List<CheckPriceDTO.CheckSku> checkSkus = orderItems.stream().map(orderFormItem -> {
|
||||
CheckPriceDTO.CheckSku checkSku = new CheckPriceDTO.CheckSku();
|
||||
checkSku.setSkuId(orderFormItem.getSkuId());
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
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);
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,13 +1,15 @@
|
||||
package com.youlai.mall.pms.api;
|
||||
|
||||
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.app.LockStockDTO;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@FeignClient(value = "mall-pms",contextId = "sku")
|
||||
@FeignClient(value = "mall-pms", contextId = "sku")
|
||||
public interface SkuFeignClient {
|
||||
|
||||
/**
|
||||
@ -33,7 +35,15 @@ public interface SkuFeignClient {
|
||||
* 扣减库存
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
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;
|
||||
*/
|
||||
@Data
|
||||
public class PmsSku extends BaseEntity {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
|
@ -3,54 +3,40 @@ package com.youlai.mall.pms.controller.admin;
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.mall.pms.pojo.entity.PmsSku;
|
||||
import com.youlai.mall.pms.service.IPmsSkuService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:xianrui0365@163.com">haoxr</a>
|
||||
* @date 2022/2/8
|
||||
*/
|
||||
@Api(tags = "「系统端」库存信息")
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/inventories")
|
||||
@RequestMapping("/api/v1/sku")
|
||||
@RequiredArgsConstructor
|
||||
public class StockController {
|
||||
|
||||
private final IPmsSkuService iPmsSkuService;
|
||||
private final IPmsSkuService skuService;
|
||||
|
||||
@ApiOperation(value = "商品库存详情")
|
||||
@ApiImplicitParam(name = "id", value = "商品ID", required = true, paramType = "path", dataType = "Long")
|
||||
@GetMapping("/{id}")
|
||||
public Result detail(@PathVariable Long id) {
|
||||
PmsSku sku = iPmsSkuService.getById(id);
|
||||
@GetMapping("/{skuId}")
|
||||
public Result detail(
|
||||
@PathVariable Long skuId
|
||||
) {
|
||||
PmsSku sku = skuService.getById(skuId);
|
||||
return Result.success(sku);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "修改库存")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "id", value = "商品ID", required = true, paramType = "path", dataType = "Long"),
|
||||
@ApiImplicitParam(name = "sku", value = "实体JSON对象", required = true, paramType = "body", dataType = "PmsSku")
|
||||
})
|
||||
@PutMapping(value = "/{id}")
|
||||
public Result update(@PathVariable Long id, @RequestBody PmsSku sku) {
|
||||
boolean status = iPmsSkuService.updateById(sku);
|
||||
@PutMapping(value = "/{skuId}")
|
||||
public Result update(
|
||||
@ApiParam("商品库存单元ID") @PathVariable Long skuId,
|
||||
@RequestBody PmsSku sku
|
||||
) {
|
||||
boolean status = skuService.updateById(sku);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.youlai.mall.pms.controller.app;
|
||||
|
||||
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.app.LockStockDTO;
|
||||
import com.youlai.mall.pms.service.IPmsSkuService;
|
||||
@ -23,27 +24,19 @@ public class SkuController {
|
||||
|
||||
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 = "获取商品库存信息")
|
||||
@GetMapping("/{skuId}")
|
||||
public Result<SkuInfoDTO> getSkuInfo(
|
||||
@ApiParam("商品库存单元ID") @PathVariable Long skuId
|
||||
@ApiParam("商品库存单元ID") @PathVariable Long skuId
|
||||
) {
|
||||
SkuInfoDTO skuInfo = skuService.getSkuInfo(skuId);
|
||||
return Result.success(skuInfo);
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("获取商品库存数量")
|
||||
@GetMapping("/{skuId}/stock_num")
|
||||
public Result<Integer> getStockNum(
|
||||
@ApiParam("商品库存单元ID") @PathVariable Long skuId
|
||||
@ApiParam("商品库存单元ID") @PathVariable Long skuId
|
||||
) {
|
||||
Integer stockNum = skuService.getStockNum(skuId);
|
||||
return Result.success(stockNum);
|
||||
@ -68,4 +61,11 @@ public class SkuController {
|
||||
boolean result = skuService.deductStock(orderToken);
|
||||
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;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.youlai.common.result.Result;
|
||||
import com.youlai.mall.pms.pojo.query.SpuPageQuery;
|
||||
import com.youlai.mall.pms.pojo.vo.AppSpuPageVO;
|
||||
import com.youlai.mall.pms.pojo.vo.AppSpuDetailVO;
|
||||
import com.youlai.mall.pms.pojo.vo.GoodsPageVO;
|
||||
import com.youlai.mall.pms.pojo.vo.GoodsDetailVO;
|
||||
import com.youlai.mall.pms.service.IPmsSpuService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@ -27,18 +27,18 @@ public class SpuController {
|
||||
|
||||
@ApiOperation(value = "商品分页列表")
|
||||
@GetMapping("/page")
|
||||
public Result<List<AppSpuPageVO>> listSpuWithPage(SpuPageQuery queryParams) {
|
||||
IPage<AppSpuPageVO> result = iPmsSpuService.listAppSpuWithPage(queryParams);
|
||||
public Result<List<GoodsPageVO>> listGoodsWithPage(SpuPageQuery queryParams) {
|
||||
IPage<GoodsPageVO> result = iPmsSpuService.listAppSpuWithPage(queryParams);
|
||||
return Result.success(result.getRecords(), result.getTotal());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取商品详情")
|
||||
@GetMapping("/{spuId}")
|
||||
public Result<AppSpuDetailVO> getSpuDetail(
|
||||
public Result<GoodsDetailVO> getGoodsDetail(
|
||||
@ApiParam("商品ID") @PathVariable Long spuId
|
||||
) {
|
||||
AppSpuDetailVO appSpuDetailVO = iPmsSpuService.getAppSpuDetail(spuId);
|
||||
return Result.success(appSpuDetailVO);
|
||||
GoodsDetailVO goodsDetailVO = iPmsSpuService.getAppSpuDetail(spuId);
|
||||
return Result.success(goodsDetailVO);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.youlai.mall.pms.pojo.entity.PmsSpu;
|
||||
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 java.util.List;
|
||||
@ -25,7 +25,7 @@ public interface PmsSpuMapper extends BaseMapper<PmsSpu> {
|
||||
* @param queryParams
|
||||
* @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);
|
||||
|
||||
|
@ -14,7 +14,7 @@ import java.util.List;
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("商品详情")
|
||||
public class AppSpuDetailVO {
|
||||
public class GoodsDetailVO {
|
||||
|
||||
@ApiModelProperty("商品基本信息")
|
||||
private GoodsInfo goodsInfo;
|
||||
@ -103,7 +103,7 @@ public class AppSpuDetailVO {
|
||||
private Long price;
|
||||
|
||||
@ApiModelProperty("库存")
|
||||
private Integer stock;
|
||||
private Integer stockNum;
|
||||
|
||||
@ApiModelProperty("商品图片URL")
|
||||
private String picUrl;
|
@ -12,7 +12,7 @@ import lombok.Data;
|
||||
*/
|
||||
@ApiModel("商品分页对象")
|
||||
@Data
|
||||
public class AppSpuPageVO {
|
||||
public class GoodsPageVO {
|
||||
|
||||
@ApiModelProperty("商品ID")
|
||||
private Long id;
|
@ -2,6 +2,7 @@ package com.youlai.mall.pms.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
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.entity.PmsSku;
|
||||
import com.youlai.mall.pms.pojo.dto.app.LockStockDTO;
|
||||
@ -54,5 +55,11 @@ public interface IPmsSkuService extends IService<PmsSku> {
|
||||
boolean deductStock(String orderToken);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 商品验价
|
||||
*
|
||||
* @param checkPriceDTO
|
||||
* @return
|
||||
*/
|
||||
boolean checkPrice(CheckPriceDTO checkPriceDTO);
|
||||
}
|
||||
|
@ -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.entity.PmsSpu;
|
||||
import com.youlai.mall.pms.pojo.query.SpuPageQuery;
|
||||
import com.youlai.mall.pms.pojo.vo.AppSpuDetailVO;
|
||||
import com.youlai.mall.pms.pojo.vo.AppSpuPageVO;
|
||||
import com.youlai.mall.pms.pojo.vo.admin.GoodsDetailVO;
|
||||
import com.youlai.mall.pms.pojo.vo.GoodsDetailVO;
|
||||
import com.youlai.mall.pms.pojo.vo.GoodsPageVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -26,7 +25,7 @@ public interface IPmsSpuService extends IService<PmsSpu> {
|
||||
* @param queryParams
|
||||
* @return
|
||||
*/
|
||||
IPage<AppSpuPageVO> listAppSpuWithPage(SpuPageQuery queryParams);
|
||||
IPage<GoodsPageVO> listAppSpuWithPage(SpuPageQuery queryParams);
|
||||
|
||||
|
||||
/**
|
||||
@ -35,7 +34,7 @@ public interface IPmsSpuService extends IService<PmsSpu> {
|
||||
* @param spuId
|
||||
* @return
|
||||
*/
|
||||
AppSpuDetailVO getAppSpuDetail(Long spuId);
|
||||
GoodsDetailVO getAppSpuDetail(Long spuId);
|
||||
|
||||
|
||||
/**
|
||||
@ -43,7 +42,7 @@ public interface IPmsSpuService extends IService<PmsSpu> {
|
||||
* @param id
|
||||
* @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);
|
||||
|
@ -10,6 +10,7 @@ import com.youlai.common.result.Result;
|
||||
import com.youlai.common.web.exception.BizException;
|
||||
import com.youlai.mall.pms.common.constant.PmsConstants;
|
||||
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.app.LockStockDTO;
|
||||
import com.youlai.mall.pms.pojo.entity.PmsSku;
|
||||
@ -159,6 +160,37 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
|
||||
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
|
||||
*/
|
||||
@Override
|
||||
public SkuInfoDTO getSkuInfo(Long skuId) {
|
||||
SkuInfoDTO skuInfo= this.baseMapper.getSkuInfo(skuId);
|
||||
SkuInfoDTO skuInfo = this.baseMapper.getSkuInfo(skuId);
|
||||
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;
|
||||
import com.youlai.mall.pms.pojo.entity.PmsSpu;
|
||||
import com.youlai.mall.pms.pojo.entity.PmsSpuAttributeValue;
|
||||
import com.youlai.mall.pms.pojo.query.SpuPageQuery;
|
||||
import com.youlai.mall.pms.pojo.vo.AppSpuDetailVO;
|
||||
import com.youlai.mall.pms.pojo.vo.AppSpuPageVO;
|
||||
import com.youlai.mall.pms.pojo.vo.GoodsDetailVO;
|
||||
import com.youlai.mall.pms.pojo.vo.GoodsPageVO;
|
||||
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.IPmsSpuAttributeValueService;
|
||||
import com.youlai.mall.pms.service.IPmsSpuService;
|
||||
@ -55,9 +54,9 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public IPage<AppSpuPageVO> listAppSpuWithPage(SpuPageQuery queryParams) {
|
||||
Page<AppSpuPageVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
|
||||
List<AppSpuPageVO> list = this.baseMapper.listAppSpuWithPage(page, queryParams);
|
||||
public IPage<GoodsPageVO> listAppSpuWithPage(SpuPageQuery queryParams) {
|
||||
Page<GoodsPageVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
|
||||
List<GoodsPageVO> list = this.baseMapper.listAppSpuWithPage(page, queryParams);
|
||||
page.setRecords(list);
|
||||
return page;
|
||||
}
|
||||
@ -69,14 +68,14 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public AppSpuDetailVO getAppSpuDetail(Long spuId) {
|
||||
public GoodsDetailVO getAppSpuDetail(Long spuId) {
|
||||
PmsSpu pmsSpu = this.getById(spuId);
|
||||
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");
|
||||
|
||||
List<String> album = new ArrayList<>();
|
||||
@ -88,19 +87,19 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
|
||||
album.addAll(Arrays.asList(pmsSpu.getAlbum()));
|
||||
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::getSpuId, spuId)
|
||||
.select(PmsSpuAttributeValue::getId, PmsSpuAttributeValue::getName, PmsSpuAttributeValue::getValue)
|
||||
).stream().map(item -> {
|
||||
AppSpuDetailVO.Attribute attribute = new AppSpuDetailVO.Attribute();
|
||||
GoodsDetailVO.Attribute attribute = new GoodsDetailVO.Attribute();
|
||||
BeanUtil.copyProperties(item, attribute);
|
||||
return attribute;
|
||||
}).collect(Collectors.toList());
|
||||
appSpuDetailVO.setAttributeList(attributeList);
|
||||
goodsDetailVO.setAttributeList(attributeList);
|
||||
|
||||
|
||||
// 商品规格列表
|
||||
@ -110,7 +109,7 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
|
||||
.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<String, List<PmsSpuAttributeValue>> specValueMap = specSourceList.stream()
|
||||
.collect(Collectors.groupingBy(PmsSpuAttributeValue::getName));
|
||||
@ -120,11 +119,11 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
|
||||
List<PmsSpuAttributeValue> specValueSourceList = entry.getValue();
|
||||
|
||||
// 规格映射处理
|
||||
AppSpuDetailVO.Specification spec = new AppSpuDetailVO.Specification();
|
||||
GoodsDetailVO.Specification spec = new GoodsDetailVO.Specification();
|
||||
spec.setName(specName);
|
||||
if (CollectionUtil.isNotEmpty(specValueSourceList)) {
|
||||
List<AppSpuDetailVO.Specification.Value> specValueList = specValueSourceList.stream().map(item -> {
|
||||
AppSpuDetailVO.Specification.Value specValue = new AppSpuDetailVO.Specification.Value();
|
||||
List<GoodsDetailVO.Specification.Value> specValueList = specValueSourceList.stream().map(item -> {
|
||||
GoodsDetailVO.Specification.Value specValue = new GoodsDetailVO.Specification.Value();
|
||||
specValue.setId(item.getId());
|
||||
specValue.setValue(item.getValue());
|
||||
return specValue;
|
||||
@ -133,16 +132,17 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
|
||||
specList.add(spec);
|
||||
}
|
||||
}
|
||||
appSpuDetailVO.setSpecList(specList);
|
||||
goodsDetailVO.setSpecList(specList);
|
||||
|
||||
// 商品SKU列表
|
||||
List<PmsSku> skuSourceList = skuService.list(new LambdaQueryWrapper<PmsSku>().eq(PmsSku::getSpuId, spuId));
|
||||
if (CollectionUtil.isNotEmpty(skuSourceList)) {
|
||||
List<AppSpuDetailVO.Sku> skuList = skuSourceList.stream().map(item -> {
|
||||
AppSpuDetailVO.Sku sku = new AppSpuDetailVO.Sku();
|
||||
List<GoodsDetailVO.Sku> skuList = skuSourceList.stream().map(item -> {
|
||||
GoodsDetailVO.Sku sku = new GoodsDetailVO.Sku();
|
||||
BeanUtil.copyProperties(item, sku);
|
||||
return sku;
|
||||
}).collect(Collectors.toList());
|
||||
appSpuDetailVO.setSkuList(skuList);
|
||||
goodsDetailVO.setSkuList(skuList);
|
||||
}
|
||||
|
||||
// 添加用户浏览历史记录
|
||||
@ -154,7 +154,7 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
|
||||
vo.setPicUrl(goodsInfo.getAlbum() != null ? goodsInfo.getAlbum().get(0) : null);
|
||||
memberFeignClient.addProductViewHistory(vo);
|
||||
}
|
||||
return appSpuDetailVO;
|
||||
return goodsDetailVO;
|
||||
}
|
||||
|
||||
|
||||
@ -165,8 +165,8 @@ public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> impleme
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public GoodsDetailVO getGoodsById(Long id) {
|
||||
GoodsDetailVO goodsDetailVO = new GoodsDetailVO();
|
||||
public com.youlai.mall.pms.pojo.vo.admin.GoodsDetailVO getGoodsById(Long id) {
|
||||
com.youlai.mall.pms.pojo.vo.admin.GoodsDetailVO goodsDetailVO = new com.youlai.mall.pms.pojo.vo.admin.GoodsDetailVO();
|
||||
|
||||
PmsSpu spu = this.getById(id);
|
||||
Assert.isTrue(spu != null, "商品不存在");
|
||||
|
@ -68,7 +68,7 @@ public class SeataTccSkuServiceImpl implements SeataTccSkuService {
|
||||
);
|
||||
// 提示订单哪些商品库存不足
|
||||
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());
|
||||
return true;
|
||||
|
@ -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
|
||||
id,
|
||||
NAME,
|
||||
|
@ -1,11 +1,13 @@
|
||||
package com.youlai.mall.sms.pojo.to;
|
||||
|
||||
import com.youlai.mall.pms.pojo.dto.SkuInfoDTO;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 秒杀商品Redis存储
|
||||
*
|
||||
* @author huawei
|
||||
* @desc 秒杀商品Redis存储 TO
|
||||
* @email huawei_code@163.com
|
||||
* @date 2021/3/7
|
||||
*/
|
||||
@ -65,6 +67,6 @@ public class SeckillSkuRedisTO {
|
||||
/**
|
||||
* 秒杀商品详情
|
||||
*/
|
||||
private AppSkuDetailVO skuInfo;
|
||||
private SkuInfoDTO skuInfo;
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.youlai.mall.sms.pojo.vo;
|
||||
|
||||
import com.youlai.mall.pms.pojo.dto.SkuInfoDTO;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
@ -68,5 +69,5 @@ public class SmsSeckillSkuVO {
|
||||
/**
|
||||
* 秒杀商品详情
|
||||
*/
|
||||
private AppSkuDetailVO skuInfo;
|
||||
private SkuInfoDTO skuInfo;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user