From 076c2152782fdb999cca00a2b4235626d6040b3a Mon Sep 17 00:00:00 2001 From: Tankaikai Date: Sat, 1 Mar 2025 11:09:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=95=86=E5=93=81=E6=A8=A1=E5=9D=97=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/service/OrderInfoRpcService.java | 6 + .../product/dto/ProductStockSubtractDTO.java | 33 ++++++ .../product/service/ProductRpcService.java | 21 ++++ .../service/impl/OrderInfoRpcServiceImpl.java | 47 ++++++++ .../service/product/mapper/ProductMapper.java | 4 +- .../service/impl/ProductRpcServiceImpl.java | 110 ++++++++++++++++++ .../main/resources/mapper/ProductMapper.xml | 7 ++ 7 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductStockSubtractDTO.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductRpcService.java create mode 100644 cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductRpcServiceImpl.java diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/OrderInfoRpcService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/OrderInfoRpcService.java index 7879fa13..0c160649 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/OrderInfoRpcService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/service/OrderInfoRpcService.java @@ -134,4 +134,10 @@ public interface OrderInfoRpcService { */ List getHandoverCategoryList(Long shopId, String loginTime, String handoverTime); + /** + * 订单支付成功回调 扣减商品库存及耗材库存 + * + * @param orderId 订单id + */ + void paySuccessCallback(Long orderId); } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductStockSubtractDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductStockSubtractDTO.java new file mode 100644 index 00000000..07b07b78 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ProductStockSubtractDTO.java @@ -0,0 +1,33 @@ +package com.czg.product.dto; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 商品库存扣减DTO + * + * @author tankaikai + * @since 2025-03-01 10:26 + */ +@Data +public class ProductStockSubtractDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 店铺id + */ + private Long shopId; + /** + * 商品id + */ + private Long productId; + /** + * 扣减数量 + */ + private BigDecimal num; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductRpcService.java b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductRpcService.java new file mode 100644 index 00000000..3b254071 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ProductRpcService.java @@ -0,0 +1,21 @@ +package com.czg.product.service; + +import java.util.List; +import java.util.Map; + +/** + * 商品RPC远程调用服务接口 + * + * @author tankaikai + * @since 2025-03-01 10:19 + */ +public interface ProductRpcService { + + /** + * 订单支付成功扣减库存 + * + * @param orderId 订单ID + * @param dataList 库存扣减数据 + */ + void paySuccessSubtractStock(Long orderId, List> dataList); +} diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoRpcServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoRpcServiceImpl.java index 7ea97cdb..643afbe2 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoRpcServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoRpcServiceImpl.java @@ -1,16 +1,28 @@ package com.czg.service.order.service.impl; +import cn.hutool.core.collection.CollUtil; import com.czg.account.vo.HandoverCategoryListVo; import com.czg.account.vo.HandoverProductListVo; +import com.czg.exception.CzgException; +import com.czg.order.entity.OrderDetail; +import com.czg.order.entity.OrderInfo; import com.czg.order.service.OrderInfoRpcService; +import com.czg.product.service.ProductRpcService; +import com.czg.service.order.mapper.OrderDetailMapper; import com.czg.service.order.mapper.OrderInfoMapper; +import com.mybatisflex.core.query.QueryWrapper; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * 订单Rpc ServiceImpl @@ -26,6 +38,12 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService { @Resource private OrderInfoMapper orderInfoMapper; + @Resource + private OrderDetailMapper orderDetailMapper; + + @DubboReference + private ProductRpcService productRpcService; + @Override public BigDecimal getHandoverWechatAmount(Long shopId, String loginTime, String handoverTime) { return orderInfoMapper.getHandoverWechatAmount(shopId, loginTime, handoverTime); @@ -85,4 +103,33 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService { public List getHandoverCategoryList(Long shopId, String loginTime, String handoverTime) { return orderInfoMapper.getHandoverCategoryList(shopId, loginTime, handoverTime); } + + @Override + @Transactional(rollbackFor = Exception.class) + public void paySuccessCallback(Long orderId) { + // 下单后商品库存扣减,耗材扣减,流水记录 + OrderInfo orderInfo = orderInfoMapper.selectOneById(orderId); + if (orderInfo == null) { + throw new CzgException("订单不存在"); + } + // 查询订单下商品 + List detailList = orderDetailMapper.selectListByQuery(QueryWrapper.create().eq(OrderDetail::getOrderId, orderId)); + if (CollUtil.isEmpty(detailList)) { + throw new CzgException("该订单下不存在商品"); + } + Long shopId = orderInfo.getShopId(); + // 封装扣减库存数据 + List> dataList = new ArrayList<>(); + for (OrderDetail orderDetail : detailList) { + Map data = new HashMap<>(16); + Long productId = orderDetail.getProductId(); + BigDecimal num = orderDetail.getNum(); + data.put("shopId", shopId); + data.put("productId", productId); + data.put("num", num); + dataList.add(data); + } + // 调用商品服务扣减库存 + productRpcService.paySuccessSubtractStock(orderId, dataList); + } } diff --git a/cash-service/product-service/src/main/java/com/czg/service/product/mapper/ProductMapper.java b/cash-service/product-service/src/main/java/com/czg/service/product/mapper/ProductMapper.java index 5c5c01b2..af00223e 100644 --- a/cash-service/product-service/src/main/java/com/czg/service/product/mapper/ProductMapper.java +++ b/cash-service/product-service/src/main/java/com/czg/service/product/mapper/ProductMapper.java @@ -10,6 +10,7 @@ import com.mybatisflex.core.query.QueryWrapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import java.math.BigDecimal; import java.util.List; /** @@ -35,4 +36,5 @@ public interface ProductMapper extends BaseMapper { List selectCouponProBySaleNum(); -} + void updateProductStockNum(@Param("id") Long id, @Param("shopId") Long shopId, @Param("subtractNum") BigDecimal subtractNum); +} \ No newline at end of file diff --git a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductRpcServiceImpl.java b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductRpcServiceImpl.java new file mode 100644 index 00000000..b8badbeb --- /dev/null +++ b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProductRpcServiceImpl.java @@ -0,0 +1,110 @@ +package com.czg.service.product.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.NumberUtil; +import com.czg.product.dto.ProductStockSubtractDTO; +import com.czg.product.entity.ConsInfo; +import com.czg.product.entity.ConsStockFlow; +import com.czg.product.entity.ProdConsRelation; +import com.czg.product.enums.InOutItemEnum; +import com.czg.product.enums.InOutTypeEnum; +import com.czg.product.service.ProductRpcService; +import com.czg.sa.StpKit; +import com.czg.service.product.mapper.ConsInfoMapper; +import com.czg.service.product.mapper.ConsStockFlowMapper; +import com.czg.service.product.mapper.ProdConsRelationMapper; +import com.czg.service.product.mapper.ProductMapper; +import com.mybatisflex.core.query.QueryWrapper; +import jakarta.annotation.Resource; +import org.apache.dubbo.config.annotation.DubboService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; +import java.util.Map; + +/** + * 商品RPC远程调用服务接口实现 + * + * @author tankaikai + * @since 2025-03-01 10:19 + */ +@Service +@DubboService +public class ProductRpcServiceImpl implements ProductRpcService { + + @Resource + private ProductMapper productMapper; + + @Resource + private ProdConsRelationMapper prodConsRelationMapper; + + @Resource + private ConsInfoMapper consInfoMapper; + + @Resource + private ConsStockFlowMapper consStockFlowMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public void paySuccessSubtractStock(Long orderId, List> dataList) { + List list = BeanUtil.copyToList(dataList, ProductStockSubtractDTO.class); + if (CollUtil.isEmpty(list)) { + return; + } + for (ProductStockSubtractDTO dto : list) { + productMapper.updateProductStockNum(dto.getProductId(), dto.getShopId(), dto.getNum()); + // 查询商品绑定耗材信息 + List relationList = prodConsRelationMapper.selectListByQuery(QueryWrapper.create().eq(ProdConsRelation::getProductId, dto.getProductId())); + if (CollUtil.isEmpty(relationList)) { + continue; + } + for (ProdConsRelation prodConsRelation : relationList) { + // 耗材id + Long consInfoId = prodConsRelation.getConsInfoId(); + // 耗材消耗数量 + BigDecimal surplusStock = prodConsRelation.getSurplusStock(); + if (surplusStock == null) { + continue; + } + // 实际消耗数量 = 耗材消耗数量 * 商品购买数量 + surplusStock = NumberUtil.mul(surplusStock, dto.getNum()); + ConsInfo consInfo = consInfoMapper.selectOneById(consInfoId); + if (consInfo == null) { + continue; + } + BigDecimal stockNumber = consInfo.getStockNumber(); + consInfo.setStockNumber(NumberUtil.sub(stockNumber, surplusStock)); + // 更新耗材库存数量 + consInfoMapper.update(consInfo); + // 插入耗材流水记录 + Long shopId = consInfo.getShopId(); + ConsStockFlow consStockFlow = new ConsStockFlow(); + consStockFlow.setId(0L); + consStockFlow.setShopId(shopId); + consStockFlow.setVendorId(null); + consStockFlow.setInOutType(InOutTypeEnum.OUT.value()); + consStockFlow.setInOutItem(InOutItemEnum.ORDER_OUT.value()); + consStockFlow.setInOutDate(LocalDate.now()); + consStockFlow.setConId(consInfo.getId()); + consStockFlow.setConName(consInfo.getConName()); + consStockFlow.setUnitName(consInfo.getConUnit()); + consStockFlow.setBeforeNumber(stockNumber); + consStockFlow.setInOutNumber(NumberUtil.sub(BigDecimal.ZERO, surplusStock)); + consStockFlow.setAfterNumber(consInfo.getStockNumber()); + consStockFlow.setSubTotal(NumberUtil.mul(surplusStock, consInfo.getPrice())); + consStockFlow.setProductId(dto.getProductId()); + //consStockFlow.setSkuId(0L); + consStockFlow.setOrderId(orderId); + Long createUserId = StpKit.USER.getLoginIdAsLong(); + String createUserName = StpKit.USER.getAccount(); + consStockFlow.setCreateUserId(createUserId); + consStockFlow.setCreateUserName(createUserName); + consStockFlowMapper.insert(consStockFlow); + } + } + } +} diff --git a/cash-service/product-service/src/main/resources/mapper/ProductMapper.xml b/cash-service/product-service/src/main/resources/mapper/ProductMapper.xml index 5917f1c6..adc7cfce 100644 --- a/cash-service/product-service/src/main/resources/mapper/ProductMapper.xml +++ b/cash-service/product-service/src/main/resources/mapper/ProductMapper.xml @@ -159,4 +159,11 @@ ORDER BY b.real_sales_number LIMIT 2 + + update tb_product + set stock_number = stock_number - #{subtractNum} + where id = #{id} + and is_stock = 1 + and shop_id = #{shopId} +