diff --git a/yudao-module-mall/yudao-module-product/pom.xml b/yudao-module-mall/yudao-module-product/pom.xml
index 07bd9d05..2382f541 100644
--- a/yudao-module-mall/yudao-module-product/pom.xml
+++ b/yudao-module-mall/yudao-module-product/pom.xml
@@ -25,6 +25,10 @@
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-biz-tenant
+
diff --git a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java
index 47c0e70a..0f263b85 100644
--- a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java
+++ b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.product.dal.dataobject.brand;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -20,7 +20,7 @@ import lombok.*;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ProductBrandDO extends BaseDO {
+public class ProductBrandDO extends TenantBaseDO {
/**
* 品牌编号
diff --git a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java
index 69d2fb30..891965a7 100644
--- a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java
+++ b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.product.dal.dataobject.category;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -20,7 +20,7 @@ import lombok.*;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ProductCategoryDO extends BaseDO {
+public class ProductCategoryDO extends TenantBaseDO {
/**
* 父分类编号 - 根分类
diff --git a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java
index ef694db0..8863e12c 100644
--- a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java
+++ b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.product.dal.dataobject.comment;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
@@ -26,7 +26,7 @@ import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ProductCommentDO extends BaseDO {
+public class ProductCommentDO extends TenantBaseDO {
/**
* 默认匿名昵称
diff --git a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java
index c4d9d543..314996e8 100644
--- a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java
+++ b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.product.dal.dataobject.favorite;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -20,7 +20,7 @@ import lombok.*;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ProductFavoriteDO extends BaseDO {
+public class ProductFavoriteDO extends TenantBaseDO {
/**
* 编号,主键自增
diff --git a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/history/ProductBrowseHistoryDO.java b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/history/ProductBrowseHistoryDO.java
index 472574bd..d36188e1 100644
--- a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/history/ProductBrowseHistoryDO.java
+++ b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/history/ProductBrowseHistoryDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.product.dal.dataobject.history;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -19,7 +19,7 @@ import lombok.*;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ProductBrowseHistoryDO extends BaseDO {
+public class ProductBrowseHistoryDO extends TenantBaseDO {
/**
* 记录编号
@@ -39,4 +39,4 @@ public class ProductBrowseHistoryDO extends BaseDO {
*/
private Boolean userDeleted;
-}
\ No newline at end of file
+}
diff --git a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java
index fb75a4db..56a2c2ce 100644
--- a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java
+++ b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.product.dal.dataobject.property;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -19,7 +19,7 @@ import lombok.*;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ProductPropertyDO extends BaseDO {
+public class ProductPropertyDO extends TenantBaseDO {
/**
* SPU 单规格时,默认属性 id
diff --git a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java
index 2e9147c5..867cde54 100644
--- a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java
+++ b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.product.dal.dataobject.property;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -20,7 +20,7 @@ import lombok.*;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ProductPropertyValueDO extends BaseDO {
+public class ProductPropertyValueDO extends TenantBaseDO {
/**
* SPU 单规格时,默认属性值 id
diff --git a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java
index 29397c94..6602e92e 100755
--- a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java
+++ b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.product.dal.dataobject.sku;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
@@ -26,7 +26,7 @@ import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ProductSkuDO extends BaseDO {
+public class ProductSkuDO extends TenantBaseDO {
/**
* 商品 SKU 编号,自增
@@ -131,4 +131,3 @@ public class ProductSkuDO extends BaseDO {
}
}
-
diff --git a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
index 37b01ed9..be094966 100755
--- a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
+++ b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.product.dal.dataobject.spu;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.IntegerListTypeHandler;
import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
@@ -28,7 +28,7 @@ import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ProductSpuDO extends BaseDO {
+public class ProductSpuDO extends TenantBaseDO {
/**
* 商品 SPU 编号,自增
diff --git a/yudao-module-mall/yudao-module-product/src/test/java/cn/iocoder/yudao/module/product/dal/dataobject/ProductTenantContractTest.java b/yudao-module-mall/yudao-module-product/src/test/java/cn/iocoder/yudao/module/product/dal/dataobject/ProductTenantContractTest.java
new file mode 100644
index 00000000..fec5ac5f
--- /dev/null
+++ b/yudao-module-mall/yudao-module-product/src/test/java/cn/iocoder/yudao/module/product/dal/dataobject/ProductTenantContractTest.java
@@ -0,0 +1,32 @@
+package cn.iocoder.yudao.module.product.dal.dataobject;
+
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
+import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
+import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
+import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
+import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO;
+import cn.iocoder.yudao.module.product.dal.dataobject.history.ProductBrowseHistoryDO;
+import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
+import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
+import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
+import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class ProductTenantContractTest {
+
+ @Test
+ void allNativeProductRecordsParticipateInFrameworkTenantIsolation() {
+ assertThat(TenantBaseDO.class).isAssignableFrom(ProductBrandDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(ProductCategoryDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(ProductPropertyDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(ProductPropertyValueDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(ProductSpuDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(ProductSkuDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(ProductCommentDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(ProductFavoriteDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(ProductBrowseHistoryDO.class);
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordCreateReqDTO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordCreateReqDTO.java
index eade5ca1..34b590fb 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordCreateReqDTO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordCreateReqDTO.java
@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.promotion.api.combination.dto;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
+import jakarta.validation.constraints.PositiveOrZero;
/**
* 拼团记录的创建 Request DTO
@@ -16,40 +18,48 @@ public class CombinationRecordCreateReqDTO {
* 拼团活动编号
*/
@NotNull(message = "拼团活动编号不能为空")
+ @Positive(message = "拼团活动编号必须大于 0")
private Long activityId;
/**
* spu 编号
*/
@NotNull(message = "spu 编号不能为空")
+ @Positive(message = "spu 编号必须大于 0")
private Long spuId;
/**
* sku 编号
*/
@NotNull(message = "sku 编号不能为空")
+ @Positive(message = "sku 编号必须大于 0")
private Long skuId;
/**
* 购买的商品数量
*/
@NotNull(message = "购买数量不能为空")
+ @Positive(message = "购买数量必须大于 0")
private Integer count;
/**
* 订单编号
*/
@NotNull(message = "订单编号不能为空")
+ @Positive(message = "订单编号必须大于 0")
private Long orderId;
/**
* 用户编号
*/
@NotNull(message = "用户编号不能为空")
+ @Positive(message = "用户编号必须大于 0")
private Long userId;
/**
* 团长编号
*/
+ @PositiveOrZero(message = "团长编号不能小于 0")
private Long headId;
/**
* 拼团商品单价
*/
@NotNull(message = "拼团商品单价不能为空")
+ @Positive(message = "拼团商品单价必须大于 0")
private Integer combinationPrice;
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityBaseVO.java
index 0c239ccb..598d4acf 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityBaseVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityBaseVO.java
@@ -1,10 +1,15 @@
package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
+import jakarta.validation.constraints.AssertTrue;
+import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
+import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -19,31 +24,38 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
public class BargainActivityBaseVO {
@Schema(description = "砍价活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "砍得越多省得越多,是兄弟就来砍我")
- @NotNull(message = "砍价名称不能为空")
+ @NotBlank(message = "砍价名称不能为空")
+ @Size(max = 255, message = "砍价名称不能超过 255 个字符")
private String name;
@Schema(description = "商品 SPU 编号", example = "1")
@NotNull(message = "砍价商品不能为空")
+ @Positive(message = "砍价商品必须大于 0")
private Long spuId;
@Schema(description = "商品 skuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
@NotNull(message = "商品 skuId 不能为空")
+ @Positive(message = "商品 skuId 必须大于 0")
private Long skuId;
@Schema(description = "砍价起始价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
@NotNull(message = "砍价起始价格不能为空")
+ @Positive(message = "砍价起始价格必须大于 0")
private Integer bargainFirstPrice;
@Schema(description = "砍价底价", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
@NotNull(message = "砍价底价不能为空")
+ @Positive(message = "砍价底价必须大于 0")
private Integer bargainMinPrice;
@Schema(description = "活动库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
@NotNull(message = "活动库存不能为空")
+ @Positive(message = "活动库存必须大于 0")
private Integer stock;
@Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218")
@NotNull(message = "总限购数量不能为空")
+ @Positive(message = "总限购数量必须大于 0")
private Integer totalLimitCount;
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
@@ -58,18 +70,40 @@ public class BargainActivityBaseVO {
@Schema(description = "最大助力次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
@NotNull(message = "最大助力次数不能为空")
+ @Positive(message = "最大助力次数必须大于 0")
private Integer helpMaxCount;
@Schema(description = "最大帮砍次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
@NotNull(message = "最大帮砍次数不能为空")
+ @Positive(message = "最大帮砍次数必须大于 0")
private Integer bargainCount;
@Schema(description = "用户每次砍价的最小金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
@NotNull(message = "用户每次砍价的最小金额不能为空")
+ @Positive(message = "用户每次砍价的最小金额必须大于 0")
private Integer randomMinPrice;
@Schema(description = "用户每次砍价的最大金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
@NotNull(message = "用户每次砍价的最大金额不能为空")
+ @Positive(message = "用户每次砍价的最大金额必须大于 0")
private Integer randomMaxPrice;
+ @AssertTrue(message = "活动结束时间必须晚于开始时间")
+ @JsonIgnore
+ public boolean isActivityTimeValid() {
+ return startTime == null || endTime == null || endTime.isAfter(startTime);
+ }
+
+ @AssertTrue(message = "砍价底价不能高于砍价起始价格")
+ @JsonIgnore
+ public boolean isBargainPriceValid() {
+ return bargainFirstPrice == null || bargainMinPrice == null || bargainMinPrice <= bargainFirstPrice;
+ }
+
+ @AssertTrue(message = "单次砍价最大金额不能小于最小金额")
+ @JsonIgnore
+ public boolean isRandomPriceValid() {
+ return randomMinPrice == null || randomMaxPrice == null || randomMinPrice <= randomMaxPrice;
+ }
+
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityUpdateReqVO.java
index 3f451183..ef954fdd 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityUpdateReqVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityUpdateReqVO.java
@@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
@Schema(description = "管理后台 - 砍价活动更新 Request VO")
@Data
@@ -15,6 +16,7 @@ public class BargainActivityUpdateReqVO extends BargainActivityBaseVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
@NotNull(message = "活动编号不能为空")
+ @Positive(message = "活动编号必须大于 0")
private Long id;
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationActivityController.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationActivityController.java
index 2f9e7863..d68cb2e4 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationActivityController.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationActivityController.java
@@ -93,6 +93,8 @@ public class CombinationActivityController {
@GetMapping("/list-by-ids")
@Operation(summary = "获得拼团活动列表,基于活动编号数组")
@Parameter(name = "ids", description = "活动编号数组", required = true, example = "[1024, 1025]")
+ @PreAuthorize("@ss.hasAnyPermissions('promotion:combination-activity:query', " +
+ "'promotion:diy-page:query', 'promotion:diy-template:query')")
public CommonResult> getCombinationActivityListByIds(@RequestParam("ids") List ids) {
// 1. 获得开启的活动列表
List activityList = combinationActivityService.getCombinationActivityListByIds(ids);
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java
index 624ef169..38971809 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java
@@ -1,10 +1,16 @@
package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
+import jakarta.validation.constraints.AssertTrue;
+import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
+import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -19,19 +25,23 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
public class CombinationActivityBaseVO {
@Schema(description = "拼团名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "越拼越省钱")
- @NotNull(message = "拼团名称不能为空")
+ @NotBlank(message = "拼团名称不能为空")
+ @Size(max = 255, message = "拼团名称不能超过 255 个字符")
private String name;
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "拼团商品不能为空")
+ @Positive(message = "拼团商品必须大于 0")
private Long spuId;
@Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218")
@NotNull(message = "总限购数量不能为空")
+ @Positive(message = "总限购数量必须大于 0")
private Integer totalLimitCount;
@Schema(description = "单次限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "28265")
@NotNull(message = "单次限购数量不能为空")
+ @Positive(message = "单次限购数量必须大于 0")
private Integer singleLimitCount;
@Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
@@ -46,6 +56,7 @@ public class CombinationActivityBaseVO {
@Schema(description = "开团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
@NotNull(message = "开团人数不能为空")
+ @Min(value = 2, message = "开团人数不能小于 2")
private Integer userSize;
@Schema(description = "虚拟成团", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
@@ -54,6 +65,20 @@ public class CombinationActivityBaseVO {
@Schema(description = "限制时长(小时)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "限制时长不能为空")
+ @Positive(message = "限制时长必须大于 0")
private Integer limitDuration;
+ @AssertTrue(message = "活动结束时间必须晚于开始时间")
+ @JsonIgnore
+ public boolean isActivityTimeValid() {
+ return startTime == null || endTime == null || endTime.isAfter(startTime);
+ }
+
+ @AssertTrue(message = "单次限购数量不能超过总限购数量")
+ @JsonIgnore
+ public boolean isLimitCountValid() {
+ return totalLimitCount == null || singleLimitCount == null
+ || singleLimitCount <= totalLimitCount;
+ }
+
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityCreateReqVO.java
index 0081c3fa..0460dca5 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityCreateReqVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityCreateReqVO.java
@@ -7,6 +7,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
import java.util.List;
@Schema(description = "管理后台 - 拼团活动创建 Request VO")
@@ -16,7 +17,7 @@ import java.util.List;
public class CombinationActivityCreateReqVO extends CombinationActivityBaseVO {
@Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
- @Valid
- private List products;
+ @NotEmpty(message = "拼团商品不能为空")
+ private List<@Valid CombinationProductBaseVO> products;
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityUpdateReqVO.java
index 0423a5f2..47028932 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityUpdateReqVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityUpdateReqVO.java
@@ -7,7 +7,9 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
import java.util.List;
@Schema(description = "管理后台 - 拼团活动更新 Request VO")
@@ -18,10 +20,11 @@ public class CombinationActivityUpdateReqVO extends CombinationActivityBaseVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
@NotNull(message = "活动编号不能为空")
+ @Positive(message = "活动编号必须大于 0")
private Long id;
@Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
- @Valid
- private List products;
+ @NotEmpty(message = "拼团商品不能为空")
+ private List<@Valid CombinationProductBaseVO> products;
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductBaseVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductBaseVO.java
index 79693e3d..5e960ba8 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductBaseVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductBaseVO.java
@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
/**
* 拼团商品 Base VO,提供给添加、修改、详细的子 VO 使用
@@ -14,14 +15,17 @@ public class CombinationProductBaseVO {
@Schema(description = "商品 spuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
@NotNull(message = "商品 spuId 不能为空")
+ @Positive(message = "商品 spuId 必须大于 0")
private Long spuId;
@Schema(description = "商品 skuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
@NotNull(message = "商品 skuId 不能为空")
+ @Positive(message = "商品 skuId 必须大于 0")
private Long skuId;
@Schema(description = "拼团价格,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "27682")
@NotNull(message = "拼团价格不能为空")
+ @Positive(message = "拼团价格必须大于 0")
private Integer combinationPrice;
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java
index 349624c5..817d2ad5 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java
@@ -102,6 +102,8 @@ public class SeckillActivityController {
@GetMapping("/list-by-ids")
@Operation(summary = "获得秒杀活动列表,基于活动编号数组")
@Parameter(name = "ids", description = "活动编号数组", required = true, example = "[1024, 1025]")
+ @PreAuthorize("@ss.hasAnyPermissions('promotion:seckill-activity:query', " +
+ "'promotion:diy-page:query', 'promotion:diy-template:query')")
public CommonResult> getSeckillActivityListByIds(@RequestParam("ids") List ids) {
// 1. 获得开启的活动列表
List activityList = seckillActivityService.getSeckillActivityListByIds(ids);
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java
index 6d393257..eb70aa08 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java
@@ -80,6 +80,7 @@ public class SeckillConfigController {
@GetMapping("/simple-list")
@Operation(summary = "获得所有开启状态的秒杀时段精简列表", description = "主要用于前端的下拉选项")
+ @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')")
public CommonResult> getSeckillConfigSimpleList() {
List list = seckillConfigService.getSeckillConfigListByStatus(
CommonStatusEnum.ENABLE.getStatus());
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java
index 3541c368..aa63d40a 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java
@@ -1,10 +1,17 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
+import jakarta.validation.constraints.AssertTrue;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
+import jakarta.validation.constraints.PositiveOrZero;
+import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.List;
@@ -22,10 +29,12 @@ public class SeckillActivityBaseVO {
@Schema(description = "秒杀活动商品 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[121,1212]")
@NotNull(message = "秒杀活动商品不能为空")
+ @Positive(message = "秒杀活动商品必须大于 0")
private Long spuId;
@Schema(description = "秒杀活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618大促")
- @NotNull(message = "秒杀活动名称不能为空")
+ @NotBlank(message = "秒杀活动名称不能为空")
+ @Size(max = 255, message = "秒杀活动名称不能超过 255 个字符")
private String name;
@Schema(description = "备注", example = "清仓大甩卖割韭菜")
@@ -43,16 +52,34 @@ public class SeckillActivityBaseVO {
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "排序不能为空")
+ @PositiveOrZero(message = "排序不能小于 0")
private Integer sort;
@Schema(description = "秒杀时段 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2,3]")
- @NotNull(message = "秒杀时段不能为空")
- private List configIds;
+ @NotEmpty(message = "秒杀时段不能为空")
+ private List<@Positive(message = "秒杀时段编号必须大于 0") Long> configIds;
@Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "12877")
+ @NotNull(message = "总限购数量不能为空")
+ @Positive(message = "总限购数量必须大于 0")
private Integer totalLimitCount;
@Schema(description = "单次限够数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "31683")
+ @NotNull(message = "单次限购数量不能为空")
+ @Positive(message = "单次限购数量必须大于 0")
private Integer singleLimitCount;
+ @AssertTrue(message = "活动结束时间必须晚于开始时间")
+ @JsonIgnore
+ public boolean isActivityTimeValid() {
+ return startTime == null || endTime == null || endTime.isAfter(startTime);
+ }
+
+ @AssertTrue(message = "单次限购数量不能超过总限购数量")
+ @JsonIgnore
+ public boolean isLimitCountValid() {
+ return totalLimitCount == null || singleLimitCount == null
+ || singleLimitCount <= totalLimitCount;
+ }
+
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java
index 9b6e7291..f96167b6 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java
@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@@ -16,6 +18,7 @@ import java.util.List;
public class SeckillActivityCreateReqVO extends SeckillActivityBaseVO {
@Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
- private List products;
+ @NotEmpty(message = "秒杀商品不能为空")
+ private List<@Valid SeckillProductBaseVO> products;
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java
index bf2ca35b..6e4a5d1b 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java
@@ -2,6 +2,10 @@ package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity;
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@@ -15,9 +19,12 @@ import java.util.List;
public class SeckillActivityUpdateReqVO extends SeckillActivityBaseVO {
@Schema(description = "秒杀活动id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "秒杀活动编号不能为空")
+ @Positive(message = "秒杀活动编号必须大于 0")
private Long id;
@Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
- private List products;
+ @NotEmpty(message = "秒杀商品不能为空")
+ private List<@Valid SeckillProductBaseVO> products;
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigBaseVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigBaseVO.java
index d3670840..c38671d1 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigBaseVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigBaseVO.java
@@ -1,11 +1,17 @@
package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.validation.InEnum;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.AssertTrue;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Pattern;
+import jakarta.validation.constraints.Size;
import java.time.LocalTime;
import java.util.List;
@@ -19,35 +25,52 @@ import java.util.List;
public class SeckillConfigBaseVO {
@Schema(description = "秒杀时段名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "早上场")
- @NotNull(message = "秒杀时段名称不能为空")
+ @NotBlank(message = "秒杀时段名称不能为空")
+ @Size(max = 128, message = "秒杀时段名称不能超过 128 个字符")
private String name;
@Schema(description = "开始时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "09:00:00")
@NotNull(message = "开始时间点不能为空")
+ @Pattern(regexp = "^(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d)?$", message = "开始时间点格式必须为 HH:mm 或 HH:mm:ss")
private String startTime;
@Schema(description = "结束时间点", requiredMode = Schema.RequiredMode.REQUIRED, example = "16:00:00")
@NotNull(message = "结束时间点不能为空")
+ @Pattern(regexp = "^(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d)?$", message = "结束时间点格式必须为 HH:mm 或 HH:mm:ss")
private String endTime;
@Schema(description = "秒杀轮播图", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]")
- @NotNull(message = "秒杀轮播图不能为空")
- private List sliderPicUrls;
+ @NotEmpty(message = "秒杀轮播图不能为空")
+ @Size(max = 5, message = "秒杀轮播图不能超过 5 张")
+ private List<@NotBlank(message = "秒杀轮播图地址不能为空") String> sliderPicUrls;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
@NotNull(message = "状态不能为空")
+ @InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}")
private Integer status;
@AssertTrue(message = "秒杀时段开始时间和结束时间不能相等")
@JsonIgnore
public boolean isValidStartTimeValid() {
- return !LocalTime.parse(startTime).equals(LocalTime.parse(endTime));
+ LocalTime start = parseTime(startTime);
+ LocalTime end = parseTime(endTime);
+ return start == null || end == null || !start.equals(end);
}
@AssertTrue(message = "秒杀时段开始时间不能在结束时间之后")
@JsonIgnore
public boolean isValidEndTimeValid() {
- return !LocalTime.parse(startTime).isAfter(LocalTime.parse(endTime));
+ LocalTime start = parseTime(startTime);
+ LocalTime end = parseTime(endTime);
+ return start == null || end == null || start.isBefore(end);
+ }
+
+ private static LocalTime parseTime(String value) {
+ try {
+ return value == null ? null : LocalTime.parse(value);
+ } catch (RuntimeException ignored) {
+ return null;
+ }
}
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateReqVO.java
index 36f7b90e..8b2c456f 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateReqVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateReqVO.java
@@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
@Schema(description = "管理后台 - 秒杀时段更新 Request VO")
@Data
@@ -15,6 +16,7 @@ public class SeckillConfigUpdateReqVO extends SeckillConfigBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "编号不能为空")
+ @Positive(message = "编号必须大于 0")
private Long id;
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateStatusReqVo.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateStatusReqVo.java
index fadf5d9c..3fe0ea52 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateStatusReqVo.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/config/SeckillConfigUpdateStatusReqVo.java
@@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
@Schema(description = "管理后台 - 修改时段配置状态 Request VO")
@Data
@@ -13,6 +14,7 @@ public class SeckillConfigUpdateStatusReqVo {
@Schema(description = "时段配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "时段配置编号不能为空")
+ @Positive(message = "时段配置编号必须大于 0")
private Long id;
@Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductBaseVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductBaseVO.java
index 092115c1..87724b80 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductBaseVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductBaseVO.java
@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
/**
* 秒杀参与商品 Base VO,提供给添加、修改、详细的子 VO 使用
@@ -16,14 +17,17 @@ public class SeckillProductBaseVO {
@Schema(description = "商品sku_id", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
@NotNull(message = "商品sku_id不能为空")
+ @Positive(message = "商品sku_id必须大于 0")
private Long skuId;
@Schema(description = "秒杀金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "6689")
@NotNull(message = "秒杀金额,单位:分不能为空")
+ @Positive(message = "秒杀金额必须大于 0")
private Integer seckillPrice;
@Schema(description = "秒杀库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
@NotNull(message = "秒杀库存不能为空")
+ @Positive(message = "秒杀库存必须大于 0")
private Integer stock;
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/vo/help/AppBargainHelpCreateReqVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/vo/help/AppBargainHelpCreateReqVO.java
index 858b022c..a3ba35f8 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/vo/help/AppBargainHelpCreateReqVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/vo/help/AppBargainHelpCreateReqVO.java
@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
@Schema(description = "用户 App - 砍价助力的创建 Request VO")
@Data
@@ -11,6 +12,7 @@ public class AppBargainHelpCreateReqVO {
@Schema(description = "砍价记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "砍价记录编号不能为空")
+ @Positive(message = "砍价记录编号必须大于 0")
private Long recordId;
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/vo/record/AppBargainRecordCreateReqVO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/vo/record/AppBargainRecordCreateReqVO.java
index c1b93a57..4fd229ce 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/vo/record/AppBargainRecordCreateReqVO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/vo/record/AppBargainRecordCreateReqVO.java
@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
@Schema(description = "用户 App - 砍价记录的创建 Request VO")
@Data
@@ -11,6 +12,7 @@ public class AppBargainRecordCreateReqVO {
@Schema(description = "砍价活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "砍价活动编号不能为空")
+ @Positive(message = "砍价活动编号必须大于 0")
private Long activityId;
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
index f82c723c..1430e4b6 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
@@ -112,8 +112,10 @@ public interface CombinationActivityConvert {
CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO);
default CombinationRecordCreateRespDTO convert4(CombinationRecordDO combinationRecord) {
+ Long headId = ObjectUtil.equal(combinationRecord.getHeadId(), CombinationRecordDO.HEAD_ID_GROUP)
+ ? combinationRecord.getId() : combinationRecord.getHeadId();
return new CombinationRecordCreateRespDTO().setCombinationActivityId(combinationRecord.getActivityId())
- .setCombinationRecordId(combinationRecord.getId()).setCombinationHeadId(combinationRecord.getHeadId());
+ .setCombinationRecordId(combinationRecord.getId()).setCombinationHeadId(headId);
}
default CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO,
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainActivityDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainActivityDO.java
index 37259ebe..b052db6e 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainActivityDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainActivityDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.bargain;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -22,7 +22,7 @@ import java.time.LocalDateTime;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class BargainActivityDO extends BaseDO {
+public class BargainActivityDO extends TenantBaseDO {
/**
* 砍价活动编号
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainHelpDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainHelpDO.java
index 8419f343..3f180a99 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainHelpDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainHelpDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.bargain;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -19,7 +19,7 @@ import lombok.*;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class BargainHelpDO extends BaseDO {
+public class BargainHelpDO extends TenantBaseDO {
/**
* 编号
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainRecordDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainRecordDO.java
index e5f574dd..5bbf3094 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainRecordDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainRecordDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.bargain;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.promotion.enums.bargain.BargainRecordStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -22,7 +22,7 @@ import java.time.LocalDateTime;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class BargainRecordDO extends BaseDO {
+public class BargainRecordDO extends TenantBaseDO {
/**
* 编号
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationActivityDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationActivityDO.java
index 5236b303..b740582f 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationActivityDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationActivityDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.combination;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -22,7 +22,7 @@ import java.time.LocalDateTime;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class CombinationActivityDO extends BaseDO {
+public class CombinationActivityDO extends TenantBaseDO {
/**
* 活动编号
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationProductDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationProductDO.java
index d793bb63..75679006 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationProductDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationProductDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.combination;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -21,7 +21,7 @@ import java.time.LocalDateTime;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class CombinationProductDO extends BaseDO {
+public class CombinationProductDO extends TenantBaseDO {
/**
* 编号
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java
index a7bff7de..ec349ddb 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.combination;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -26,7 +26,7 @@ import java.time.LocalDateTime;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class CombinationRecordDO extends BaseDO {
+public class CombinationRecordDO extends TenantBaseDO {
/**
* 团长编号 - 团长
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java
index 741449db..7bb0491e 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.coupon;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum;
@@ -25,7 +25,7 @@ import java.util.List;
@KeySequence("promotion_coupon_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
-public class CouponDO extends BaseDO {
+public class CouponDO extends TenantBaseDO {
// ========== 基本信息 BEGIN ==========
/**
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java
index 560cedd3..dcee544e 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java
@@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.coupon;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
@@ -28,7 +28,7 @@ import java.util.List;
@KeySequence("promotion_coupon_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
-public class CouponTemplateDO extends BaseDO {
+public class CouponTemplateDO extends TenantBaseDO {
/**
* 领取数量 - 不限制
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java
index ac0661d8..a2bde629 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.discount;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -22,7 +22,7 @@ import java.time.LocalDateTime;
@KeySequence("promotion_discount_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
-public class DiscountActivityDO extends BaseDO {
+public class DiscountActivityDO extends TenantBaseDO {
/**
* 活动编号,主键自增
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java
index 2b28b091..e3f21b47 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.discount;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -19,7 +19,7 @@ import java.time.LocalDateTime;
@KeySequence("promotion_discount_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
-public class DiscountProductDO extends BaseDO {
+public class DiscountProductDO extends TenantBaseDO {
/**
* 编号,主键自增
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java
index b495c4aa..3811352f 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.reward;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum;
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
@@ -27,7 +27,7 @@ import java.util.Map;
@KeySequence("promotion_reward_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
-public class RewardActivityDO extends BaseDO {
+public class RewardActivityDO extends TenantBaseDO {
/**
* 活动编号,主键自增
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/SeckillActivityDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/SeckillActivityDO.java
index 76a08ac7..cdf1e3cd 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/SeckillActivityDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/SeckillActivityDO.java
@@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -24,7 +24,7 @@ import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
-public class SeckillActivityDO extends BaseDO {
+public class SeckillActivityDO extends TenantBaseDO {
/**
* 秒杀活动编号
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/SeckillConfigDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/SeckillConfigDO.java
index 5dcb74f9..286d996b 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/SeckillConfigDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/SeckillConfigDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -24,7 +24,7 @@ import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class SeckillConfigDO extends BaseDO {
+public class SeckillConfigDO extends TenantBaseDO {
/**
* 编号
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/SeckillProductDO.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/SeckillProductDO.java
index 45a2d9e9..e924527b 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/SeckillProductDO.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/SeckillProductDO.java
@@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -17,7 +17,7 @@ import java.util.List;
*
* @author HUIHUI
*/
-@TableName("promotion_seckill_product")
+@TableName(value = "promotion_seckill_product", autoResultMap = true)
@KeySequence("promotion_seckill_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@@ -25,7 +25,7 @@ import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class SeckillProductDO extends BaseDO {
+public class SeckillProductDO extends TenantBaseDO {
/**
* 秒杀参与商品编号
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java
index 08783bd3..57740adc 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java
@@ -43,6 +43,7 @@ public interface BargainActivityMapper extends BaseMapperX {
if (count > 0) {
return update(null, new LambdaUpdateWrapper()
.eq(BargainActivityDO::getId, id)
+ .apply("stock + {0} <= total_stock", count)
.setSql("stock = stock + " + count));
}
// 情况二:扣减库存
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationProductMapper.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationProductMapper.java
index 5d80b6d0..e6ff8572 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationProductMapper.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationProductMapper.java
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductPageReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationProductDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
@@ -35,4 +36,14 @@ public interface CombinationProductMapper extends BaseMapperX()
+ .eq(CombinationProductDO::getActivityId, activityId)
+ .set(CombinationProductDO::getActivityStatus, status));
+ }
+
+ default void deleteByActivityId(Long activityId) {
+ delete(CombinationProductDO::getActivityId, activityId);
+ }
+
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java
index 04c1c615..79734122 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java
@@ -43,6 +43,13 @@ public interface CombinationRecordMapper extends BaseMapperX()
+ .eq(CombinationRecordDO::getId, headId)
+ .eq(CombinationRecordDO::getStatus, status)
+ .last("FOR UPDATE"));
+ }
+
/**
* 查询拼团记录
*
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java
index 7f0c07da..6c185719 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java
@@ -37,6 +37,11 @@ public interface SeckillActivityMapper extends BaseMapperX {
SeckillActivityDO::getStatus, status);
}
+ default Long selectCountByConfigId(Long configId) {
+ return selectCount(new LambdaQueryWrapperX()
+ .apply(MyBatisUtils.findInSet("config_ids"), configId));
+ }
+
/**
* 更新活动库存(减少)
*
@@ -63,6 +68,7 @@ public interface SeckillActivityMapper extends BaseMapperX {
Assert.isTrue(count > 0);
return update(null, new LambdaUpdateWrapper()
.eq(SeckillActivityDO::getId, id)
+ .apply("stock + {0} <= total_stock", count)
.setSql("stock = stock + " + count));
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java
index 8fb14017..29fc2fb1 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java
@@ -59,4 +59,10 @@ public interface SeckillProductMapper extends BaseMapperX {
.setSql("stock = stock + " + count));
}
+ default int updateActivityStatusByActivityId(Long activityId, Integer status) {
+ return update(null, new LambdaUpdateWrapper()
+ .eq(SeckillProductDO::getActivityId, activityId)
+ .set(SeckillProductDO::getActivityStatus, status));
+ }
+
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
index 514cb27a..ca79ef42 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
@@ -57,6 +57,7 @@ public interface ErrorCodeConstants {
// ========== 秒杀活动 1-013-008-000 ==========
ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_008_000, "秒杀活动不存在");
+ ErrorCode SECKILL_ACTIVITY_PRODUCT_DUPLICATE = new ErrorCode(1_013_008_001, "秒杀商品 SKU 不能重复");
ErrorCode SECKILL_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1_013_008_002, "存在商品参加了其它秒杀活动,秒杀时段冲突");
ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_008_003, "秒杀活动已关闭,不能修改");
ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1_013_008_004, "秒杀活动未关闭或未结束,不能删除");
@@ -66,10 +67,13 @@ public interface ErrorCodeConstants {
ErrorCode SECKILL_JOIN_ACTIVITY_STATUS_CLOSED = new ErrorCode(1_013_008_008, "秒杀失败,原因:秒杀活动已关闭");
ErrorCode SECKILL_JOIN_ACTIVITY_SINGLE_LIMIT_COUNT_EXCEED = new ErrorCode(1_013_008_009, "秒杀失败,原因:单次限购超出");
ErrorCode SECKILL_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS = new ErrorCode(1_013_008_010, "秒杀失败,原因:商品不存在");
+ ErrorCode SECKILL_ACTIVITY_PRODUCT_PRICE_INVALID = new ErrorCode(1_013_008_011, "秒杀价格不能高于商品价格");
+ ErrorCode SECKILL_ACTIVITY_PRODUCT_STOCK_EXCEED = new ErrorCode(1_013_008_012, "秒杀库存不能超过商品库存");
// ========== 秒杀时段 1-013-009-000 ==========
ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1_013_009_000, "秒杀时段不存在");
ErrorCode SECKILL_CONFIG_TIME_CONFLICTS = new ErrorCode(1_013_009_001, "秒杀时段冲突");
+ ErrorCode SECKILL_CONFIG_DELETE_FAIL_USED = new ErrorCode(1_013_009_002, "秒杀时段已被活动使用,不能删除");
ErrorCode SECKILL_CONFIG_DISABLE = new ErrorCode(1_013_009_004, "秒杀时段已关闭");
// ========== 拼团活动 1-013-010-000 ==========
@@ -80,6 +84,9 @@ public interface ErrorCodeConstants {
ErrorCode COMBINATION_ACTIVITY_STATUS_DISABLE = new ErrorCode(1_013_010_004, "拼团失败,原因:拼团活动已关闭");
ErrorCode COMBINATION_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS = new ErrorCode(1_013_010_005, "拼团失败,原因:拼团活动商品不存在");
ErrorCode COMBINATION_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1_013_010_006, "拼团失败,原因:拼团活动商品库存不足");
+ ErrorCode COMBINATION_ACTIVITY_PRODUCT_DUPLICATE = new ErrorCode(1_013_010_007, "拼团商品 SKU 不能重复");
+ ErrorCode COMBINATION_ACTIVITY_PRODUCT_PRICE_INVALID = new ErrorCode(1_013_010_008, "拼团价格不能高于商品价格");
+ ErrorCode COMBINATION_ACTIVITY_PRODUCT_SPU_MISMATCH = new ErrorCode(1_013_010_009, "拼团商品必须属于活动 SPU");
// ========== 拼团记录 1-013-011-000 ==========
ErrorCode COMBINATION_RECORD_NOT_EXISTS = new ErrorCode(1_013_011_000, "拼团不存在");
@@ -92,6 +99,7 @@ public interface ErrorCodeConstants {
ErrorCode COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED = new ErrorCode(1_013_011_007, "拼团失败,原因:单次限购超出");
ErrorCode COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED = new ErrorCode(1_013_011_008, "拼团失败,原因:超出总购买次数");
ErrorCode COMBINATION_RECORD_FAILED_ORDER_STATUS_UNPAID = new ErrorCode(1_013_011_009, "拼团失败,原因:存在未支付订单,请先支付");
+ ErrorCode COMBINATION_RECORD_HEAD_ACTIVITY_MISMATCH = new ErrorCode(1_013_011_010, "拼团失败,父拼团不属于当前活动");
// ========== 砍价活动 1-013-012-000 ==========
ErrorCode BARGAIN_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_012_000, "砍价活动不存在");
@@ -101,6 +109,9 @@ public interface ErrorCodeConstants {
ErrorCode BARGAIN_ACTIVITY_STOCK_NOT_ENOUGH = new ErrorCode(1_013_012_004, "砍价活动库存不足");
ErrorCode BARGAIN_ACTIVITY_STATUS_CLOSED = new ErrorCode(1_013_012_005, "砍价活动已关闭");
ErrorCode BARGAIN_ACTIVITY_TIME_END = new ErrorCode(1_013_012_006, "砍价活动已经结束");
+ ErrorCode BARGAIN_ACTIVITY_SKU_SPU_MISMATCH = new ErrorCode(1_013_012_007, "砍价商品 SKU 不属于活动 SPU");
+ ErrorCode BARGAIN_ACTIVITY_PRICE_INVALID = new ErrorCode(1_013_012_008, "砍价起始价格不能高于商品价格");
+ ErrorCode BARGAIN_ACTIVITY_STOCK_RESTORE_EXCEED = new ErrorCode(1_013_012_009, "砍价活动库存回补不能超过总库存");
// ========== 砍价记录 1-013-013-000 ==========
ErrorCode BARGAIN_RECORD_NOT_EXISTS = new ErrorCode(1_013_013_000, "砍价记录不存在");
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java
index eb01d753..be080abb 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java
@@ -48,7 +48,7 @@ public class BargainActivityServiceImpl implements BargainActivityService {
// 校验商品 SPU 是否存在是否参加的别的活动
validateBargainConflict(createReqVO.getSpuId(), null);
// 校验商品 sku 是否存在
- validateSku(createReqVO.getSkuId());
+ validateSku(createReqVO.getSpuId(), createReqVO.getSkuId(), createReqVO.getBargainFirstPrice());
// 插入砍价活动
BargainActivityDO activityDO = BargainActivityConvert.INSTANCE.convert(createReqVO)
@@ -70,7 +70,7 @@ public class BargainActivityServiceImpl implements BargainActivityService {
// 校验商品冲突
validateBargainConflict(updateReqVO.getSpuId(), updateReqVO.getId());
// 校验商品 sku 是否存在
- validateSku(updateReqVO.getSkuId());
+ validateSku(updateReqVO.getSpuId(), updateReqVO.getSkuId(), updateReqVO.getBargainFirstPrice());
// 更新
BargainActivityDO updateObj = BargainActivityConvert.INSTANCE.convert(updateReqVO);
@@ -89,7 +89,9 @@ public class BargainActivityServiceImpl implements BargainActivityService {
throw exception(BARGAIN_ACTIVITY_STOCK_NOT_ENOUGH);
}
} else if (count > 0) {
- bargainActivityMapper.updateStock(id, count);
+ if (bargainActivityMapper.updateStock(id, count) == 0) {
+ throw exception(BARGAIN_ACTIVITY_STOCK_RESTORE_EXCEED);
+ }
}
}
@@ -118,11 +120,17 @@ public class BargainActivityServiceImpl implements BargainActivityService {
}
}
- private void validateSku(Long skuId) {
+ private void validateSku(Long spuId, Long skuId, Integer bargainFirstPrice) {
ProductSkuRespDTO sku = productSkuApi.getSku(skuId);
if (sku == null) {
throw exception(SKU_NOT_EXISTS);
}
+ if (!ObjectUtil.equal(sku.getSpuId(), spuId)) {
+ throw exception(BARGAIN_ACTIVITY_SKU_SPU_MISMATCH);
+ }
+ if (bargainFirstPrice > sku.getPrice()) {
+ throw exception(BARGAIN_ACTIVITY_PRICE_INVALID);
+ }
}
@Override
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainHelpServiceImpl.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainHelpServiceImpl.java
index 345449f1..ab698b93 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainHelpServiceImpl.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainHelpServiceImpl.java
@@ -96,7 +96,7 @@ public class BargainHelpServiceImpl implements BargainHelpService {
// TODO 管理员:优化点:实现一个更随机的逻辑,可以按照你自己的业务;
private Integer calculateReducePrice(BargainActivityDO activity, BargainRecordDO record) {
// 1. 随机金额
- Integer reducePrice = MathUtil.randomInt(activity.getBargainMinPrice(),
+ Integer reducePrice = MathUtil.randomInt(activity.getRandomMinPrice(),
activity.getRandomMaxPrice() + 1); // + 1 的原因是,randomInt 默认不包含第二个参数
// 2. 校验是否超过砍价上限
if (record.getBargainPrice() - reducePrice < activity.getBargainMinPrice()) {
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java
index 5e2862ac..eba48a79 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java
@@ -18,6 +18,7 @@ import org.springframework.validation.annotation.Validated;
import jakarta.annotation.Nullable;
import jakarta.annotation.Resource;
+import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -71,7 +72,7 @@ public class BargainRecordServiceImpl implements BargainRecordService {
Integer reducePrice, Boolean success) {
BargainRecordDO updateObj = new BargainRecordDO().setBargainPrice(whereBargainPrice - reducePrice);
if (success) {
- updateObj.setStatus(BargainRecordStatusEnum.SUCCESS.getStatus());
+ updateObj.setStatus(BargainRecordStatusEnum.SUCCESS.getStatus()).setEndTime(LocalDateTime.now());
}
return bargainRecordMapper.updateByIdAndBargainPrice(id, whereBargainPrice, updateObj) > 0;
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
index f5b38a13..5933eb28 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
@@ -25,8 +25,10 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
@@ -108,10 +110,21 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
// 2. 校验商品 sku 都存在
List skus = productSkuApi.getSkuListBySpuId(singletonList(spuId));
Map skuMap = convertMap(skus, ProductSkuRespDTO::getId);
+ Set skuIds = new HashSet<>();
products.forEach(product -> {
- if (!skuMap.containsKey(product.getSkuId())) {
+ if (!skuIds.add(product.getSkuId())) {
+ throw exception(COMBINATION_ACTIVITY_PRODUCT_DUPLICATE);
+ }
+ if (!ObjectUtil.equal(product.getSpuId(), spuId)) {
+ throw exception(COMBINATION_ACTIVITY_PRODUCT_SPU_MISMATCH);
+ }
+ ProductSkuRespDTO sku = skuMap.get(product.getSkuId());
+ if (sku == null) {
throw exception(SKU_NOT_EXISTS);
}
+ if (product.getCombinationPrice() > sku.getPrice()) {
+ throw exception(COMBINATION_ACTIVITY_PRODUCT_PRICE_INVALID);
+ }
});
}
@@ -130,7 +143,8 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
validateProductExists(updateReqVO.getSpuId(), updateReqVO.getProducts());
// 更新活动
- CombinationActivityDO updateObj = CombinationActivityConvert.INSTANCE.convert(updateReqVO);
+ CombinationActivityDO updateObj = CombinationActivityConvert.INSTANCE.convert(updateReqVO)
+ .setStatus(activityDO.getStatus());
combinationActivityMapper.updateById(updateObj);
// 更新商品
updateCombinationProduct(updateObj, updateReqVO.getProducts());
@@ -148,6 +162,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
// 关闭活动
combinationActivityMapper.updateById(new CombinationActivityDO().setId(id)
.setStatus(CommonStatusEnum.DISABLE.getStatus()));
+ combinationProductMapper.updateActivityStatusByActivityId(id, CommonStatusEnum.DISABLE.getStatus());
}
/**
@@ -191,6 +206,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
}
// 删除
+ combinationProductMapper.deleteByActivityId(id);
combinationActivityMapper.deleteById(id);
}
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
index ab215f60..6edc4a47 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
@@ -80,6 +80,9 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
@Override
public KeyValue validateCombinationRecord(
Long userId, Long activityId, Long headId, Long skuId, Integer count) {
+ if (count == null || count <= 0) {
+ throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED);
+ }
// 1. 校验拼团活动是否存在
CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(activityId);
// 1.1 校验活动是否开启
@@ -99,9 +102,12 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
if (isJoinCombination(headId)) {
// 2.1. 查询进行中的父拼团
CombinationRecordDO record = combinationRecordMapper.selectByHeadId(headId, CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
- if (record == null) {
+ if (record == null || ObjUtil.notEqual(record.getHeadId(), CombinationRecordDO.HEAD_ID_GROUP)) {
throw exception(COMBINATION_RECORD_HEAD_NOT_EXISTS);
}
+ if (ObjUtil.notEqual(record.getActivityId(), activityId)) {
+ throw exception(COMBINATION_RECORD_HEAD_ACTIVITY_MISMATCH);
+ }
// 2.2. 校验拼团是否已满
if (ObjUtil.equal(record.getUserCount(), record.getUserSize())) {
throw exception(COMBINATION_RECORD_USER_FULL);
@@ -122,6 +128,9 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
if (product == null) {
throw exception(COMBINATION_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS);
}
+ if (ObjUtil.notEqual(product.getSpuId(), activity.getSpuId())) {
+ throw exception(COMBINATION_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS);
+ }
// 4.2 校验 sku 是否存在
ProductSkuRespDTO sku = productSkuApi.getSku(skuId);
if (sku == null) {
@@ -165,14 +174,29 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
@Override
@Transactional(rollbackFor = Exception.class)
public CombinationRecordDO createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
+ if (isJoinCombination(reqDTO.getHeadId())) {
+ CombinationRecordDO headRecord = combinationRecordMapper.selectByHeadIdForUpdate(reqDTO.getHeadId(),
+ CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
+ if (headRecord == null
+ || ObjUtil.notEqual(headRecord.getHeadId(), CombinationRecordDO.HEAD_ID_GROUP)) {
+ throw exception(COMBINATION_RECORD_HEAD_NOT_EXISTS);
+ }
+ }
// 1. 校验拼团活动
KeyValue keyValue = validateCombinationRecord(reqDTO.getUserId(),
reqDTO.getActivityId(), reqDTO.getHeadId(), reqDTO.getSkuId(), reqDTO.getCount());
+ if (ObjUtil.notEqual(reqDTO.getSpuId(), keyValue.getKey().getSpuId())
+ || ObjUtil.notEqual(reqDTO.getCombinationPrice(), keyValue.getValue().getCombinationPrice())) {
+ throw exception(COMBINATION_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS);
+ }
// 2. 组合数据创建拼团记录
MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId());
ProductSpuRespDTO spu = productSpuApi.getSpu(reqDTO.getSpuId());
ProductSkuRespDTO sku = productSkuApi.getSku(reqDTO.getSkuId());
+ if (user == null || spu == null || sku == null) {
+ throw exception(COMBINATION_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS);
+ }
CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO, keyValue.getKey(), user, spu, sku);
// 2.1. 如果是团长需要设置 headId 为 CombinationRecordDO#HEAD_ID_GROUP
if (!isJoinCombination(record.getHeadId())) {
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java
index 3c84a172..a6b05e2d 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java
@@ -30,6 +30,7 @@ import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.HashSet;
import static cn.hutool.core.collection.CollUtil.isNotEmpty;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -124,10 +125,20 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
// 2. 校验商品 sku 都存在
List skus = productSkuApi.getSkuListBySpuId(singletonList(spuId));
Map skuMap = convertMap(skus, ProductSkuRespDTO::getId);
+ if (new HashSet<>(convertList(products, SeckillProductBaseVO::getSkuId)).size() != products.size()) {
+ throw exception(SECKILL_ACTIVITY_PRODUCT_DUPLICATE);
+ }
products.forEach(product -> {
- if (!skuMap.containsKey(product.getSkuId())) {
+ ProductSkuRespDTO sku = skuMap.get(product.getSkuId());
+ if (sku == null) {
throw exception(SKU_NOT_EXISTS);
}
+ if (product.getSeckillPrice() > sku.getPrice()) {
+ throw exception(SECKILL_ACTIVITY_PRODUCT_PRICE_INVALID);
+ }
+ if (product.getStock() > sku.getStock()) {
+ throw exception(SECKILL_ACTIVITY_PRODUCT_STOCK_EXCEED);
+ }
});
}
@@ -185,11 +196,21 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
@Override
@Transactional(rollbackFor = Exception.class)
public void updateSeckillStockIncr(Long id, Long skuId, Integer count) {
+ validateSeckillActivityExists(id);
SeckillProductDO product = seckillProductMapper.selectByActivityIdAndSkuId(id, skuId);
+ if (product == null) {
+ throw exception(SECKILL_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS);
+ }
// 更新活动商品库存
- seckillProductMapper.updateStockIncr(product.getId(), count);
+ int updateCount = seckillProductMapper.updateStockIncr(product.getId(), count);
+ if (updateCount == 0) {
+ throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
+ }
// 更新活动库存
- seckillActivityMapper.updateStockIncr(id, count);
+ updateCount = seckillActivityMapper.updateStockIncr(id, count);
+ if (updateCount == 0) {
+ throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
+ }
}
/**
@@ -223,6 +244,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
}
@Override
+ @Transactional(rollbackFor = Exception.class)
public void closeSeckillActivity(Long id) {
// 校验存在
SeckillActivityDO activity = validateSeckillActivityExists(id);
@@ -233,6 +255,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
// 更新
SeckillActivityDO updateObj = new SeckillActivityDO().setId(id).setStatus(CommonStatusEnum.DISABLE.getStatus());
seckillActivityMapper.updateById(updateObj);
+ seckillProductMapper.updateActivityStatusByActivityId(id, CommonStatusEnum.DISABLE.getStatus());
}
@Override
diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillConfigServiceImpl.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillConfigServiceImpl.java
index d35a1728..e85b1522 100644
--- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillConfigServiceImpl.java
+++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillConfigServiceImpl.java
@@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck
import cn.iocoder.yudao.module.promotion.convert.seckill.SeckillConfigConvert;
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper;
+import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -36,6 +37,8 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
@Resource
private SeckillConfigMapper seckillConfigMapper;
+ @Resource
+ private SeckillActivityMapper seckillActivityMapper;
@Override
public Long createSeckillConfig(SeckillConfigCreateReqVO createReqVO) {
@@ -80,6 +83,9 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
public void deleteSeckillConfig(Long id) {
// 校验存在
validateSeckillConfigExists(id);
+ if (seckillActivityMapper.selectCountByConfigId(id) > 0) {
+ throw exception(SECKILL_CONFIG_DELETE_FAIL_USED);
+ }
// 删除
seckillConfigMapper.deleteById(id);
diff --git a/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainRequestValidationContractTest.java b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainRequestValidationContractTest.java
new file mode 100644
index 00000000..b06f79f2
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainRequestValidationContractTest.java
@@ -0,0 +1,56 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.bargain;
+
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityBaseVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.help.AppBargainHelpCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.record.AppBargainRecordCreateReqVO;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Positive;
+import jakarta.validation.constraints.Size;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDateTime;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class BargainRequestValidationContractTest {
+
+ @Test
+ void activityRequestsRequireBoundedNameAndPositiveValues() throws Exception {
+ assertThat(BargainActivityBaseVO.class.getDeclaredField("name")
+ .isAnnotationPresent(NotBlank.class)).isTrue();
+ assertThat(BargainActivityBaseVO.class.getDeclaredField("name")
+ .getAnnotation(Size.class).max()).isEqualTo(255);
+ for (String field : new String[]{"spuId", "skuId", "bargainFirstPrice", "bargainMinPrice",
+ "stock", "totalLimitCount", "helpMaxCount", "bargainCount", "randomMinPrice", "randomMaxPrice"}) {
+ assertThat(BargainActivityBaseVO.class.getDeclaredField(field)
+ .isAnnotationPresent(Positive.class)).as(field).isTrue();
+ }
+ assertThat(BargainActivityUpdateReqVO.class.getDeclaredField("id")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ }
+
+ @Test
+ void activityRequestRejectsReversedTimesAndInvalidPriceRelationships() {
+ BargainActivityBaseVO request = new BargainActivityBaseVO();
+ request.setStartTime(LocalDateTime.of(2026, 1, 2, 0, 0));
+ request.setEndTime(LocalDateTime.of(2026, 1, 1, 0, 0));
+ request.setBargainFirstPrice(100);
+ request.setBargainMinPrice(101);
+ request.setRandomMinPrice(20);
+ request.setRandomMaxPrice(19);
+
+ assertThat(request.isActivityTimeValid()).isFalse();
+ assertThat(request.isBargainPriceValid()).isFalse();
+ assertThat(request.isRandomPriceValid()).isFalse();
+ }
+
+ @Test
+ void appRequestsRequirePositiveIdentifiers() throws Exception {
+ assertThat(AppBargainRecordCreateReqVO.class.getDeclaredField("activityId")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ assertThat(AppBargainHelpCreateReqVO.class.getDeclaredField("recordId")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationRequestValidationContractTest.java b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationRequestValidationContractTest.java
new file mode 100644
index 00000000..11c1bdb3
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationRequestValidationContractTest.java
@@ -0,0 +1,67 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.combination;
+
+import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
+import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityBaseVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductBaseVO;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.Positive;
+import jakarta.validation.constraints.PositiveOrZero;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.AnnotatedParameterizedType;
+import java.time.LocalDateTime;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class CombinationRequestValidationContractTest {
+
+ @Test
+ void activityRequestsRequireProductsPositiveIdentifiersAndAtLeastTwoMembers() throws Exception {
+ assertThat(CombinationActivityCreateReqVO.class.getDeclaredField("products")
+ .isAnnotationPresent(NotEmpty.class)).isTrue();
+ AnnotatedParameterizedType productsType = (AnnotatedParameterizedType)
+ CombinationActivityCreateReqVO.class.getDeclaredField("products").getAnnotatedType();
+ assertThat(productsType.getAnnotatedActualTypeArguments()[0].isAnnotationPresent(Valid.class)).isTrue();
+ assertThat(CombinationActivityUpdateReqVO.class.getDeclaredField("id")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ assertThat(CombinationActivityBaseVO.class.getDeclaredField("spuId")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ assertThat(CombinationActivityBaseVO.class.getDeclaredField("userSize")
+ .getAnnotation(Min.class).value()).isEqualTo(2L);
+ assertThat(CombinationProductBaseVO.class.getDeclaredField("skuId")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ assertThat(CombinationProductBaseVO.class.getDeclaredField("combinationPrice")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ }
+
+ @Test
+ void activityRequestRejectsReversedTimesAndInvalidLimitRelationship() {
+ CombinationActivityBaseVO request = new CombinationActivityBaseVO();
+ request.setStartTime(LocalDateTime.of(2026, 1, 2, 0, 0));
+ request.setEndTime(LocalDateTime.of(2026, 1, 1, 0, 0));
+ request.setTotalLimitCount(2);
+ request.setSingleLimitCount(3);
+
+ assertThat(request.isActivityTimeValid()).isFalse();
+ assertThat(request.isLimitCountValid()).isFalse();
+ }
+
+ @Test
+ void recordCreationRequiresPositiveOrderUserProductAndNonNegativeHead() throws Exception {
+ assertThat(CombinationRecordCreateReqDTO.class.getDeclaredField("activityId")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ assertThat(CombinationRecordCreateReqDTO.class.getDeclaredField("orderId")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ assertThat(CombinationRecordCreateReqDTO.class.getDeclaredField("userId")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ assertThat(CombinationRecordCreateReqDTO.class.getDeclaredField("combinationPrice")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ assertThat(CombinationRecordCreateReqDTO.class.getDeclaredField("headId")
+ .isAnnotationPresent(PositiveOrZero.class)).isTrue();
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillRequestValidationContractTest.java b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillRequestValidationContractTest.java
new file mode 100644
index 00000000..353ec696
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillRequestValidationContractTest.java
@@ -0,0 +1,43 @@
+package cn.iocoder.yudao.module.promotion.controller.admin.seckill;
+
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigBaseVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.Positive;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.AnnotatedParameterizedType;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class SeckillRequestValidationContractTest {
+
+ @Test
+ void activityRequestsRequirePositiveProductsAndIdentifiers() throws Exception {
+ assertThat(SeckillActivityCreateReqVO.class.getDeclaredField("products")
+ .isAnnotationPresent(NotEmpty.class)).isTrue();
+ AnnotatedParameterizedType productsType = (AnnotatedParameterizedType)
+ SeckillActivityCreateReqVO.class.getDeclaredField("products").getAnnotatedType();
+ assertThat(productsType.getAnnotatedActualTypeArguments()[0].isAnnotationPresent(Valid.class)).isTrue();
+ assertThat(SeckillActivityUpdateReqVO.class.getDeclaredField("id")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ assertThat(SeckillProductBaseVO.class.getDeclaredField("seckillPrice")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ assertThat(SeckillProductBaseVO.class.getDeclaredField("stock")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ }
+
+ @Test
+ void configRequestsRequireAtLeastOneSliderAndRejectReversedTimes() throws Exception {
+ assertThat(SeckillConfigBaseVO.class.getDeclaredField("sliderPicUrls")
+ .isAnnotationPresent(NotEmpty.class)).isTrue();
+ SeckillConfigBaseVO request = new SeckillConfigBaseVO();
+ request.setStartTime("12:00");
+ request.setEndTime("11:00");
+ assertThat(request.isValidEndTimeValid()).isFalse();
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvertContractTest.java b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvertContractTest.java
new file mode 100644
index 00000000..80913cf1
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvertContractTest.java
@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.promotion.convert.combination;
+
+import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class CombinationActivityConvertContractTest {
+
+ @Test
+ void headCreationReturnsPersistedHeadRecordIdInsteadOfSentinel() {
+ CombinationRecordDO head = new CombinationRecordDO().setId(123L).setActivityId(45L)
+ .setHeadId(CombinationRecordDO.HEAD_ID_GROUP);
+
+ assertThat(CombinationActivityConvert.INSTANCE.convert4(head))
+ .satisfies(response -> {
+ assertThat(response.getCombinationActivityId()).isEqualTo(45L);
+ assertThat(response.getCombinationRecordId()).isEqualTo(123L);
+ assertThat(response.getCombinationHeadId()).isEqualTo(123L);
+ });
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/dal/dataobject/PromotionActivityTenantContractTest.java b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/dal/dataobject/PromotionActivityTenantContractTest.java
new file mode 100644
index 00000000..6a238fb7
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/dal/dataobject/PromotionActivityTenantContractTest.java
@@ -0,0 +1,50 @@
+package cn.iocoder.yudao.module.promotion.dal.dataobject;
+
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainHelpDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationProductDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class PromotionActivityTenantContractTest {
+
+ @Test
+ void checkoutPromotionRecordsParticipateInFrameworkTenantIsolation() {
+ assertThat(TenantBaseDO.class).isAssignableFrom(DiscountActivityDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(DiscountProductDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(RewardActivityDO.class);
+ }
+
+ @Test
+ void seckillRecordsParticipateInFrameworkTenantIsolation() {
+ assertThat(TenantBaseDO.class).isAssignableFrom(SeckillActivityDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(SeckillProductDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(SeckillConfigDO.class);
+ }
+
+ @Test
+ void combinationRecordsParticipateInFrameworkTenantIsolation() {
+ assertThat(TenantBaseDO.class).isAssignableFrom(CombinationActivityDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(CombinationProductDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(CombinationRecordDO.class);
+ }
+
+ @Test
+ void bargainRecordsParticipateInFrameworkTenantIsolation() {
+ assertThat(TenantBaseDO.class).isAssignableFrom(BargainActivityDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(BargainRecordDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(BargainHelpDO.class);
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTenantContractTest.java b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTenantContractTest.java
new file mode 100644
index 00000000..9607f6ee
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTenantContractTest.java
@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.module.promotion.dal.dataobject.coupon;
+
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class CouponTenantContractTest {
+
+ @Test
+ void nativeCouponRecordsParticipateInFrameworkTenantIsolation() {
+ assertThat(TenantBaseDO.class).isAssignableFrom(CouponTemplateDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(CouponDO.class);
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainServiceBehaviorContractTest.java b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainServiceBehaviorContractTest.java
new file mode 100644
index 00000000..71ee9050
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion/src/test/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainServiceBehaviorContractTest.java
@@ -0,0 +1,50 @@
+package cn.iocoder.yudao.module.promotion.service.bargain;
+
+import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO;
+import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainRecordMapper;
+import cn.iocoder.yudao.module.promotion.enums.bargain.BargainRecordStatusEnum;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class BargainServiceBehaviorContractTest {
+
+ @Test
+ void calculateReducePriceUsesConfiguredRandomRange() {
+ BargainHelpServiceImpl service = new BargainHelpServiceImpl();
+ BargainActivityDO activity = new BargainActivityDO()
+ .setRandomMinPrice(7)
+ .setRandomMaxPrice(7)
+ .setBargainMinPrice(10);
+ BargainRecordDO record = new BargainRecordDO().setBargainPrice(100);
+
+ Integer reducePrice = ReflectionTestUtils.invokeMethod(service, "calculateReducePrice", activity, record);
+
+ assertThat(reducePrice).isEqualTo(7);
+ }
+
+ @Test
+ void successfulPriceUpdateStoresStatusAndEndTime() {
+ BargainRecordMapper mapper = mock(BargainRecordMapper.class);
+ BargainRecordServiceImpl service = new BargainRecordServiceImpl();
+ ReflectionTestUtils.setField(service, "bargainRecordMapper", mapper);
+ when(mapper.updateByIdAndBargainPrice(eq(1L), eq(100), org.mockito.ArgumentMatchers.any()))
+ .thenReturn(1);
+
+ assertThat(service.updateBargainRecordBargainPrice(1L, 100, 20, true)).isTrue();
+
+ ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(BargainRecordDO.class);
+ verify(mapper).updateByIdAndBargainPrice(eq(1L), eq(100), updateCaptor.capture());
+ assertThat(updateCaptor.getValue().getBargainPrice()).isEqualTo(80);
+ assertThat(updateCaptor.getValue().getStatus()).isEqualTo(BargainRecordStatusEnum.SUCCESS.getStatus());
+ assertThat(updateCaptor.getValue().getEndTime()).isNotNull();
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java
index 2bc654b2..11c0178f 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/AfterSaleController.java
@@ -103,7 +103,7 @@ public class AfterSaleController {
@PutMapping("/disagree")
@Operation(summary = "拒绝售后")
@PreAuthorize("@ss.hasPermission('trade:after-sale:disagree')")
- public CommonResult disagreeAfterSale(@RequestBody AfterSaleDisagreeReqVO confirmReqVO) {
+ public CommonResult disagreeAfterSale(@RequestBody @Valid AfterSaleDisagreeReqVO confirmReqVO) {
afterSaleService.disagreeAfterSale(getLoginUserId(), confirmReqVO);
return success(true);
}
@@ -121,7 +121,7 @@ public class AfterSaleController {
@Operation(summary = "拒绝收货")
@Parameter(name = "id", description = "售后编号", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('trade:after-sale:receive')")
- public CommonResult refuseAfterSale(AfterSaleRefuseReqVO refuseReqVO) {
+ public CommonResult refuseAfterSale(@Valid AfterSaleRefuseReqVO refuseReqVO) {
afterSaleService.refuseAfterSale(getLoginUserId(), refuseReqVO);
return success(true);
}
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleDetailRespVO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleDetailRespVO.java
index 3f220770..30894a32 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleDetailRespVO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleDetailRespVO.java
@@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderItemBas
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
+import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 售后订单的详情 Response VO")
@@ -17,7 +18,8 @@ public class AfterSaleDetailRespVO extends AfterSaleBaseVO {
@Schema(description = "售后编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
-
+ @Schema(description = "申请时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ private LocalDateTime createTime;
/**
* 订单基本信息
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleRefuseReqVO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleRefuseReqVO.java
index 36e52e84..85bcf4e9 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleRefuseReqVO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/AfterSaleRefuseReqVO.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
+import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@Schema(description = "管理后台 - 交易售后拒绝收货 Request VO")
@@ -14,7 +15,7 @@ public class AfterSaleRefuseReqVO {
private Long id;
@Schema(description = "收货备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "你猜")
- @NotNull(message = "收货备注不能为空")
+ @NotBlank(message = "收货备注不能为空")
private String refuseMemo;
}
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageUserController.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageUserController.java
index c037c9fa..8b2295ce 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageUserController.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageUserController.java
@@ -85,6 +85,9 @@ public class BrokerageUserController {
@PreAuthorize("@ss.hasPermission('trade:brokerage-user:query')")
public CommonResult getBrokerageUser(@RequestParam("id") Long id) {
BrokerageUserDO brokerageUser = brokerageUserService.getBrokerageUser(id);
+ if (brokerageUser == null) {
+ return success(null);
+ }
// TODO @疯狂:是不是搞成一个统一的 convert?
BrokerageUserRespVO respVO = BrokerageUserConvert.INSTANCE.convert(brokerageUser);
return success(BrokerageUserConvert.INSTANCE.copyTo(memberUserApi.getUser(id), respVO));
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRejectReqVO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRejectReqVO.java
index a0967f19..35f9a183 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRejectReqVO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawRejectReqVO.java
@@ -4,7 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
-import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@Schema(description = "管理后台 - 驳回申请 Request VO")
@@ -17,7 +17,7 @@ public class BrokerageWithdrawRejectReqVO {
private Long id;
@Schema(description = "审核驳回原因", example = "不对")
- @NotEmpty(message = "审核驳回原因不能为空")
+ @NotBlank(message = "审核驳回原因不能为空")
private String auditReason;
}
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java
index 180b016a..5145901d 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java
@@ -6,24 +6,25 @@ import cn.iocoder.yudao.module.pay.enums.PayChannelEnum;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.Positive;
import lombok.Data;
import org.hibernate.validator.constraints.URL;
import jakarta.validation.Validator;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.PositiveOrZero;
@Schema(description = "用户 App - 分销提现创建 Request VO")
@Data
public class AppBrokerageWithdrawCreateReqVO {
@Schema(description = "提现方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "提现方式不能为空")
@InEnum(value = BrokerageWithdrawTypeEnum.class, message = "提现方式必须是 {value}")
private Integer type;
@Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
- @PositiveOrZero(message = "提现金额不能小于 0")
+ @Positive(message = "提现金额必须大于 0")
@Min(value = 30, message = "微信提现金额不能小于 0.3", groups = {WechatApi.class})
@NotNull(message = "提现金额不能为空")
private Integer price;
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java
index ff66e001..3498f459 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java
@@ -44,6 +44,11 @@ public interface BrokerageRecordConvert {
Integer status = brokerageFrozenDays > 0
? BrokerageRecordStatusEnum.WAIT_SETTLEMENT.getStatus()
: BrokerageRecordStatusEnum.SETTLEMENT.getStatus();
+ // 即时结算也要记录结算时刻。排行、汇总接口按 unfreeze_time 过滤,留空会导致
+ // 无冻结期的正常佣金永远不出现在时间范围统计中。
+ if (BrokerageRecordStatusEnum.SETTLEMENT.getStatus().equals(status) && unfreezeTime == null) {
+ unfreezeTime = LocalDateTime.now();
+ }
return new BrokerageRecordDO().setUserId(user.getId())
.setBizType(bizType.getType()).setBizId(bizId)
.setPrice(brokeragePrice).setTotalPrice(user.getBrokeragePrice())
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleDO.java
index 87fe1ec6..77f1cf89 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.aftersale;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleStatusEnum;
@@ -23,7 +23,7 @@ import java.util.List;
@TableName(value = "trade_after_sale", autoResultMap = true)
@KeySequence("trade_after_sale_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
-public class AfterSaleDO extends BaseDO {
+public class AfterSaleDO extends TenantBaseDO {
/**
* 售后编号,主键自增
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleLogDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleLogDO.java
index 92262dde..e0784251 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleLogDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleLogDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.aftersale;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -21,7 +21,7 @@ import lombok.*;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class AfterSaleLogDO extends BaseDO {
+public class AfterSaleLogDO extends TenantBaseDO {
/**
* 编号
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageRecordDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageRecordDO.java
index 7dec2b85..4fabe488 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageRecordDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageRecordDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
@@ -23,7 +23,7 @@ import java.time.LocalDateTime;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class BrokerageRecordDO extends BaseDO {
+public class BrokerageRecordDO extends TenantBaseDO {
/**
* 编号
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageUserDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageUserDO.java
index 8d73858e..d9b49149 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageUserDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageUserDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -21,7 +21,7 @@ import java.time.LocalDateTime;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class BrokerageUserDO extends BaseDO {
+public class BrokerageUserDO extends TenantBaseDO {
/**
* 用户编号
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java
index b887b281..3d97d8c9 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
@@ -23,7 +23,7 @@ import java.time.LocalDateTime;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class BrokerageWithdrawDO extends BaseDO {
+public class BrokerageWithdrawDO extends TenantBaseDO {
/**
* 编号
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/CartDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/CartDO.java
index 54819741..6aa15e09 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/CartDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/CartDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.cart;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@@ -15,7 +15,7 @@ import lombok.Data;
@TableName("trade_cart")
@KeySequence("trade_cart_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
-public class CartDO extends BaseDO {
+public class CartDO extends TenantBaseDO {
// ========= 基础字段 BEGIN =========
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java
index 1ab715db..a49411b8 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.config;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.IntegerListTypeHandler;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageBindModeEnum;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageEnabledConditionEnum;
@@ -27,7 +27,7 @@ import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class TradeConfigDO extends BaseDO {
+public class TradeConfigDO extends TenantBaseDO {
/**
* 自增主键
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java
index a1c1efff..6cdb5093 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.delivery;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -15,7 +15,7 @@ import lombok.Data;
@TableName(value ="trade_delivery_express")
@KeySequence("trade_delivery_express_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
-public class DeliveryExpressDO extends BaseDO {
+public class DeliveryExpressDO extends TenantBaseDO {
/**
* 编号,自增
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java
index c3bb30e9..47620777 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateChargeDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.delivery;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.IntegerListTypeHandler;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
@@ -18,7 +18,7 @@ import java.util.List;
@TableName(value ="trade_delivery_express_template_charge", autoResultMap = true)
@KeySequence("trade_delivery_express_template_charge_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
-public class DeliveryExpressTemplateChargeDO extends BaseDO {
+public class DeliveryExpressTemplateChargeDO extends TenantBaseDO {
/**
* 编号,自增
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateDO.java
index b6d6db3b..3d404d90 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.delivery;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -15,7 +15,7 @@ import lombok.*;
@TableName("trade_delivery_express_template")
@KeySequence("trade_delivery_express_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
-public class DeliveryExpressTemplateDO extends BaseDO {
+public class DeliveryExpressTemplateDO extends TenantBaseDO {
/**
* 编号,自增
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java
index 8bf035b7..8fe88f79 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.delivery;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.IntegerListTypeHandler;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
@@ -18,7 +18,7 @@ import java.util.List;
@TableName(value ="trade_delivery_express_template_free", autoResultMap = true)
@KeySequence("trade_delivery_express_template_free_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
-public class DeliveryExpressTemplateFreeDO extends BaseDO {
+public class DeliveryExpressTemplateFreeDO extends TenantBaseDO {
/**
* 编号
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java
index 93fe74f2..b8082ed4 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryPickUpStoreDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.delivery;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.baomidou.mybatisplus.annotation.KeySequence;
@@ -21,7 +21,7 @@ import java.util.List;
@TableName(value ="trade_delivery_pick_up_store", autoResultMap = true)
@KeySequence("trade_delivery_pick_up_store_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
-public class DeliveryPickUpStoreDO extends BaseDO {
+public class DeliveryPickUpStoreDO extends TenantBaseDO {
/**
* 编号
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
index 02962b9e..4fd6bcac 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.order;
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
@@ -35,7 +35,7 @@ import java.util.Map;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class TradeOrderDO extends BaseDO {
+public class TradeOrderDO extends TenantBaseDO {
/**
* 发货物流公司编号 - 空(无需发货)
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java
index db941fb4..85a2a165 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.order;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO;
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
@@ -21,7 +21,7 @@ import java.util.List;
@TableName(value = "trade_order_item", autoResultMap = true)
@KeySequence("trade_order_item_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
-public class TradeOrderItemDO extends BaseDO {
+public class TradeOrderItemDO extends TenantBaseDO {
// ========== 订单项基本信息 ==========
/**
@@ -208,4 +208,3 @@ public class TradeOrderItemDO extends BaseDO {
}
}
-
diff --git a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderLogDO.java b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderLogDO.java
index 36022c16..bda5ab38 100644
--- a/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderLogDO.java
+++ b/yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderLogDO.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.order;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderOperateTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -21,7 +21,7 @@ import lombok.*;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class TradeOrderLogDO extends BaseDO {
+public class TradeOrderLogDO extends TenantBaseDO {
/**
* 用户类型 - 系统
diff --git a/yudao-module-mall/yudao-module-trade/src/test/java/cn/iocoder/yudao/module/trade/dal/dataobject/AfterSaleTenantContractTest.java b/yudao-module-mall/yudao-module-trade/src/test/java/cn/iocoder/yudao/module/trade/dal/dataobject/AfterSaleTenantContractTest.java
new file mode 100644
index 00000000..390c21fc
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade/src/test/java/cn/iocoder/yudao/module/trade/dal/dataobject/AfterSaleTenantContractTest.java
@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.module.trade.dal.dataobject;
+
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleLogDO;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class AfterSaleTenantContractTest {
+
+ @Test
+ void activatedAfterSaleRecordsParticipateInFrameworkTenantIsolation() {
+ assertThat(TenantBaseDO.class).isAssignableFrom(AfterSaleDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(AfterSaleLogDO.class);
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-trade/src/test/java/cn/iocoder/yudao/module/trade/dal/dataobject/BrokerageTenantContractTest.java b/yudao-module-mall/yudao-module-trade/src/test/java/cn/iocoder/yudao/module/trade/dal/dataobject/BrokerageTenantContractTest.java
new file mode 100644
index 00000000..419a05f8
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade/src/test/java/cn/iocoder/yudao/module/trade/dal/dataobject/BrokerageTenantContractTest.java
@@ -0,0 +1,35 @@
+package cn.iocoder.yudao.module.trade.dal.dataobject;
+
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
+import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRejectReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class BrokerageTenantContractTest {
+
+ @Test
+ void nativeBrokerageRecordsParticipateInTenantIsolation() {
+ assertThat(TenantBaseDO.class).isAssignableFrom(BrokerageUserDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(BrokerageRecordDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(BrokerageWithdrawDO.class);
+ }
+
+ @Test
+ void withdrawalRequestsRejectMissingTypesNonPositiveAmountsAndBlankAuditReasons() throws Exception {
+ assertThat(AppBrokerageWithdrawCreateReqVO.class.getDeclaredField("type")
+ .isAnnotationPresent(NotNull.class)).isTrue();
+ assertThat(AppBrokerageWithdrawCreateReqVO.class.getDeclaredField("price")
+ .isAnnotationPresent(Positive.class)).isTrue();
+ assertThat(BrokerageWithdrawRejectReqVO.class.getDeclaredField("auditReason")
+ .isAnnotationPresent(NotBlank.class)).isTrue();
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-trade/src/test/java/cn/iocoder/yudao/module/trade/dal/dataobject/DeliveryTenantContractTest.java b/yudao-module-mall/yudao-module-trade/src/test/java/cn/iocoder/yudao/module/trade/dal/dataobject/DeliveryTenantContractTest.java
new file mode 100644
index 00000000..7a537b21
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade/src/test/java/cn/iocoder/yudao/module/trade/dal/dataobject/DeliveryTenantContractTest.java
@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.trade.dal.dataobject;
+
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateChargeDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressTemplateFreeDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class DeliveryTenantContractTest {
+
+ @Test
+ void activatedDeliveryRecordsParticipateInFrameworkTenantIsolation() {
+ assertThat(TenantBaseDO.class).isAssignableFrom(DeliveryExpressDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(DeliveryExpressTemplateDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(DeliveryExpressTemplateChargeDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(DeliveryExpressTemplateFreeDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(DeliveryPickUpStoreDO.class);
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-trade/src/test/java/cn/iocoder/yudao/module/trade/dal/dataobject/TradeTenantContractTest.java b/yudao-module-mall/yudao-module-trade/src/test/java/cn/iocoder/yudao/module/trade/dal/dataobject/TradeTenantContractTest.java
new file mode 100644
index 00000000..a21a0dc5
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade/src/test/java/cn/iocoder/yudao/module/trade/dal/dataobject/TradeTenantContractTest.java
@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.trade.dal.dataobject;
+
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class TradeTenantContractTest {
+
+ @Test
+ void activatedTradeRecordsParticipateInFrameworkTenantIsolation() {
+ assertThat(TenantBaseDO.class).isAssignableFrom(TradeConfigDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(CartDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(TradeOrderDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(TradeOrderItemDO.class);
+ assertThat(TenantBaseDO.class).isAssignableFrom(TradeOrderLogDO.class);
+ }
+
+}