【功能优化】商城:拼团中时,禁止发起售后

pull/140/head
YunaiV 2024-09-07 14:07:16 +08:00
parent d2f0c00d8f
commit ef3d712e42
8 changed files with 143 additions and 19 deletions

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.api.combination;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO;
import cn.iocoder.yudao.module.promotion.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
@ -43,14 +44,14 @@ public interface CombinationRecordApi {
CommonResult<CombinationRecordCreateRespDTO> createCombinationRecord(
@RequestBody @Valid CombinationRecordCreateReqDTO reqDTO);
@GetMapping(PREFIX + "/is-success")
@Operation(summary = "查询拼团记录是否成功")
@GetMapping(PREFIX + "/get-by-order-id")
@Operation(summary = "基于订单编号,查询拼团记录")
@Parameters({
@Parameter(name = "userId", description = "用户编号", required = true, example = "1024"),
@Parameter(name = "orderId", description = "订单编号", required = true, example = "2048"),
})
CommonResult<Boolean> isCombinationRecordSuccess(@RequestParam("userId") Long userId,
@RequestParam("orderId") Long orderId);
CommonResult<CombinationRecordRespDTO> getCombinationRecordByOrderId(@RequestParam("userId") Long userId,
@RequestParam("orderId") Long orderId);
@GetMapping(PREFIX + "/validate-join")
@Operation(summary = "【下单前】校验是否满足拼团活动条件") // 如果校验失败,则抛出业务异常

View File

@ -1,8 +1,7 @@
package cn.iocoder.yudao.module.promotion.api.combination.dto;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* Request DTO

View File

@ -0,0 +1,110 @@
package cn.iocoder.yudao.module.promotion.api.combination.dto;
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
import lombok.Data;
import java.time.LocalDateTime;
/**
* Response DTO
*
* @author
*/
@Data
public class CombinationRecordRespDTO {
/**
*
*/
private Long id;
/**
*
*
* CombinationActivityDO id
*/
private Long activityId;
/**
*
*
* CombinationProductDO combinationPrice
*/
private Integer combinationPrice;
/**
* SPU
*/
private Long spuId;
/**
*
*/
private String spuName;
/**
*
*/
private String picUrl;
/**
* SKU
*/
private Long skuId;
/**
*
*/
private Integer count;
/**
*
*/
private Long userId;
/**
*
*/
private String nickname;
/**
*
*/
private String avatar;
/**
*
*/
private Long headId;
/**
*
*
* {@link CombinationRecordStatusEnum}
*/
private Integer status;
/**
*
*/
private Long orderId;
/**
*
*
* CombinationActivityDO userSize
*/
private Integer userSize;
/**
*
*/
private Integer userCount;
/**
*
*/
private Boolean virtualGroup;
/**
*
*/
private LocalDateTime expireTime;
/**
* ()
*/
private LocalDateTime startTime;
/**
* /
*/
private LocalDateTime endTime;
}

View File

@ -1,21 +1,19 @@
package cn.iocoder.yudao.module.promotion.api.combination;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO;
import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_RECORD_NOT_EXISTS;
/**
* API
@ -41,12 +39,9 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
}
@Override
public CommonResult<Boolean> isCombinationRecordSuccess(Long userId, Long orderId) {
public CommonResult<CombinationRecordRespDTO> getCombinationRecordByOrderId(Long userId, Long orderId) {
CombinationRecordDO record = combinationRecordService.getCombinationRecord(userId, orderId);
if (record == null) {
throw exception(COMBINATION_RECORD_NOT_EXISTS);
}
return success(CombinationRecordStatusEnum.isSuccess(record.getStatus()));
return success(BeanUtils.toBean(record, CombinationRecordRespDTO.class));
}
@Override

View File

@ -51,6 +51,7 @@ public interface ErrorCodeConstants {
ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1_011_000_110, "退款失败,售后单状态不是【待退款】");
ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE_OR_BUYER_DELIVERY =
new ErrorCode(1_011_000_111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】或【商家待收货】");
ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_COMBINATION_IN_PROGRESS = new ErrorCode(1_011_000_112, "订单拼团中,无法申请售后");
// ========== Cart 模块 1-011-002-000 ==========
ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1_011_002_000, "购物车项不存在");

View File

@ -8,6 +8,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleDisagreeReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleRefuseReqVO;
@ -26,6 +29,7 @@ import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleTypeEnum;
import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleWayEnum;
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
import cn.iocoder.yudao.module.trade.framework.aftersale.core.annotations.AfterSaleLog;
import cn.iocoder.yudao.module.trade.framework.aftersale.core.utils.AfterSaleLogUtils;
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
@ -71,6 +75,8 @@ public class AfterSaleServiceImpl implements AfterSaleService {
@Resource
private PayRefundApi payRefundApi;
@Resource
private CombinationRecordApi combinationRecordApi;
@Resource
private TradeOrderProperties tradeOrderProperties;
@ -148,6 +154,14 @@ public class AfterSaleServiceImpl implements AfterSaleService {
&& !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED);
}
// 如果是拼团订单,则进行中不允许售后
if (TradeOrderTypeEnum.isCombination(order.getType())) {
CombinationRecordRespDTO combinationRecord = combinationRecordApi.getCombinationRecordByOrderId(
order.getUserId(), order.getId()).getCheckedData();
if (combinationRecord != null && CombinationRecordStatusEnum.isInProgress(combinationRecord.getStatus())) {
throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_COMBINATION_IN_PROGRESS);
}
}
return orderItem;
}

View File

@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.trade.service.order.handler;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO;
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
@ -49,7 +51,7 @@ public class TradeCombinationOrderHandler implements TradeOrderHandler {
// 1. 校验是否满足拼团活动相关限制
TradeOrderItemDO item = orderItems.get(0);
combinationRecordApi.validateCombinationRecord(order.getUserId(), order.getCombinationActivityId(),
order.getCombinationHeadId(), item.getSkuId(), item.getCount()).checkError();
order.getCombinationHeadId(), item.getSkuId(), item.getCount());
// 2. 校验该用户是否存在未支付的拼团活动订单,避免一个拼团可以下多个单子了
TradeOrderDO activityOrder = orderQueryService.getOrderByUserIdAndStatusAndCombination(
@ -84,7 +86,9 @@ public class TradeCombinationOrderHandler implements TradeOrderHandler {
return;
}
// 校验订单拼团是否成功
if (!combinationRecordApi.isCombinationRecordSuccess(order.getUserId(), order.getId()).getCheckedData()) {
CombinationRecordRespDTO combinationRecord = combinationRecordApi.getCombinationRecordByOrderId(order.getUserId(), order.getId()).getCheckedData();
Assert.notNull(combinationRecord, "订单({})对应的拼团记录不存在", order.getId());
if (!CombinationRecordStatusEnum.isSuccess(combinationRecord.getStatus())) {
throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS);
}
}

View File

@ -43,7 +43,7 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator {
public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
// 只有【普通】订单,才允许使用优惠劵
if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) {
if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) {
if (param.getCouponId() != null) {
throw exception(PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER);
}
return;