订单管理-退单
This commit is contained in:
parent
d4357b9949
commit
c30fe148de
|
|
@ -5,7 +5,7 @@ import lombok.Data;
|
|||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
public class TradeAndWallerInfo {
|
||||
public class TradeAndWalletInfo {
|
||||
private Long tradeId;
|
||||
private BigDecimal actualAmount;
|
||||
private BigDecimal amount;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package com.bonus.canteen.core.account.mapper;
|
||||
|
||||
import com.bonus.canteen.core.account.domain.AccountTrade;
|
||||
import com.bonus.canteen.core.account.domain.bo.TradeAndWallerInfo;
|
||||
import com.bonus.canteen.core.account.domain.bo.TradeAndWalletInfo;
|
||||
import com.bonus.canteen.core.account.domain.param.AccConsumeDetailQueryParam;
|
||||
import com.bonus.canteen.core.account.domain.param.AccWalletOperationQueryParam;
|
||||
import com.bonus.canteen.core.account.domain.vo.AccConsumeDetailVO;
|
||||
|
|
@ -75,7 +75,7 @@ public interface AccTradeMapper {
|
|||
List<AccOperationListVO> queryAccOperationList(@Param("param") AccWalletOperationQueryParam param,
|
||||
@Param("encryptedSearchValue") String encryptedSearchValue);
|
||||
|
||||
List<TradeAndWallerInfo> queryTradeAndWallerInfoByOrderNo(@Param("orderNo") String orderNo,
|
||||
List<TradeAndWalletInfo> queryTradeAndWallerInfoByOrderNo(@Param("orderNo") String orderNo,
|
||||
@Param("accTradeType") Integer accTradeType);
|
||||
|
||||
List<AccConsumeDetailVO> queryAccConsumeDetail(@Param("param") AccConsumeDetailQueryParam param,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.bonus.canteen.core.account.service;
|
|||
|
||||
import com.bonus.canteen.core.account.constants.AccTradeTypeEnum;
|
||||
import com.bonus.canteen.core.account.domain.AccountTrade;
|
||||
import com.bonus.canteen.core.account.domain.bo.TradeAndWallerInfo;
|
||||
import com.bonus.canteen.core.account.domain.bo.TradeAndWalletInfo;
|
||||
import com.bonus.canteen.core.account.domain.param.AccConsumeDetailQueryParam;
|
||||
import com.bonus.canteen.core.account.domain.param.AccWalletOperationQueryParam;
|
||||
import com.bonus.canteen.core.account.domain.vo.AccConsumeDetailVO;
|
||||
|
|
@ -74,7 +74,7 @@ public interface IAccTradeService {
|
|||
|
||||
List<AccOperationListVO> queryAccOperationList(AccWalletOperationQueryParam param);
|
||||
|
||||
List<TradeAndWallerInfo> queryTradeAndWallerInfoByOrderNo(String orderNo, AccTradeTypeEnum accTradeTypeEnum);
|
||||
List<TradeAndWalletInfo> queryTradeAndWallerInfoByOrderNo(String orderNo, AccTradeTypeEnum accTradeTypeEnum);
|
||||
|
||||
List<AccConsumeDetailVO> queryAccConsumeDetail(AccConsumeDetailQueryParam param);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.bonus.canteen.core.account.service.impl;
|
|||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.bonus.canteen.core.account.constants.AccTradeTypeEnum;
|
||||
import com.bonus.canteen.core.account.domain.AccountTrade;
|
||||
import com.bonus.canteen.core.account.domain.bo.TradeAndWallerInfo;
|
||||
import com.bonus.canteen.core.account.domain.bo.TradeAndWalletInfo;
|
||||
import com.bonus.canteen.core.account.domain.param.AccConsumeDetailQueryParam;
|
||||
import com.bonus.canteen.core.account.domain.param.AccWalletOperationQueryParam;
|
||||
import com.bonus.canteen.core.account.domain.vo.AccConsumeDetailVO;
|
||||
|
|
@ -160,7 +160,7 @@ public class AccTradeServiceImpl implements IAccTradeService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<TradeAndWallerInfo> queryTradeAndWallerInfoByOrderNo(String orderNo, AccTradeTypeEnum accTradeTypeEnum) {
|
||||
public List<TradeAndWalletInfo> queryTradeAndWallerInfoByOrderNo(String orderNo, AccTradeTypeEnum accTradeTypeEnum) {
|
||||
return accTradeMapper.queryTradeAndWallerInfoByOrderNo(orderNo, accTradeTypeEnum.getKey());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,24 +5,35 @@ import com.bonus.canteen.core.account.constants.AccTradeTypeEnum;
|
|||
import com.bonus.canteen.core.account.constants.AccWalletTypeEnum;
|
||||
import com.bonus.canteen.core.account.domain.AccWalletInfo;
|
||||
import com.bonus.canteen.core.account.domain.WalletUpdateDTO;
|
||||
import com.bonus.canteen.core.account.domain.bo.TradeAndWalletInfo;
|
||||
import com.bonus.canteen.core.account.service.IAccTradeService;
|
||||
import com.bonus.canteen.core.account.service.IAccWalletInfoService;
|
||||
import com.bonus.canteen.core.common.utils.MqUtil;
|
||||
import com.bonus.canteen.core.common.utils.ObjectUtils;
|
||||
import com.bonus.canteen.core.common.utils.RedisUtil;
|
||||
import com.bonus.canteen.core.cook.domain.CookRecipeDishes;
|
||||
import com.bonus.canteen.core.cook.service.ICookRecipeDishesService;
|
||||
import com.bonus.canteen.core.order.constants.OrderDetailStateEnum;
|
||||
import com.bonus.canteen.core.order.constants.OrderDetailTypeEnum;
|
||||
import com.bonus.canteen.core.order.constants.OrderRefundStateEnum;
|
||||
import com.bonus.canteen.core.order.constants.OrderStateEnum;
|
||||
import com.bonus.canteen.core.order.domain.OrderDetail;
|
||||
import com.bonus.canteen.core.order.domain.OrderInfo;
|
||||
import com.bonus.canteen.core.order.domain.OrderPayDTO;
|
||||
import com.bonus.canteen.core.order.domain.OrderPayResultDTO;
|
||||
import com.bonus.canteen.core.order.domain.param.OrderPartRefundDetailParam;
|
||||
import com.bonus.canteen.core.order.domain.param.OrderPartRefundParam;
|
||||
import com.bonus.canteen.core.order.mapper.OrderInfoMapper;
|
||||
import com.bonus.canteen.core.order.mq.bo.DeviceRefundOrderBO;
|
||||
import com.bonus.canteen.core.order.mq.bo.DeviceRefundOrderDetailBO;
|
||||
import com.bonus.canteen.core.order.service.IOrderDetailService;
|
||||
import com.bonus.canteen.core.pay.constants.PayChannelEnum;
|
||||
import com.bonus.canteen.core.pay.constants.PayStateEnum;
|
||||
import com.bonus.canteen.core.pay.constants.PayTypeEnum;
|
||||
import com.bonus.canteen.core.user.domain.DeviceMqPersonalUpdateMessageDTO;
|
||||
import com.bonus.common.core.exception.ServiceException;
|
||||
import com.bonus.common.core.utils.DateUtils;
|
||||
import com.bonus.common.core.utils.StringUtils;
|
||||
import com.bonus.common.houqin.mq.constant.LeMqConstant;
|
||||
import com.bonus.common.houqin.utils.JacksonUtil;
|
||||
import com.bonus.common.security.utils.SecurityUtils;
|
||||
|
|
@ -34,12 +45,15 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class OrderBusiness {
|
||||
private static final Logger log = LoggerFactory.getLogger(OrderBusiness.class);
|
||||
private static final String ORDER_REFUND_REDIS_KEY = "sc:order_refund_orderId_%s";
|
||||
|
||||
@Autowired
|
||||
private IOrderDetailService orderDetailService;
|
||||
|
|
@ -49,6 +63,8 @@ public class OrderBusiness {
|
|||
private ICookRecipeDishesService cookRecipeDishesService;
|
||||
@Autowired
|
||||
private IAccWalletInfoService accWalletInfoService;
|
||||
@Autowired
|
||||
private IAccTradeService accTradeService;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<OrderInfo> orderPlaceHandler(List<OrderInfo> orderInfoList) {
|
||||
|
|
@ -202,4 +218,200 @@ public class OrderBusiness {
|
|||
.findFirst()
|
||||
.orElse(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = {Exception.class})
|
||||
public List<DeviceRefundOrderDetailBO> partRefund(OrderPartRefundParam param, OrderInfo orderInfo) {
|
||||
if(Objects.isNull(orderInfo)) {
|
||||
throw new ServiceException("订单不存在");
|
||||
}
|
||||
String refundKey = String.format(ORDER_REFUND_REDIS_KEY, param.getOrderId());
|
||||
if (!RedisUtil.setNx(refundKey, 1, 2)) {
|
||||
log.info("退单处理中:{}", refundKey);
|
||||
throw new ServiceException("退单处理中");
|
||||
}
|
||||
if(orderInfo.getOrderRefundState().equals(OrderRefundStateEnum.FINISH.getKey())) {
|
||||
throw new ServiceException("订单已退");
|
||||
}
|
||||
if(orderInfo.getOrderState().equals(OrderStateEnum.CANCEL.getKey())) {
|
||||
throw new ServiceException("订单已取消");
|
||||
}
|
||||
// if(orderInfo.getOrderState().equals(OrderStateEnum.FINISH.getKey())) {
|
||||
// throw new ServiceException("订单已核销");
|
||||
// }
|
||||
List<OrderDetail> orderRefundDetailList = new ArrayList<>();
|
||||
List<DeviceRefundOrderDetailBO> deviceRefundOrderDetailList = new ArrayList<>();
|
||||
if(PayStateEnum.PAY_SUCC.getKey().equals(orderInfo.getPayState())) {
|
||||
List<TradeAndWalletInfo> accTradeList = accTradeService.queryTradeAndWallerInfoByOrderNo
|
||||
(String.valueOf(param.getOrderId()), AccTradeTypeEnum.CONSUME);
|
||||
if(CollUtil.isEmpty(accTradeList)) {
|
||||
throw new ServiceException("订单交易记录不存在");
|
||||
}
|
||||
BigDecimal refundAmount = BigDecimal.ZERO;
|
||||
|
||||
List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
|
||||
for(OrderPartRefundDetailParam detailParam : param.getOrderPartRefundDetailList()) {
|
||||
OrderDetail orderDetail = orderDetailList.stream()
|
||||
.filter(detail -> detail.getDetailId()
|
||||
.equals(detailParam.getDetailId())).findFirst().orElse(null);
|
||||
if(orderDetail == null) {
|
||||
throw new ServiceException("订单明细不存在");
|
||||
}
|
||||
if(orderDetail.getQuantity() < detailParam.getQuantity()) {
|
||||
throw new ServiceException("退菜数量不能大于订单数量");
|
||||
}
|
||||
BigDecimal detailRefundAmount = orderDetail.getFinalPrice().multiply(new BigDecimal(detailParam.getQuantity()));
|
||||
refundAmount = refundAmount.add(detailRefundAmount);
|
||||
orderDetail.setRefundAmount(detailRefundAmount);
|
||||
orderDetail.setRefundNum(detailParam.getQuantity());
|
||||
if(detailParam.getQuantity().equals(orderDetail.getQuantity())){
|
||||
orderDetail.setDetailState(OrderDetailStateEnum.REFUNDED.getKey());
|
||||
}else {
|
||||
orderDetail.setDetailState(OrderDetailStateEnum.PART_REFUND.getKey());
|
||||
}
|
||||
orderDetail.setUpdateBy(SecurityUtils.getUsername());
|
||||
orderDetailService.updateOrderDetail(orderDetail);
|
||||
orderRefundDetailList.add(orderDetail);
|
||||
DeviceRefundOrderDetailBO orderDetailBO = new DeviceRefundOrderDetailBO();
|
||||
orderDetailBO.setQuantity(detailParam.getQuantity());
|
||||
orderDetailBO.setGoodsId(orderDetail.getGoodsId());
|
||||
deviceRefundOrderDetailList.add(orderDetailBO);
|
||||
}
|
||||
OrderInfo refundOrderInfo = new OrderInfo();
|
||||
refundOrderInfo.setOrderId(param.getOrderId());
|
||||
refundOrderInfo.setRefundAmount(refundAmount);
|
||||
if(orderInfo.getRealAmount().equals(refundAmount)){
|
||||
refundOrderInfo.setOrderRefundState(OrderRefundStateEnum.FINISH.getKey());
|
||||
refundOrderInfo.setOrderState(OrderStateEnum.CANCEL.getKey());
|
||||
}else {
|
||||
refundOrderInfo.setOrderRefundState(OrderRefundStateEnum.PART_SUCC.getKey());
|
||||
}
|
||||
refundOrderInfo.setUpdateBy(SecurityUtils.getUsername());
|
||||
refundOrderInfo.setUpdateTime(DateUtils.getNowDate());
|
||||
orderInfoMapper.updateOrderInfo(refundOrderInfo);
|
||||
|
||||
TradeAndWalletInfo tradeAndWalletInfo = accTradeList.stream()
|
||||
.filter(trade -> PayStateEnum.PAY_SUCC.getKey().equals(trade.getPayState())
|
||||
&& AccWalletTypeEnum.WALLET.getKey().equals(trade.getWalletType()))
|
||||
.findFirst().orElse(null);
|
||||
if(Objects.nonNull(tradeAndWalletInfo)) {
|
||||
if(tradeAndWalletInfo.getActualAmount().compareTo(refundAmount) >= 0) {
|
||||
refundToWallet(param, refundAmount, orderInfo, tradeAndWalletInfo);
|
||||
}else {
|
||||
TradeAndWalletInfo tradeAndSubsidyInfo = accTradeList.stream()
|
||||
.filter(trade -> PayStateEnum.PAY_SUCC.getKey().equals(trade.getPayState())
|
||||
&& AccWalletTypeEnum.SUBSIDY.getKey().equals(trade.getWalletType()))
|
||||
.findFirst().orElse(null);
|
||||
refundToWallet(param, tradeAndWalletInfo.getActualAmount(), orderInfo, tradeAndWalletInfo);
|
||||
|
||||
if(Objects.nonNull(tradeAndSubsidyInfo)) {
|
||||
refundToWallet(param, refundAmount.subtract(tradeAndWalletInfo.getActualAmount())
|
||||
, orderInfo, tradeAndSubsidyInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else {
|
||||
throw new ServiceException("订单未支付");
|
||||
}
|
||||
if (CollUtil.isNotEmpty(orderRefundDetailList)) {
|
||||
addMenuDishSupplyNum(orderRefundDetailList);
|
||||
}
|
||||
return deviceRefundOrderDetailList;
|
||||
}
|
||||
|
||||
private void refundToWallet(OrderPartRefundParam param, BigDecimal refundAmount
|
||||
, OrderInfo orderInfo, TradeAndWalletInfo tradeAndWalletInfo) {
|
||||
WalletUpdateDTO walletUpdateDTO = new WalletUpdateDTO();
|
||||
walletUpdateDTO.setAmount(refundAmount);
|
||||
walletUpdateDTO.setUserId(orderInfo.getUserId());
|
||||
walletUpdateDTO.setAccWalletTypeEnum(AccWalletTypeEnum.getEnum(tradeAndWalletInfo.getWalletType()));
|
||||
walletUpdateDTO.setAccTradeTypeEnum(AccTradeTypeEnum.CONSUME_REFUND);
|
||||
walletUpdateDTO.setPayChannelEnum(PayChannelEnum.ACC);
|
||||
walletUpdateDTO.setPayTypeEnum(PayTypeEnum.MEAL_CARD);
|
||||
walletUpdateDTO.setOrderNo(param.getOrderId());
|
||||
walletUpdateDTO.setDeviceSn(orderInfo.getDeviceSn());
|
||||
walletUpdateDTO.setOperationUser(SecurityUtils.getUsername());
|
||||
accWalletInfoService.addAccWalletBalance(walletUpdateDTO);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = {Exception.class})
|
||||
public boolean refund(String operationUser, OrderInfo orderInfo) {
|
||||
if(Objects.isNull(orderInfo)) {
|
||||
throw new ServiceException("订单不存在");
|
||||
}
|
||||
String refundKey = String.format(ORDER_REFUND_REDIS_KEY, orderInfo.getOrderId());
|
||||
if (!RedisUtil.setNx(refundKey, 1, 2)) {
|
||||
log.info("退单处理中:{}", refundKey);
|
||||
throw new ServiceException("退单处理中");
|
||||
}
|
||||
if(orderInfo.getOrderRefundState().equals(OrderRefundStateEnum.FINISH.getKey())) {
|
||||
throw new ServiceException("订单已退");
|
||||
}
|
||||
if(orderInfo.getOrderState().equals(OrderStateEnum.CANCEL.getKey())) {
|
||||
throw new ServiceException("订单已取消");
|
||||
}
|
||||
if(orderInfo.getOrderRefundState().equals(OrderRefundStateEnum.PART_SUCC.getKey())) {
|
||||
throw new ServiceException("已部分退单");
|
||||
}
|
||||
// if(orderInfo.getOrderState().equals(OrderStateEnum.FINISH.getKey())) {
|
||||
// throw new ServiceException("订单已核销");
|
||||
// }
|
||||
List<OrderDetail> orderDetailList = null;
|
||||
boolean isSendMQ = false;
|
||||
if(PayStateEnum.PAY_SUCC.getKey().equals(orderInfo.getPayState())) {
|
||||
List<TradeAndWalletInfo> accTradeList = accTradeService.queryTradeAndWallerInfoByOrderNo
|
||||
(String.valueOf(orderInfo.getOrderId()), AccTradeTypeEnum.CONSUME);
|
||||
if(CollUtil.isEmpty(accTradeList)) {
|
||||
throw new ServiceException("订单交易记录不存在");
|
||||
}
|
||||
BigDecimal refundAmount = BigDecimal.ZERO;
|
||||
for(TradeAndWalletInfo accTrade : accTradeList) {
|
||||
if(PayStateEnum.PAY_SUCC.getKey().equals(accTrade.getPayState())) {
|
||||
WalletUpdateDTO walletUpdateDTO = new WalletUpdateDTO();
|
||||
walletUpdateDTO.setAmount(accTrade.getActualAmount());
|
||||
walletUpdateDTO.setUserId(orderInfo.getUserId());
|
||||
walletUpdateDTO.setAccWalletTypeEnum(AccWalletTypeEnum.getEnum(accTrade.getWalletType()));
|
||||
walletUpdateDTO.setAccTradeTypeEnum(AccTradeTypeEnum.CONSUME_REFUND);
|
||||
walletUpdateDTO.setPayChannelEnum(PayChannelEnum.ACC);
|
||||
walletUpdateDTO.setPayTypeEnum(PayTypeEnum.MEAL_CARD);
|
||||
walletUpdateDTO.setOrderNo(orderInfo.getOrderId());
|
||||
walletUpdateDTO.setDeviceSn(orderInfo.getDeviceSn());
|
||||
walletUpdateDTO.setOperationUser(operationUser);
|
||||
accWalletInfoService.addAccWalletBalance(walletUpdateDTO);
|
||||
refundAmount = refundAmount.add(accTrade.getActualAmount());
|
||||
}
|
||||
}
|
||||
OrderInfo refundOrderInfo = new OrderInfo();
|
||||
refundOrderInfo.setOrderId(orderInfo.getOrderId());
|
||||
refundOrderInfo.setRefundAmount(refundAmount);
|
||||
refundOrderInfo.setOrderRefundState(OrderRefundStateEnum.FINISH.getKey());
|
||||
refundOrderInfo.setOrderState(OrderStateEnum.CANCEL.getKey());
|
||||
refundOrderInfo.setUpdateBy(StringUtils.isBlank(operationUser) ? SecurityUtils.getUsername() : operationUser);
|
||||
refundOrderInfo.setUpdateTime(DateUtils.getNowDate());
|
||||
orderInfoMapper.updateOrderInfo(refundOrderInfo);
|
||||
orderDetailList = orderInfo.getOrderDetailList();
|
||||
for(OrderDetail orderDetail : orderDetailList) {
|
||||
orderDetail.setRefundAmount(orderDetail.getRealAmount());
|
||||
orderDetail.setRefundNum(orderDetail.getQuantity());
|
||||
orderDetail.setDetailState(OrderDetailStateEnum.REFUNDED.getKey());
|
||||
orderDetail.setUpdateBy(StringUtils.isBlank(operationUser) ? SecurityUtils.getUsername() : operationUser);
|
||||
orderDetailService.updateOrderDetail(orderDetail);
|
||||
}
|
||||
isSendMQ = true;
|
||||
}else {
|
||||
OrderInfo refundOrderInfo = new OrderInfo();
|
||||
refundOrderInfo.setOrderId(orderInfo.getOrderId());
|
||||
refundOrderInfo.setOrderRefundState(OrderRefundStateEnum.FINISH.getKey());
|
||||
refundOrderInfo.setOrderState(OrderStateEnum.CANCEL.getKey());
|
||||
refundOrderInfo.setUpdateBy(StringUtils.isBlank(operationUser) ? SecurityUtils.getUsername() : operationUser);
|
||||
refundOrderInfo.setUpdateTime(DateUtils.getNowDate());
|
||||
orderInfoMapper.updateOrderInfo(refundOrderInfo);
|
||||
OrderDetail orderDetailQuery = new OrderDetail();
|
||||
orderDetailQuery.setOrderId(orderInfo.getOrderId());
|
||||
orderDetailList = orderDetailService.selectOrderDetailList(orderDetailQuery);
|
||||
}
|
||||
if (orderDetailList != null) {
|
||||
addMenuDishSupplyNum(orderDetailList);
|
||||
}
|
||||
return isSendMQ;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,6 +176,15 @@ public class OrderInfoController extends BaseController
|
|||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@SysLog(title = "部分退单", module = "订单", businessType = OperaType.UPDATE)
|
||||
@PostMapping("/part_refund")
|
||||
@ResponseBody
|
||||
public AjaxResult partRefund(@RequestBody @Valid OrderPartRefundParam param)
|
||||
{
|
||||
orderInfoService.partRefund(param);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@SysLog(title = "退单", module = "订单", businessType = OperaType.UPDATE)
|
||||
@PostMapping("/device/refund")
|
||||
@ResponseBody
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package com.bonus.canteen.core.order.domain.param;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Data
|
||||
public class OrderPartRefundDetailParam {
|
||||
@NotNull(message = "订单详情ID不能为空")
|
||||
private Long detailId;
|
||||
@NotNull(message = "订单退款数量不能为空")
|
||||
@Min(value = 1, message = "订单退款数量不能小于1")
|
||||
private Integer quantity;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.bonus.canteen.core.order.domain.param;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.DecimalMin;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class OrderPartRefundParam {
|
||||
@NotNull(message = "订单ID不能为空")
|
||||
private Long orderId;
|
||||
@Valid
|
||||
@NotNull(message = "订单退款详情不能为空")
|
||||
List<OrderPartRefundDetailParam> orderPartRefundDetailList;
|
||||
|
||||
}
|
||||
|
|
@ -2,7 +2,11 @@ package com.bonus.canteen.core.order.mq.bo;
|
|||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class DeviceRefundOrderBO {
|
||||
private String deviceOrderId;
|
||||
private Integer type;
|
||||
List<DeviceRefundOrderDetailBO> deviceRefundOrderDetailBOList;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
package com.bonus.canteen.core.order.mq.bo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DeviceRefundOrderDetailBO {
|
||||
private Long goodsId;
|
||||
private Integer quantity;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.bonus.canteen.core.order.mq.constant;
|
||||
|
||||
|
||||
public enum MQOrderRefundTypeEnum {
|
||||
ALL_REFUND(1, "整单退"),
|
||||
PART_REFUND(2, "部分退");
|
||||
|
||||
private final Integer key;
|
||||
private final String desc;
|
||||
|
||||
private MQOrderRefundTypeEnum(Integer key, String desc) {
|
||||
this.key = key;
|
||||
this.desc = desc;
|
||||
}
|
||||
public Integer getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return this.desc;
|
||||
}
|
||||
}
|
||||
|
|
@ -67,6 +67,7 @@ public interface IOrderInfoService
|
|||
public int deleteOrderInfoByOrderId(Long orderId);
|
||||
|
||||
public void refund(Long orderId, String operationUser, boolean isSendDeviceRefundMQ);
|
||||
public void partRefund(OrderPartRefundParam param);
|
||||
public void pay(Long orderId);
|
||||
List<OrderRefundHistoryVO> orderRefundHistory(OrderRefundHistoryParam param);
|
||||
public void writeOffOrderByOrderIds(OrderWriteOffParam param);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import cn.hutool.crypto.digest.DigestUtil;
|
|||
import com.bonus.canteen.core.account.constants.AccTradeTypeEnum;
|
||||
import com.bonus.canteen.core.account.constants.AccWalletTypeEnum;
|
||||
import com.bonus.canteen.core.account.domain.WalletUpdateDTO;
|
||||
import com.bonus.canteen.core.account.domain.bo.TradeAndWallerInfo;
|
||||
import com.bonus.canteen.core.account.domain.bo.TradeAndWalletInfo;
|
||||
import com.bonus.canteen.core.account.domain.vo.AccInfoDetailsVO;
|
||||
import com.bonus.canteen.core.account.service.IAccInfoService;
|
||||
import com.bonus.canteen.core.account.service.IAccTradeService;
|
||||
|
|
@ -25,6 +25,8 @@ import com.bonus.canteen.core.order.domain.OrderRefundHistoryVO;
|
|||
import com.bonus.canteen.core.order.domain.param.*;
|
||||
import com.bonus.canteen.core.order.mapper.OrderInfoMapper;
|
||||
import com.bonus.canteen.core.order.mq.bo.DeviceRefundOrderBO;
|
||||
import com.bonus.canteen.core.order.mq.bo.DeviceRefundOrderDetailBO;
|
||||
import com.bonus.canteen.core.order.mq.constant.MQOrderRefundTypeEnum;
|
||||
import com.bonus.canteen.core.order.mq.utils.OrderMQUtils;
|
||||
import com.bonus.canteen.core.order.service.IOrderDetailService;
|
||||
import com.bonus.canteen.core.order.service.IOrderInfoService;
|
||||
|
|
@ -357,102 +359,56 @@ public class OrderInfoServiceImpl implements IOrderInfoService
|
|||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = {Exception.class})
|
||||
public void refund(Long orderId, String operationUser, boolean isSendDeviceRefundMQ) {
|
||||
if(Objects.isNull(orderId) || orderId <= 0) {
|
||||
throw new ServiceException("订单ID不能为空");
|
||||
}
|
||||
OrderInfo orderInfo = selectOrderInfoByOrderId(orderId);
|
||||
if(Objects.isNull(orderInfo)) {
|
||||
throw new ServiceException("订单不存在");
|
||||
boolean isSendMQ = orderBusiness.refund(operationUser, orderInfo);
|
||||
if(!isSendMQ){
|
||||
return;
|
||||
}
|
||||
String refundKey = String.format(ORDER_REFUND_REDIS_KEY, orderId);
|
||||
if (!RedisUtil.setNx(refundKey, 1, 2)) {
|
||||
log.info("退单处理中:{}", refundKey);
|
||||
throw new ServiceException("退单处理中");
|
||||
}
|
||||
if(orderInfo.getOrderRefundState().equals(OrderRefundStateEnum.FINISH.getKey())) {
|
||||
throw new ServiceException("订单已退");
|
||||
}
|
||||
if(orderInfo.getOrderState().equals(OrderStateEnum.CANCEL.getKey())) {
|
||||
throw new ServiceException("订单已取消");
|
||||
}
|
||||
// if(orderInfo.getOrderState().equals(OrderStateEnum.FINISH.getKey())) {
|
||||
// throw new ServiceException("订单已核销");
|
||||
// }
|
||||
List<OrderDetail> orderDetailList = null;
|
||||
if(PayStateEnum.PAY_SUCC.getKey().equals(orderInfo.getPayState())) {
|
||||
List<TradeAndWallerInfo> accTradeList = accTradeService.queryTradeAndWallerInfoByOrderNo
|
||||
(String.valueOf(orderId), AccTradeTypeEnum.CONSUME);
|
||||
if(CollUtil.isEmpty(accTradeList)) {
|
||||
throw new ServiceException("订单交易记录不存在");
|
||||
try {
|
||||
DeviceMqPersonalUpdateMessageDTO bean = new DeviceMqPersonalUpdateMessageDTO().setUpdatePerson(Math.toIntExact(orderInfo.getUserId()),"update");
|
||||
String jsonString = JacksonUtil.writeValueAsString(bean);
|
||||
log.info("账户变动发送mq内容:{}", jsonString);
|
||||
MqUtil.pushToTenantAllDevice(bean, LeMqConstant.Topic.DEVICE_UPDATE_PERSONAL_CONFIG_V4);
|
||||
if(StringUtils.isNotBlank(orderInfo.getDeviceOrderId()) && isSendDeviceRefundMQ) {
|
||||
DeviceRefundOrderBO deviceRefundOrderBO = new DeviceRefundOrderBO();
|
||||
deviceRefundOrderBO.setDeviceOrderId(orderInfo.getDeviceOrderId());
|
||||
deviceRefundOrderBO.setType(MQOrderRefundTypeEnum.ALL_REFUND.getKey());
|
||||
String deviceJsonString = JacksonUtil.writeValueAsString(deviceRefundOrderBO);
|
||||
log.info("设备订单退款发送mq内容:{}", deviceJsonString);
|
||||
MqUtil.pushToTenantAllDevice(deviceRefundOrderBO, LeMqConstant.Topic.DEVICE_UPDATE_ORDER_STATE_V4);
|
||||
}
|
||||
BigDecimal refundAmount = BigDecimal.ZERO;
|
||||
for(TradeAndWallerInfo accTrade : accTradeList) {
|
||||
if(PayStateEnum.PAY_SUCC.getKey().equals(accTrade.getPayState())) {
|
||||
WalletUpdateDTO walletUpdateDTO = new WalletUpdateDTO();
|
||||
walletUpdateDTO.setAmount(accTrade.getActualAmount());
|
||||
walletUpdateDTO.setUserId(orderInfo.getUserId());
|
||||
walletUpdateDTO.setAccWalletTypeEnum(AccWalletTypeEnum.getEnum(accTrade.getWalletType()));
|
||||
walletUpdateDTO.setAccTradeTypeEnum(AccTradeTypeEnum.CONSUME_REFUND);
|
||||
walletUpdateDTO.setPayChannelEnum(PayChannelEnum.ACC);
|
||||
walletUpdateDTO.setPayTypeEnum(PayTypeEnum.MEAL_CARD);
|
||||
walletUpdateDTO.setOrderNo(orderId);
|
||||
walletUpdateDTO.setDeviceSn(orderInfo.getDeviceSn());
|
||||
walletUpdateDTO.setOperationUser(operationUser);
|
||||
accWalletInfoService.addAccWalletBalance(walletUpdateDTO);
|
||||
refundAmount = refundAmount.add(accTrade.getActualAmount());
|
||||
}
|
||||
}
|
||||
OrderInfo refundOrderInfo = new OrderInfo();
|
||||
refundOrderInfo.setOrderId(orderId);
|
||||
refundOrderInfo.setRefundAmount(refundAmount);
|
||||
refundOrderInfo.setOrderRefundState(OrderRefundStateEnum.FINISH.getKey());
|
||||
refundOrderInfo.setOrderState(OrderStateEnum.CANCEL.getKey());
|
||||
refundOrderInfo.setUpdateBy(StringUtils.isBlank(operationUser) ? SecurityUtils.getUsername() : operationUser);
|
||||
refundOrderInfo.setUpdateTime(DateUtils.getNowDate());
|
||||
orderInfoMapper.updateOrderInfo(refundOrderInfo);
|
||||
OrderDetail orderDetailQuery = new OrderDetail();
|
||||
orderDetailQuery.setOrderId(orderId);
|
||||
orderDetailList = orderDetailService.selectOrderDetailList(orderDetailQuery);
|
||||
for(OrderDetail orderDetail : orderDetailList) {
|
||||
orderDetail.setRefundAmount(orderDetail.getRealAmount());
|
||||
orderDetail.setRefundNum(orderDetail.getQuantity());
|
||||
orderDetail.setDetailState(OrderDetailStateEnum.REFUNDED.getKey());
|
||||
orderDetail.setUpdateBy(StringUtils.isBlank(operationUser) ? SecurityUtils.getUsername() : operationUser);
|
||||
orderDetailService.updateOrderDetail(orderDetail);
|
||||
}
|
||||
try {
|
||||
DeviceMqPersonalUpdateMessageDTO bean = new DeviceMqPersonalUpdateMessageDTO().setUpdatePerson(Math.toIntExact(orderInfo.getUserId()),"update");
|
||||
String jsonString = JacksonUtil.writeValueAsString(bean);
|
||||
log.info("账户变动发送mq内容:{}", jsonString);
|
||||
MqUtil.pushToTenantAllDevice(bean, LeMqConstant.Topic.DEVICE_UPDATE_PERSONAL_CONFIG_V4);
|
||||
if(StringUtils.isNotBlank(orderInfo.getDeviceOrderId()) && isSendDeviceRefundMQ) {
|
||||
DeviceRefundOrderBO deviceRefundOrderBO = new DeviceRefundOrderBO();
|
||||
deviceRefundOrderBO.setDeviceOrderId(orderInfo.getDeviceOrderId());
|
||||
String deviceJsonString = JacksonUtil.writeValueAsString(deviceRefundOrderBO);
|
||||
log.info("设备订单退款发送mq内容:{}", deviceJsonString);
|
||||
MqUtil.pushToTenantAllDevice(deviceRefundOrderBO, LeMqConstant.Topic.DEVICE_UPDATE_ORDER_STATE_V4);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("发送MQ消息失败", e);
|
||||
}
|
||||
}else {
|
||||
OrderInfo refundOrderInfo = new OrderInfo();
|
||||
refundOrderInfo.setOrderId(orderId);
|
||||
refundOrderInfo.setOrderRefundState(OrderRefundStateEnum.FINISH.getKey());
|
||||
refundOrderInfo.setOrderState(OrderStateEnum.CANCEL.getKey());
|
||||
refundOrderInfo.setUpdateBy(StringUtils.isBlank(operationUser) ? SecurityUtils.getUsername() : operationUser);
|
||||
refundOrderInfo.setUpdateTime(DateUtils.getNowDate());
|
||||
orderInfoMapper.updateOrderInfo(refundOrderInfo);
|
||||
OrderDetail orderDetailQuery = new OrderDetail();
|
||||
orderDetailQuery.setOrderId(orderId);
|
||||
orderDetailList = orderDetailService.selectOrderDetailList(orderDetailQuery);
|
||||
}
|
||||
if (orderDetailList != null) {
|
||||
orderBusiness.addMenuDishSupplyNum(orderDetailList);
|
||||
} catch (Exception e) {
|
||||
log.error("发送MQ消息失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void partRefund(OrderPartRefundParam param) {
|
||||
OrderInfo orderInfo = selectOrderInfoByOrderId(param.getOrderId());
|
||||
List<DeviceRefundOrderDetailBO> orderDetailList = orderBusiness.partRefund(param, orderInfo);
|
||||
try {
|
||||
DeviceMqPersonalUpdateMessageDTO bean = new DeviceMqPersonalUpdateMessageDTO().setUpdatePerson(Math.toIntExact(orderInfo.getUserId()),"update");
|
||||
String jsonString = JacksonUtil.writeValueAsString(bean);
|
||||
log.info("账户变动发送mq内容:{}", jsonString);
|
||||
MqUtil.pushToTenantAllDevice(bean, LeMqConstant.Topic.DEVICE_UPDATE_PERSONAL_CONFIG_V4);
|
||||
if(StringUtils.isNotBlank(orderInfo.getDeviceOrderId())) {
|
||||
DeviceRefundOrderBO deviceRefundOrderBO = new DeviceRefundOrderBO();
|
||||
deviceRefundOrderBO.setDeviceOrderId(orderInfo.getDeviceOrderId());
|
||||
deviceRefundOrderBO.setDeviceRefundOrderDetailBOList(orderDetailList);
|
||||
deviceRefundOrderBO.setType(MQOrderRefundTypeEnum.PART_REFUND.getKey());
|
||||
String deviceJsonString = JacksonUtil.writeValueAsString(deviceRefundOrderBO);
|
||||
log.info("设备订单部分退款发送mq内容:{}", deviceJsonString);
|
||||
MqUtil.pushToTenantAllDevice(deviceRefundOrderBO, LeMqConstant.Topic.DEVICE_UPDATE_ORDER_STATE_V4);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("发送MQ消息失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = {Exception.class})
|
||||
public void timeOutCancel(Long orderId, String operationUser) {
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
order by atwd.id desc
|
||||
</select>
|
||||
|
||||
<select id="queryTradeAndWallerInfoByOrderNo" resultType="com.bonus.canteen.core.account.domain.bo.TradeAndWallerInfo">
|
||||
<select id="queryTradeAndWallerInfoByOrderNo" resultType="com.bonus.canteen.core.account.domain.bo.TradeAndWalletInfo">
|
||||
select
|
||||
ate.trade_id,
|
||||
ate.actual_amount,
|
||||
|
|
|
|||
Loading…
Reference in New Issue