退款 扣除库存校验

This commit is contained in:
2026-04-10 16:11:43 +08:00
parent c4b93b6a5b
commit 0e600d76f8
8 changed files with 88 additions and 54 deletions

View File

@@ -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<OrderDetail> details = orderDetailService.list(QueryWrapper.create().eq(OrderDetail::getOrderId, orderId).eq(OrderDetail::getPlaceNum, placeNum));
List<Map<String, Object>> dataList = new ArrayList<>();
List<ProductStockVO> 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<OrderDetail> 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<Long, BigDecimal> products, boolean refundStock) {
List<Product> 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<ProductStockVO> resultProduct = new ArrayList<>();
HashMap<Long, Integer> 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)));
}
}
}

View File

@@ -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<Map<String, Object>> dataList = new ArrayList<>();
List<ProductStockVO> 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<Map<String, Object>> dataList = new ArrayList<>();
List<ProductStockVO> 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<String> keys = obj.keySet();
// 封装扣减库存数据
List<Map<String, Object>> dataList = new ArrayList<>();
for (String key : keys) {
dataList.add(Map.of("productId", key, "number", obj.getBigDecimal(key)));
}
List<ProductStockVO> dataList = data.getList("returnProList", ProductStockVO.class);
try {
// 调用商品服务回退库存
productRpcService.orderRefundReturnStock(orderInfo.getShopId(), orderId, dataList);

View File

@@ -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<String, BigDecimal> returnProMap = new HashMap<>();
Map<Long,BigDecimal> 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()));