From 0e600d76f8c179975e199e99558f4a4a75ad2c2f Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Fri, 10 Apr 2026 16:11:43 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=80=E6=AC=BE=20=E6=89=A3=E9=99=A4?= =?UTF-8?q?=E5=BA=93=E5=AD=98=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/czg/mq/OrderMqListener.java | 8 +-- .../com/czg/order/dto/OrderInfoRefundDTO.java | 4 ++ .../order/service/OrderInfoCustomService.java | 7 +++ .../product/service/ProductRpcService.java | 11 ++-- .../impl/OrderInfoCustomServiceImpl.java | 58 +++++++++++++++++-- .../service/impl/OrderInfoRpcServiceImpl.java | 18 ++---- .../service/impl/OrderPayServiceImpl.java | 15 ++--- .../service/impl/ProductRpcServiceImpl.java | 21 +------ 8 files changed, 88 insertions(+), 54 deletions(-) diff --git a/cash-api/order-server/src/main/java/com/czg/mq/OrderMqListener.java b/cash-api/order-server/src/main/java/com/czg/mq/OrderMqListener.java index 395f1a25e..9ef163c81 100644 --- a/cash-api/order-server/src/main/java/com/czg/mq/OrderMqListener.java +++ b/cash-api/order-server/src/main/java/com/czg/mq/OrderMqListener.java @@ -2,7 +2,6 @@ package com.czg.mq; import cn.hutool.core.date.DateUtil; import cn.hutool.core.exceptions.ExceptionUtil; -import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.czg.config.RabbitConstants; import com.czg.order.entity.MqLog; @@ -71,10 +70,10 @@ public class OrderMqListener { public void orderStockRecover(String orderId) { long startTime = DateUtil.date().getTime(); log.info("接收到订单取消恢复库存消息:{}", orderId); - MqLog mqLog = new MqLog().setQueue(RabbitConstants.Queue.ORDER_CANCEL_QUEUE).setMsg(orderId).setType("orderStockRecover").setPlat("java.order").setCreateTime(DateUtil.date().toLocalDateTime()); try { orderInfoRpcService.orderCancelCallback(Long.valueOf(orderId)); } catch (Exception e) { + MqLog mqLog = new MqLog().setQueue(RabbitConstants.Queue.ORDER_CANCEL_QUEUE).setMsg(orderId).setType("orderStockRecover").setPlat("java.order").setCreateTime(DateUtil.date().toLocalDateTime()); log.error("订单取消恢复库存失败", e); String errorInfo = ExceptionUtil.stacktraceToString(e); mqLog.setErrInfo(errorInfo); @@ -88,11 +87,10 @@ public class OrderMqListener { public void orderStockReturn(String jsonObjStr) { long startTime = DateUtil.date().getTime(); log.info("接收到订单退款返还库存消息:{}", jsonObjStr); - MqLog mqLog = new MqLog().setQueue(RabbitConstants.Queue.ORDER_REFUND_QUEUE).setMsg(jsonObjStr).setType("orderStockReturn").setPlat("java.order").setCreateTime(DateUtil.date().toLocalDateTime()); try { - JSONObject data = JSON.parseObject(jsonObjStr); - orderInfoRpcService.orderRefundCallback(data); + orderInfoRpcService.orderRefundCallback(JSONObject.parseObject(jsonObjStr)); } catch (Exception e) { + MqLog mqLog = new MqLog().setQueue(RabbitConstants.Queue.ORDER_REFUND_QUEUE).setMsg(jsonObjStr).setType("orderStockReturn").setPlat("java.order").setCreateTime(DateUtil.date().toLocalDateTime()); log.error("订单退款返还库存失败", e); String errorInfo = ExceptionUtil.stacktraceToString(e); mqLog.setErrInfo(errorInfo); diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoRefundDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoRefundDTO.java index 903799856..b0a94d982 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoRefundDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoRefundDTO.java @@ -54,6 +54,10 @@ public class OrderInfoRefundDTO implements Serializable { * 是否打印退菜/退款票 */ private boolean print; + /** + * 是否退库存 + */ + private boolean refundStock; private String refundReason; diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/service/OrderInfoCustomService.java b/cash-common/cash-common-service/src/main/java/com/czg/order/service/OrderInfoCustomService.java index bda46f3d6..272df4d00 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/service/OrderInfoCustomService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/service/OrderInfoCustomService.java @@ -2,6 +2,7 @@ package com.czg.order.service; import cn.hutool.core.exceptions.ValidateException; import com.alibaba.fastjson2.JSONObject; +import com.czg.account.entity.ShopInfo; import com.czg.exception.CzgException; import com.czg.exception.OrderCancelException; import com.czg.exception.OrderValidateException; @@ -21,6 +22,7 @@ import org.jetbrains.annotations.NotNull; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; +import java.util.Map; /** * 订单表 服务层。 @@ -73,4 +75,9 @@ public interface OrderInfoCustomService { Boolean upOrderDetail(Long shopId, OrderDetailStatusDTO detailStatusDTO); + + /** + * 退单库存问题 + */ + void refundStock(ShopInfo shopInfo, Long orderId, Map products, boolean refundStock); } 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 index 97544bbdb..b781392c6 100644 --- 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 @@ -1,9 +1,9 @@ package com.czg.product.service; +import com.czg.product.vo.ProductStockVO; import com.czg.product.vo.ProductVO; import java.util.List; -import java.util.Map; /** * 商品RPC远程调用服务接口 @@ -20,24 +20,23 @@ public interface ProductRpcService { * @param orderId 订单ID * @param dataList 库存扣减数据 */ - void paySuccessSubtractStock(Long shopId, Long orderId, List> dataList); + void paySuccessSubtractStock(Long shopId, Long orderId, List dataList); /** * 订单取消后恢复库存 * * @param shopId 店铺id * @param orderId 订单ID - * @param dataList 库存恢复数据 */ - void orderCancelRecoverStock(Long shopId, Long orderId, List> dataList); + void orderCancelRecoverStock(Long shopId, Long orderId, List list); /** * 订单退菜或退款后回退库存 * @param shopId 店铺id * @param orderId 订单ID - * @param dataList 库存恢复数据 + * @param list 库存恢复数据 */ - void orderRefundReturnStock(Long shopId, Long orderId, List> dataList); + void orderRefundReturnStock(Long shopId, Long orderId, List list); List listAndLowPrice(Long shopId, List productIds); diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java index 467252fab..bb48fa0e5 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderInfoCustomServiceImpl.java @@ -43,8 +43,12 @@ import com.czg.order.enums.PayEnums; import com.czg.order.service.*; import com.czg.order.vo.*; import com.czg.pay.PayNotifyRespDTO; +import com.czg.product.entity.Product; +import com.czg.product.entity.ShopProdCategory; import com.czg.product.service.ProductRpcService; import com.czg.product.service.ProductService; +import com.czg.product.service.ShopProdCategoryService; +import com.czg.product.vo.ProductStockVO; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; import com.czg.service.RedisService; @@ -107,6 +111,8 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService { @DubboReference private ProductService productService; @DubboReference + private ShopProdCategoryService shopProdCategoryService; + @DubboReference private ProductRpcService productRpcService; @DubboReference private ShopInfoService shopInfoService; @@ -1696,13 +1702,13 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService { return true; } List details = orderDetailService.list(QueryWrapper.create().eq(OrderDetail::getOrderId, orderId).eq(OrderDetail::getPlaceNum, placeNum)); - List> dataList = new ArrayList<>(); + List listStock = new ArrayList<>(); for (OrderDetail detail : details) { - dataList.add(Map.of("productId", detail.getProductId(), "number", NumberUtil.sub(detail.getNum(), detail.getReturnNum()))); + listStock.add(new ProductStockVO(detail.getProductId(), NumberUtil.sub(detail.getNum(), detail.getReturnNum()))); } orderDetailService.remove(new QueryWrapper().eq(OrderDetail::getOrderId, orderId).eq(OrderDetail::getPlaceNum, placeNum)); - if (CollUtil.isNotEmpty(dataList)) { - productRpcService.orderCancelRecoverStock(shopId, orderId, dataList); + if (CollUtil.isNotEmpty(listStock)) { + productRpcService.orderCancelRecoverStock(shopId, orderId, listStock); } List list = orderDetailService.queryChain().eq(OrderDetail::getOrderId, orderId).eq(OrderDetail::getShopId, shopId).list(); if (CollUtil.isEmpty(list)) { @@ -1828,4 +1834,48 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService { rabbitPublisher.sendOrderDetailStatusMsg(shopId.toString(), "bc"); return true; } + + + /** + * 退单库存问题 + * 1退菜退库存 2仅退菜不退库存 3每次询问-退菜后弹窗提示1 + */ + @Override + public void refundStock(ShopInfo shopInfo, Long orderId, Map products, boolean refundStock) { + List list = productService.list(new QueryWrapper().select(Product::getId, Product::getCategoryId, Product::getRefundMode) + .eq(Product::getShopId, shopInfo.getId()) + .in(Product::getId, products.keySet())); + if (CollUtil.isEmpty(list)) { + return; + } + List resultProduct = new ArrayList<>(); + HashMap categoryMap = new HashMap<>(); + for (Product product : list) { + Integer refundMode; + if (shopInfo.getRefundMode().equals(1)) { + //分类 + if (!categoryMap.containsKey(product.getCategoryId())) { + refundMode = shopProdCategoryService.getOneAs(new QueryWrapper().select(ShopProdCategory::getRefundMode) + .eq(ShopProdCategory::getShopId, shopInfo.getId()).eq(ShopProdCategory::getId, product.getCategoryId()), Integer.class); + categoryMap.put(product.getCategoryId(), refundMode); + } else { + refundMode = categoryMap.get(product.getCategoryId()); + } + } else if (shopInfo.getRefundMode().equals(2)) { + //单商品 + refundMode = product.getRefundMode(); + } else { + log.error("退菜模式错误 店铺{},退款模式{},商品Id{}分类Id{}", shopInfo.getShopName(), shopInfo.getRefundMode(), product.getId(), product.getCategoryId()); + throw new CzgException("退菜模式错误"); + } + if (refundMode.equals(1)) { + resultProduct.add(new ProductStockVO(product.getId(), products.get(product.getId()))); + } else if (refundMode.equals(3) && refundStock) { + resultProduct.add(new ProductStockVO(product.getId(), products.get(product.getId()))); + } + } + if (CollUtil.isNotEmpty(resultProduct)) { + rabbitPublisher.sendOrderRefundMsg(JSONObject.toJSONString(Map.of("orderId", orderId, "returnProList", resultProduct))); + } + } } 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 428a335ed..577c0cca9 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 @@ -13,6 +13,7 @@ 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.product.vo.ProductStockVO; import com.czg.service.market.mapper.OrderInfoMapper; import com.czg.service.order.mapper.OrderDetailMapper; import com.mybatisflex.core.query.QueryWrapper; @@ -95,12 +96,12 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService { } Long shopId = orderInfo.getShopId(); // 封装扣减库存数据 - List> dataList = new ArrayList<>(); + List dataList = new ArrayList<>(); for (OrderDetail orderDetail : detailList) { Long productId = orderDetail.getProductId(); BigDecimal num = orderDetail.getNum(); BigDecimal refundNum = orderDetail.getRefundNum(); - dataList.add(Map.of("productId", productId, "number", NumberUtil.sub(num, refundNum))); + dataList.add(new ProductStockVO(productId, NumberUtil.sub(num, refundNum))); } try { // 调用商品服务扣减库存 @@ -127,12 +128,12 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService { throw new CzgException("该订单下不存在商品"); } // 封装扣减库存数据 - List> dataList = new ArrayList<>(); + List dataList = new ArrayList<>(); for (OrderDetail orderDetail : detailList) { Long productId = orderDetail.getProductId(); BigDecimal num = orderDetail.getNum(); BigDecimal refundNum = orderDetail.getRefundNum(); - dataList.add(Map.of("productId", productId, "number", NumberUtil.sub(num, refundNum))); + dataList.add(new ProductStockVO(productId, NumberUtil.sub(num, refundNum))); } try { // 调用商品服务扣减库存 @@ -145,7 +146,6 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService { @Override public void orderRefundCallback(JSONObject data) { - log.info(">>>>>>>>>>>>>>>>>:入参:{}", data.toJSONString()); Long orderId = data.getLong("orderId"); // 订单取消后商品库存恢复,耗材恢复,流水记录 OrderInfo orderInfo = orderInfoMapper.selectOneById(orderId); @@ -157,13 +157,7 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService { if (CollUtil.isEmpty(detailList)) { throw new CzgException("该订单下不存在商品"); } - JSONObject obj = data.getJSONObject("returnProMap"); - Set keys = obj.keySet(); - // 封装扣减库存数据 - List> dataList = new ArrayList<>(); - for (String key : keys) { - dataList.add(Map.of("productId", key, "number", obj.getBigDecimal(key))); - } + List dataList = data.getList("returnProList", ProductStockVO.class); try { // 调用商品服务回退库存 productRpcService.orderRefundReturnStock(orderInfo.getShopId(), orderId, dataList); diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderPayServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderPayServiceImpl.java index 89322b67d..61bccad67 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderPayServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderPayServiceImpl.java @@ -1,13 +1,11 @@ package com.czg.service.order.service.impl; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.convert.Convert; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.digest.MD5; -import com.alibaba.fastjson2.JSONObject; import com.czg.PayCst; import com.czg.account.dto.shopuser.ShopUserMoneyEditDTO; import com.czg.account.entity.ShopInfo; @@ -383,7 +381,7 @@ public class OrderPayServiceImpl implements OrderPayService { } boolean isFirstRefund = orderInfo.getRefundAmount().compareTo(BigDecimal.ZERO) == 0; ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId()); - Map returnProMap = new HashMap<>(); + Map productStockMap = new HashMap<>(); boolean isPay = true; String refPayOrderNo = "REFO" + IdUtil.getSnowflakeNextId(); if (orderInfo.getStatus().equals(OrderStatusEnums.UNPAID.getCode())) { @@ -443,7 +441,7 @@ public class OrderPayServiceImpl implements OrderPayService { } orderDetailService.updateById(orderDetail); if (orderDetail.getProductId() != null && orderDetail.getProductId() > 0) { - returnProMap.put(Convert.toStr(orderDetail.getProductId()), refundDetail.getNum()); + productStockMap.put(orderDetail.getProductId(), refundDetail.getNum()); } } long count = orderDetailService.count(QueryWrapper.create().eq(OrderDetail::getOrderId, orderInfo.getId()) @@ -461,14 +459,14 @@ public class OrderPayServiceImpl implements OrderPayService { for (OrderDetail orderDetail : orderDetails) { if (isPay) { if (orderDetail.getProductId() != null && orderDetail.getProductId() > 0) { - returnProMap.put(Convert.toStr(orderDetail.getProductId()), orderDetail.getNum().subtract(orderDetail.getReturnNum()).subtract(orderDetail.getRefundNum())); + productStockMap.put(orderDetail.getProductId(), orderDetail.getNum().subtract(orderDetail.getReturnNum()).subtract(orderDetail.getRefundNum())); } orderDetail.setReturnAmount(orderDetail.getPayAmount()); orderDetail.setRefundNum(orderDetail.getNum().subtract(orderDetail.getReturnNum())); orderDetail.setStatus(OrderStatusEnums.REFUND.getCode()); } else { if (orderDetail.getProductId() != null && orderDetail.getProductId() > 0) { - returnProMap.put(Convert.toStr(orderDetail.getProductId()), orderDetail.getNum().subtract(orderDetail.getReturnNum())); + productStockMap.put(orderDetail.getProductId(), orderDetail.getNum().subtract(orderDetail.getReturnNum())); } orderDetail.setReturnNum(orderDetail.getNum()); orderDetail.setStatus(OrderStatusEnums.CANCELLED.getCode()); @@ -519,9 +517,8 @@ public class OrderPayServiceImpl implements OrderPayService { , param.getRefundReason(), orderInfo.getRefundType(), orderInfo, param.getRefundDetails()); } //退款返还库存 - if (!returnProMap.isEmpty()) { - //TODO 退款 商品退不退的 校验 - rabbitPublisher.sendOrderRefundMsg(JSONObject.toJSONString(Map.of("orderId", orderInfo.getId(), "returnProMap", returnProMap))); + if (!productStockMap.isEmpty()) { + orderInfoCustomService.refundStock(shopInfo, orderInfo.getId(), productStockMap, param.isRefundStock()); } refundOrderAfter(orderInfo.getId(), orderInfo.getShopId(), orderInfo.getUserId(), orderInfo.getOrderNo(), orderInfo.getPointsNum(), isFirstRefund, orderInfo.getStatus().equals(OrderStatusEnums.REFUND.getCode())); 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 index 71663587a..a5726b90e 100644 --- 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 @@ -1,7 +1,5 @@ package com.czg.service.product.service.impl; -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.collection.CollUtil; import com.czg.product.enums.InOutItemEnum; import com.czg.product.enums.InOutTypeEnum; import com.czg.product.service.ProductRpcService; @@ -16,7 +14,6 @@ import org.apache.dubbo.config.annotation.DubboService; import org.springframework.transaction.annotation.Transactional; import java.util.List; -import java.util.Map; import static com.czg.constant.CacheConstant.ADMIN_CLIENT_PRODUCT_LIST; @@ -39,32 +36,20 @@ public class ProductRpcServiceImpl implements ProductRpcService { @Override @Transactional(rollbackFor = Exception.class) - public void paySuccessSubtractStock(Long shopId, Long orderId, List> dataList) { - List list = BeanUtil.copyToList(dataList, ProductStockVO.class); - if (CollUtil.isEmpty(list)) { - return; - } + public void paySuccessSubtractStock(Long shopId, Long orderId, List list) { productService.consStockByProduct(shopId, InOutTypeEnum.OUT, InOutItemEnum.ORDER_OUT, list, orderId, "订单消费"); } @Override @Transactional(rollbackFor = Exception.class) - public void orderCancelRecoverStock(Long shopId, Long orderId, List> dataList) { - List list = BeanUtil.copyToList(dataList, ProductStockVO.class); - if (CollUtil.isEmpty(list)) { - return; - } + public void orderCancelRecoverStock(Long shopId, Long orderId, List list) { productService.consStockByProduct(shopId, InOutTypeEnum.IN, InOutItemEnum.ORDER_IN, list, orderId, "订单取消/过期返还库存"); } @Override @Transactional(rollbackFor = Exception.class) - public void orderRefundReturnStock(Long shopId, Long orderId, List> dataList) { - List list = BeanUtil.copyToList(dataList, ProductStockVO.class); - if (CollUtil.isEmpty(list)) { - return; - } + public void orderRefundReturnStock(Long shopId, Long orderId, List list) { productService.consStockByProduct(shopId, InOutTypeEnum.IN, InOutItemEnum.ORDER_IN, list, orderId, "订单退菜/退款返还库存"); }