diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
index 102f858fc..1d0ea189f 100644
--- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
+++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
@@ -34,8 +34,9 @@ public interface ErrorCodeConstants {
// ========== 商品 SPU 1-008-005-000 ==========
ErrorCode SPU_NOT_EXISTS = new ErrorCode(1_008_005_000, "商品 SPU 不存在");
ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1_008_005_001, "商品分类不正确,原因:必须使用第二级的商品分类及以下");
- ErrorCode SPU_NOT_ENABLE = new ErrorCode(1_008_005_002, "商品 SPU【{}】不处于上架状态");
- ErrorCode SPU_NOT_RECYCLE = new ErrorCode(1_008_005_003, "商品 SPU 不处于回收站状态");
+ ErrorCode SPU_SAVE_FAIL_COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1_008_005_002, "商品 SPU 保存失败,原因:优惠卷不存在");
+ ErrorCode SPU_NOT_ENABLE = new ErrorCode(1_008_005_003, "商品 SPU【{}】不处于上架状态");
+ ErrorCode SPU_NOT_RECYCLE = new ErrorCode(1_008_005_004, "商品 SPU 不处于回收站状态");
// ========== 商品 SKU 1-008-006-000 ==========
ErrorCode SKU_NOT_EXISTS = new ErrorCode(1_008_006_000, "商品 SKU 不存在");
diff --git a/yudao-module-mall/yudao-module-product-biz/pom.xml b/yudao-module-mall/yudao-module-product-biz/pom.xml
index f6190ceda..385b6690e 100644
--- a/yudao-module-mall/yudao-module-product-biz/pom.xml
+++ b/yudao-module-mall/yudao-module-product-biz/pom.xml
@@ -28,6 +28,11 @@
yudao-module-member-api
${revision}
+
+ cn.iocoder.boot
+ yudao-module-promotion-api
+ ${revision}
+
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
index 7f88dd8c6..f41138179 100755
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
@@ -11,6 +11,8 @@ import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
+import cn.iocoder.yudao.module.promotion.api.coupon.CouponTemplateApi;
+import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponTemplateRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -43,6 +45,9 @@ public class ProductSpuController {
@Resource
private ProductSkuService productSkuService;
+ @Resource
+ private CouponTemplateApi couponTemplateApi;
+
@PostMapping("/create")
@Operation(summary = "创建商品 SPU")
@PreAuthorize("@ss.hasPermission('product:spu:create')")
@@ -87,7 +92,10 @@ public class ProductSpuController {
}
// 查询商品 SKU
List skus = productSkuService.getSkuListBySpuId(spu.getId());
- return success(ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus));
+ // 查询优惠卷
+ List couponTemplateList = couponTemplateApi.getCouponTemplateListByIds(
+ spu.getGiveCouponTemplateIds());
+ return success(ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus, couponTemplateList));
}
@GetMapping("/list-all-simple")
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java
index 23c2467f8..7f2c22c95 100755
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java
@@ -96,19 +96,31 @@ public class ProductSpuBaseVO {
@NotNull(message = "商品赠送积分不能为空")
private Integer giveIntegral;
- @Schema(description = "赠送的优惠劵编号的数组", example = "[1, 10]") // TODO 这块前端还未实现
- private List giveCouponTemplateIds;
+ @Schema(description = "赠送的优惠劵数组包含优惠券编号和名称")
+ private List giveCouponTemplates;
@Schema(description = "分销类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
@NotNull(message = "商品分销类型不能为空")
private Boolean subCommissionType;
- @Schema(description = "活动展示顺序", example = "[1, 3, 2, 4, 5]") // TODO 这块前端还未实现
+ @Schema(description = "活动展示顺序", example = "[1, 3, 2, 4, 5]")
private List activityOrders;
// ========== 统计相关字段 =========
- @Schema(description = "虚拟销量", example = "芋道")
+ @Schema(description = "虚拟销量", example = "66")
private Integer virtualSalesCount;
+ @Schema(description = "管理后台 - 商品 SPU 赠送的优惠卷")
+ @Data
+ public static class GiveCouponTemplate {
+
+ @Schema(description = "模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "优惠劵名", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节送送送")
+ private String name;
+
+ }
+
}
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
index e8e6a8bc1..0b83abe42 100755
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
@@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.enums.DictTypeConstants;
+import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponTemplateRespDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
@@ -100,10 +101,14 @@ public interface ProductSpuConvert {
List convertListForGetSpuDetail(List skus);
- default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List skus) {
- ProductSpuDetailRespVO detailRespVO = convert03(spu);
- detailRespVO.setSkus(ProductSkuConvert.INSTANCE.convertList(skus));
- return detailRespVO;
+ List convertList04(List couponTemplateList);
+
+ default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List skus,
+ List couponTemplateList) {
+ ProductSpuDetailRespVO respVO = convert03(spu);
+ respVO.setSkus(ProductSkuConvert.INSTANCE.convertList(skus));
+ respVO.setGiveCouponTemplates(convertList04(couponTemplateList));
+ return respVO;
}
default List convertForSpuDetailRespListVO(List spus, List skus) {
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
index 9e073fee7..9ce55a096 100755
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
@@ -194,7 +194,7 @@ public class ProductSpuDO extends BaseDO {
* 对应 PromotionTypeEnum 枚举
*/
@TableField(typeHandler = JacksonTypeHandler.class)
- private List activityOrders;
+ private List activityOrders; // TODO @芋艿: 活动顺序字段长度需要增加
// ========== 统计相关字段 =========
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
index 521a5fefe..5f2fcbb04 100755
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
@@ -16,8 +16,10 @@ import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
-import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
+import cn.iocoder.yudao.module.promotion.api.coupon.CouponTemplateApi;
+import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponTemplateRespDTO;
+import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
import com.google.common.collect.Maps;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@@ -26,10 +28,10 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.*;
+import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMinValue;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.CATEGORY_LEVEL;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
@@ -52,9 +54,10 @@ public class ProductSpuServiceImpl implements ProductSpuService {
private ProductBrandService brandService;
@Resource
private ProductCategoryService categoryService;
+
@Resource
- @Lazy // 循环依赖,避免报错
- private ProductPropertyValueService productPropertyValueService;
+ @Lazy
+ private CouponTemplateApi couponTemplateApi;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -62,6 +65,9 @@ public class ProductSpuServiceImpl implements ProductSpuService {
// 校验分类、品牌
validateCategory(createReqVO.getCategoryId());
brandService.validateProductBrand(createReqVO.getBrandId());
+ // 校验优惠券
+ Set giveCouponTemplateIds = convertSet(createReqVO.getGiveCouponTemplates(), ProductSpuCreateReqVO.GiveCouponTemplate::getId);
+ validateCouponTemplate(giveCouponTemplateIds);
// 校验 SKU
List skuSaveReqList = createReqVO.getSkus();
productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType());
@@ -69,6 +75,8 @@ public class ProductSpuServiceImpl implements ProductSpuService {
ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO);
// 初始化 SPU 中 SKU 相关属性
initSpuFromSkus(spu, skuSaveReqList);
+ // 设置优惠券
+ spu.setGiveCouponTemplateIds(CollUtil.newArrayList(giveCouponTemplateIds));
// 插入 SPU
productSpuMapper.insert(spu);
// 插入 SKU
@@ -85,6 +93,9 @@ public class ProductSpuServiceImpl implements ProductSpuService {
// 校验分类、品牌
validateCategory(updateReqVO.getCategoryId());
brandService.validateProductBrand(updateReqVO.getBrandId());
+ // 校验优惠券
+ Set giveCouponTemplateIds = convertSet(updateReqVO.getGiveCouponTemplates(), ProductSpuUpdateReqVO.GiveCouponTemplate::getId);
+ validateCouponTemplate(giveCouponTemplateIds);
// 校验SKU
List skuSaveReqList = updateReqVO.getSkus();
productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType());
@@ -92,6 +103,8 @@ public class ProductSpuServiceImpl implements ProductSpuService {
// 更新 SPU
ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO);
initSpuFromSkus(updateObj, skuSaveReqList);
+ // 设置优惠券
+ updateObj.setGiveCouponTemplateIds(CollUtil.newArrayList(giveCouponTemplateIds));
productSpuMapper.updateById(updateObj);
// 批量更新 SKU
productSkuService.updateSkuList(updateObj.getId(), updateReqVO.getSkus());
@@ -125,6 +138,10 @@ public class ProductSpuServiceImpl implements ProductSpuService {
// 默认商品浏览量
spu.setBrowseCount(0);
}
+ // 如果活动顺序为空则默认初始化
+ if (CollUtil.isEmpty(spu.getActivityOrders())) {
+ spu.setActivityOrders(Arrays.stream(PromotionTypeEnum.ARRAYS).boxed().collect(Collectors.toList()));
+ }
}
/**
@@ -140,6 +157,13 @@ public class ProductSpuServiceImpl implements ProductSpuService {
}
}
+ private void validateCouponTemplate(Collection ids) {
+ List couponTemplateList = couponTemplateApi.getCouponTemplateListByIds(ids);
+ if (couponTemplateList.size() != ids.size()) {
+ throw exception(SPU_SAVE_FAIL_COUPON_TEMPLATE_NOT_EXISTS);
+ }
+ }
+
@Override
public List validateSpuList(Collection ids) {
if (CollUtil.isEmpty(ids)) {
diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponTemplateApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponTemplateApi.java
new file mode 100644
index 000000000..d31e80ec1
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponTemplateApi.java
@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.promotion.api.coupon;
+
+import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponTemplateRespDTO;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 优惠劵模版 API 接口
+ *
+ * @author HUIHUI
+ */
+public interface CouponTemplateApi {
+
+ /**
+ * 获得优惠券模版的精简信息列表
+ *
+ * @param ids 优惠券模版编号
+ * @return 优惠券模版的精简信息列表
+ */
+ List getCouponTemplateListByIds(Collection ids);
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponTemplateRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponTemplateRespDTO.java
new file mode 100644
index 000000000..a54ccf2b0
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponTemplateRespDTO.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.promotion.api.coupon.dto;
+
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import lombok.Data;
+
+/**
+ * 优惠券模版 Response DTO
+ *
+ * @author HUIHUI
+ */
+@Data
+public class CouponTemplateRespDTO {
+ /**
+ * 模板编号,自增唯一
+ */
+
+ private Long id;
+ /**
+ * 优惠劵名
+ */
+ private String name;
+
+ /**
+ * 状态
+ *
+ * 枚举 {@link CommonStatusEnum}
+ */
+ private Integer status;
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/banner/BannerPositionEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/banner/BannerPositionEnum.java
new file mode 100644
index 000000000..5d99fc1b4
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/banner/BannerPositionEnum.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.module.promotion.enums.banner;
+
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
+import cn.iocoder.yudao.module.promotion.enums.bargain.BargainRecordStatusEnum;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * Banner Position 枚举
+ *
+ * @author HUIHUI
+ */
+@AllArgsConstructor
+@Getter
+public enum BannerPositionEnum implements IntArrayValuable {
+
+ HOME_POSITION(1, "首页"),
+ SECKILL_POSITION(2, "秒杀活动页"),
+ COMBINATION_POSITION(3, "砍价活动页"),
+ DISCOUNT_POSITION(4, "限时折扣页"),
+ REWARD_POSITION(5, "满减送页");
+
+ public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BargainRecordStatusEnum::getStatus).toArray();
+ /**
+ * 值
+ */
+ private final Integer position;
+ /**
+ * 名字
+ */
+ private final String name;
+
+ @Override
+ public int[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponTemplateApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponTemplateApiImpl.java
new file mode 100644
index 000000000..8c4f443f5
--- /dev/null
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponTemplateApiImpl.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.promotion.api.coupon;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponTemplateRespDTO;
+import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert;
+import cn.iocoder.yudao.module.promotion.service.coupon.CouponTemplateService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 优惠劵模版 API 接口实现类
+ *
+ * @author HUIHUI
+ */
+@Service
+public class CouponTemplateApiImpl implements CouponTemplateApi {
+
+ @Resource
+ private CouponTemplateService couponTemplateService;
+
+ @Override
+ public List getCouponTemplateListByIds(Collection ids) {
+ if (CollUtil.isEmpty(ids)) { // 防御一下
+ return Collections.emptyList();
+ }
+ return CouponTemplateConvert.INSTANCE.convertList(couponTemplateService.getCouponTemplateListByIds(ids));
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java
index ff90cb7a0..f840254cc 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java
@@ -27,6 +27,10 @@ public class BannerBaseVO {
@NotNull(message = "图片地址不能为空")
private String picUrl;
+ @Schema(description = "position", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotNull(message = "position 不能为空")
+ private Integer position;
+
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "排序不能为空")
private Integer sort;
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java
index b97008ccd..4aafb9f46 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java
@@ -25,7 +25,6 @@ public class BannerPageReqVO extends PageParam {
@Schema(description = "标题")
private String title;
-
@Schema(description = "状态")
@InEnum(CommonStatusEnum.class)
private Integer status;
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleController.java
index 534e82ff3..5acb43cfe 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleController.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleController.java
@@ -56,13 +56,11 @@ public class AppArticleController {
return success(ArticleConvert.INSTANCE.convert01(articleService.getArticle(id)));
}
- // TODO @puhui999:add-browse-count 噢;前端 uniapp 也要接下;就是打开文章的时候,调用下这个接口;
- @PutMapping("/add-browseCount")
+ @PutMapping("/add-browse-count")
@Operation(summary = "增加文章浏览量")
@Parameter(name = "id", description = "文章编号", example = "1024")
public CommonResult addBrowseCount(@RequestParam("id") Long id) {
- // TODO @puhui999:addArticleBrowseCount
- articleService.addBrowseCount(id);
+ articleService.addArticleBrowseCount(id);
return success(true);
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java
index 3a4ff8a78..4947e113c 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java
@@ -2,18 +2,23 @@ package cn.iocoder.yudao.module.promotion.controller.app.banner;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.promotion.controller.app.banner.vo.AppBannerRespVO;
+import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO;
+import cn.iocoder.yudao.module.promotion.service.banner.BannerService;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
-import java.util.ArrayList;
+import javax.annotation.Resource;
+import java.time.Duration;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
@RestController
@RequestMapping("/promotion/banner")
@@ -21,22 +26,39 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Validated
public class AppBannerController {
+ @Resource
+ private BannerService bannerService;
+ /**
+ * {@link AppBannerRespVO} 缓存,通过它异步刷新 {@link #getBannerList0(Integer)} 所要的首页数据
+ */
+ private final LoadingCache> bannerListCache = buildAsyncReloadingCache(Duration.ofSeconds(10L),
+ new CacheLoader>() {
+
+ @Override
+ public List load(Integer position) {
+ return getBannerList0(position);
+ }
+
+ });
+
@GetMapping("/list")
@Operation(summary = "获得 banner 列表")
- // todo @芋艿:swagger 注解,待补全
- // TODO @芋艿:可以增加缓存,提升性能
- // TODO @芋艿:position = 1 时,首页;position = 10 时,拼团活动页
+ @Parameter(name = "position", description = "Banner position", example = "1")
public CommonResult> getBannerList(@RequestParam("position") Integer position) {
- List bannerList = new ArrayList<>();
- AppBannerRespVO banner1 = new AppBannerRespVO();
- banner1.setUrl("https://www.example.com/link1");
- banner1.setPicUrl("https://api.java.crmeb.net/crmebimage/public/content/2022/08/04/0f78716213f64bfa83f191d51a832cbf73f6axavoy.jpg");
- bannerList.add(banner1);
- AppBannerRespVO banner2 = new AppBannerRespVO();
- banner2.setUrl("https://www.example.com/link2");
- banner2.setPicUrl("https://api.java.crmeb.net/crmebimage/public/content/2023/01/11/be09e755268b43ee90b0db3a3e1b7132r7a6t2wvsm.jpg");
- bannerList.add(banner2);
- return success(bannerList);
+ return success(bannerListCache.getUnchecked(position));
+ }
+
+ private List getBannerList0(Integer position) {
+ List bannerList = bannerService.getBannerListByPosition(position);
+ return BannerConvert.INSTANCE.convertList01(bannerList);
+ }
+
+ @PutMapping("/add-browse-count")
+ @Operation(summary = "增加 Banner 点击量")
+ @Parameter(name = "id", description = "Banner 编号", example = "1024")
+ public CommonResult addBrowseCount(@RequestParam("id") Long id) {
+ bannerService.addBannerBrowseCount(id);
+ return success(true);
}
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/vo/AppBannerRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/vo/AppBannerRespVO.java
index 7656a431d..cc36d87d4 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/vo/AppBannerRespVO.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/vo/AppBannerRespVO.java
@@ -9,6 +9,13 @@ import javax.validation.constraints.NotNull;
@Data
public class AppBannerRespVO {
+ @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED)
+ private Long id;
+
+ @Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotNull(message = "标题不能为空")
+ private String title;
+
@Schema(description = "跳转链接", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "跳转链接不能为空")
private String url;
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java
index 3e2afeb49..d2d75362e 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO;
import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.app.banner.vo.AppBannerRespVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@@ -25,4 +26,6 @@ public interface BannerConvert {
BannerDO convert(BannerUpdateReqVO updateReqVO);
+ List convertList01(List bannerList);
+
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java
index e09d0f013..8e1c57f5c 100755
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.convert.coupon;
import cn.hutool.core.map.MapUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponTemplateRespDTO;
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO;
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateRespVO;
@@ -58,4 +59,6 @@ public interface CouponTemplateConvert {
}
}
+ List convertList(List list);
+
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java
index 585462b95..0a2065e77 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java
@@ -1,6 +1,8 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.banner;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.promotion.enums.banner.BannerPositionEnum;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
@@ -40,14 +42,25 @@ public class BannerDO extends BaseDO {
private Integer sort;
/**
- * 状态 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
+ * 状态 {@link CommonStatusEnum}
*/
private Integer status;
+
+ /**
+ * 定位 {@link BannerPositionEnum}
+ */
+ private Integer position;
+
/**
* 备注
*/
private String memo;
- // TODO 芋艿 点击次数。&& 其他数据相关
+ /**
+ * 点击次数
+ */
+ private Integer browseCount;
+
+ // TODO 芋艿 其他数据相关
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java
index d98375365..74bd3c7da 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java
@@ -5,8 +5,11 @@ 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.banner.vo.BannerPageReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
+import java.util.List;
+
/**
* Banner Mapper
*
@@ -23,4 +26,14 @@ public interface BannerMapper extends BaseMapperX {
.orderByDesc(BannerDO::getSort));
}
+ default void updateBrowseCount(Long id) {
+ update(null, new LambdaUpdateWrapper()
+ .eq(BannerDO::getId, id)
+ .setSql("browse_count = browse_count + 1"));
+ }
+
+ default List selectBannerListByPosition(Integer position) {
+ return selectList(new LambdaQueryWrapperX().eq(BannerDO::getPosition, position));
+ }
+
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java
index fd5466648..72d604e77 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java
@@ -86,7 +86,6 @@ public interface BargainActivityMapper extends BaseMapperX {
.last("LIMIT " + count));
}
- // TODO @puhui999:是不是返回 BargainActivityDO 更干净哈?分组后返回 DO 的话需要联表查询
/**
* 查询出指定 spuId 的 spu 参加的活动最接近现在的一条记录。多个的话,一个 spuId 对应一个最近的活动编号
*
@@ -102,7 +101,6 @@ public interface BargainActivityMapper extends BaseMapperX {
.groupBy("spu_id"));
}
- // TODO @puhui999:是不是只要 endTime 小于就可以啦;
/**
* 获取指定活动编号的活动列表且
* 开始时间和结束时间小于给定时间 dateTime 的活动列表
@@ -115,7 +113,7 @@ public interface BargainActivityMapper extends BaseMapperX {
return selectList(new LambdaQueryWrapperX()
.in(BargainActivityDO::getId, ids)
.lt(BargainActivityDO::getStartTime, dateTime)
- .lt(BargainActivityDO::getEndTime, dateTime)
+ .gt(BargainActivityDO::getEndTime, dateTime)// 开始时间 < 指定时间 < 结束时间,也就是说获取指定时间段的活动
.orderByDesc(BargainActivityDO::getCreateTime));
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationActivityMapper.java
index 530478e69..55e975c45 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationActivityMapper.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationActivityMapper.java
@@ -71,7 +71,7 @@ public interface CombinationActivityMapper extends BaseMapperX()
.in(CombinationActivityDO::getId, ids)
.lt(CombinationActivityDO::getStartTime, dateTime)
- .lt(CombinationActivityDO::getEndTime, dateTime)
+ .gt(CombinationActivityDO::getEndTime, dateTime)// 开始时间 < 指定时间 < 结束时间,也就是说获取指定时间段的活动
.orderByDesc(CombinationActivityDO::getCreateTime));
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java
index f5715298d..ba5706a77 100755
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java
@@ -8,10 +8,11 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
+import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
@@ -39,7 +40,11 @@ public interface CouponTemplateMapper extends BaseMapperX {
.orderByDesc(CouponTemplateDO::getId));
}
- void updateTakeCount(@Param("id") Long id, @Param("incrCount") Integer incrCount);
+ default void updateTakeCount(Long id, Integer incrCount) {
+ update(null, new LambdaUpdateWrapper()
+ .eq(CouponTemplateDO::getId, id)
+ .setSql("take_count = take_count + " + incrCount));
+ }
default List selectListByTakeType(Integer takeType) {
return selectList(CouponTemplateDO::getTakeType, takeType);
@@ -70,4 +75,8 @@ public interface CouponTemplateMapper extends BaseMapperX {
return canTakeConsumer;
}
+ default List selectListByIds(Collection ids) {
+ return selectList(new LambdaQueryWrapperX().in(CouponTemplateDO::getId, ids));
+ }
+
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java
index 82fbafecd..ca40e7602 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java
@@ -103,7 +103,7 @@ public interface SeckillActivityMapper extends BaseMapperX {
return selectList(new LambdaQueryWrapperX()
.in(SeckillActivityDO::getId, ids)
.lt(SeckillActivityDO::getStartTime, dateTime)
- .lt(SeckillActivityDO::getEndTime, dateTime)
+ .gt(SeckillActivityDO::getEndTime, dateTime)// 开始时间 < 指定时间 < 结束时间,也就是说获取指定时间段的活动
.orderByDesc(SeckillActivityDO::getCreateTime));
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/article/ArticleService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/article/ArticleService.java
index 81b463373..4188cc681 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/article/ArticleService.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/article/ArticleService.java
@@ -93,6 +93,6 @@ public interface ArticleService {
*
* @param id 文章编号
*/
- void addBrowseCount(Long id);
+ void addArticleBrowseCount(Long id);
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/article/ArticleServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/article/ArticleServiceImpl.java
index 47e614057..7a4e69a6e 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/article/ArticleServiceImpl.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/article/ArticleServiceImpl.java
@@ -111,7 +111,7 @@ public class ArticleServiceImpl implements ArticleService {
}
@Override
- public void addBrowseCount(Long id) {
+ public void addArticleBrowseCount(Long id) {
// 校验文章是否存在
validateArticleExists(id);
// 增加浏览次数
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java
index d541211be..404f7f5b2 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java
@@ -46,12 +46,6 @@ public interface BannerService {
*/
BannerDO getBanner(Long id);
- /**
- * 获得所有 Banner列表
- * @return Banner列表
- */
- List getBannerList();
-
/**
* 获得 Banner 分页
*
@@ -60,4 +54,19 @@ public interface BannerService {
*/
PageResult getBannerPage(BannerPageReqVO pageReqVO);
+ /**
+ * 增加 Banner 点击量
+ *
+ * @param id Banner编号
+ */
+ void addBannerBrowseCount(Long id);
+
+ /**
+ * 获得 Banner 列表
+ *
+ * @param position 定位
+ * @return Banner 列表
+ */
+ List getBannerListByPosition(Integer position);
+
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java
index 013ae8992..46c22f0e2 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java
@@ -65,14 +65,22 @@ public class BannerServiceImpl implements BannerService {
return bannerMapper.selectById(id);
}
- @Override
- public List getBannerList() {
- return bannerMapper.selectList();
- }
-
@Override
public PageResult getBannerPage(BannerPageReqVO pageReqVO) {
return bannerMapper.selectPage(pageReqVO);
}
+ @Override
+ public void addBannerBrowseCount(Long id) {
+ // 校验 Banner 是否存在
+ validateBannerExists(id);
+ // 增加点击次数
+ bannerMapper.updateBrowseCount(id);
+ }
+
+ @Override
+ public List getBannerListByPosition(Integer position) {
+ return bannerMapper.selectBannerListByPosition(position);
+ }
+
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
index db4197f52..f5b78ab13 100644
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
@@ -369,8 +369,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
keyValue.setValue(keyValue.getValue() + 1);
}
} catch (Exception ignored) { // 处理异常继续循环
- // TODO @puhui999:拼团过期 or 虚拟成团 可以改成 expireCombinationRecord;因为找方法更容易一些;
- log.error("[拼团过期 or 虚拟成团][record({}) 处理异常,请进行处理!record 数据是:{}]",
+ log.error("[expireCombinationRecord][record({}) 处理异常,请进行处理!record 数据是:{}]",
record.getId(), JsonUtils.toJsonString(record));
}
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java
index db0fa6cb4..a47644a4c 100755
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java
@@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
import javax.validation.Valid;
+import java.util.Collection;
import java.util.List;
/**
@@ -91,4 +92,12 @@ public interface CouponTemplateService {
List getCouponTemplateList(List canTakeTypes, Integer productScope,
Long productScopeValue, Integer count);
+ /**
+ * 获得优惠券模版列表
+ *
+ * @param ids 优惠券模版编号
+ * @return 优惠券模版列表
+ */
+ List getCouponTemplateListByIds(Collection ids);
+
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java
index 2228df71a..8a7fbb8ba 100755
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java
+++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java
@@ -16,6 +16,7 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
+import java.util.Collection;
import java.util.List;
import java.util.Objects;
@@ -126,4 +127,9 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
return couponTemplateMapper.selectList(canTakeTypes, productScope, productScopeValue, count);
}
+ @Override
+ public List getCouponTemplateListByIds(Collection ids) {
+ return couponTemplateMapper.selectListByIds(ids);
+ }
+
}
diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/coupon/CouponTemplateMapper.xml b/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/coupon/CouponTemplateMapper.xml
deleted file mode 100644
index 987143534..000000000
--- a/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/coupon/CouponTemplateMapper.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
- UPDATE promotion_coupon_template
- SET take_count = take_count + #{incrCount}
- WHERE id = #{id}
-
-
-
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInController.java
deleted file mode 100644
index ec5e0a4a8..000000000
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInController.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package cn.iocoder.yudao.module.member.controller.app.signin;
-
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.module.member.service.signin.MemberSignInRecordService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.annotation.Resource;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-
-// TODO @xiaqing:sign-in
-@Tag(name = "签到APP - 签到")
-@RestController
-@RequestMapping("/member/signin")
-public class AppMemberSignInController {
-
- @Resource
- private MemberSignInRecordService signInRecordService;
-
- // TODO @xiaqing:泛型:
- // TODO @xiaqing:合并到 AppMemberSignInRecordController 的 getSignInRecordSummary 里哈。
- @Operation(summary = "个人签到信息")
- @GetMapping("/get-summary")
- public CommonResult getUserSummary() {
- return success(signInRecordService.getSignInRecordSummary(getLoginUserId()));
- }
-
-}
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java
index fa07d85ec..2f7afa042 100644
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java
+++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java
@@ -31,22 +31,11 @@ public class AppMemberSignInRecordController {
@Resource
private MemberSignInRecordService signInRecordService;
- // TODO 芋艿:临时 mock => UserSignController.getUserInfo
@GetMapping("/get-summary")
@Operation(summary = "获得个人签到统计")
@PreAuthenticated
public CommonResult getSignInRecordSummary() {
- AppMemberSignInRecordSummaryRespVO respVO = new AppMemberSignInRecordSummaryRespVO();
- if (false) {
- respVO.setTotalDay(100);
- respVO.setContinuousDay(5);
- respVO.setTodaySignIn(true);
- } else {
- respVO.setTotalDay(100);
- respVO.setContinuousDay(10);
- respVO.setTodaySignIn(false);
- }
- return success(respVO);
+ return success(signInRecordService.getSignInRecordSummary(getLoginUserId()));
}
@PostMapping("/create")
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInRecordRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInRecordRespVO.java
deleted file mode 100644
index c31e365ec..000000000
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInRecordRespVO.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.member.controller.app.signin.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "用户签到积分 Response VO")
-@Data
-public class AppMemberSignInRecordRespVO {
-
- @Schema(description = "第几天签到", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
- private Integer day;
-
- @Schema(description = "签到的积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
- private Integer point;
-
- @Schema(description = "签到的经验", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
- private Integer experience;
-
- @Schema(description = "签到时间", requiredMode = Schema.RequiredMode.REQUIRED)
- private LocalDateTime createTime;
-
-}
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInSummaryRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInSummaryRespVO.java
deleted file mode 100644
index 55eaddbdd..000000000
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInSummaryRespVO.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package cn.iocoder.yudao.module.member.controller.app.signin.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "用户签到统计信息 Response VO")
-@Data
-public class AppMemberSignInSummaryRespVO {
-
- @Schema(description = "持续签到天数", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
- private Integer continuousDay;
-
- @Schema(description = "总签到天数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
- private Integer totalDay;
-
- @Schema(description = "当天是否签到", requiredMode = Schema.RequiredMode.REQUIRED,example = "true")
- private Boolean todaySignIn ;
-
-}
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/signin/MemberSignInRecordConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/signin/MemberSignInRecordConvert.java
index edac5edae..6ad9794d8 100644
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/signin/MemberSignInRecordConvert.java
+++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/signin/MemberSignInRecordConvert.java
@@ -1,14 +1,19 @@
package cn.iocoder.yudao.module.member.convert.signin;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordRespVO;
import cn.iocoder.yudao.module.member.controller.app.signin.vo.record.AppMemberSignInRecordRespVO;
+import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInConfigDO;
import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
@@ -32,10 +37,37 @@ public interface MemberSignInRecordConvert {
memberUserRespDTO -> record.setNickname(memberUserRespDTO.getNickname())));
return voPageResult;
}
+
PageResult convertPage(PageResult pageResult);
PageResult convertPage02(PageResult pageResult);
AppMemberSignInRecordRespVO coverRecordToAppRecordVo(MemberSignInRecordDO memberSignInRecordDO);
+ default MemberSignInRecordDO convert(Long userId, MemberSignInRecordDO firstRecord, List signInConfigs) {
+ // 1. 计算今天是第几天签到
+ long day = ChronoUnit.DAYS.between(firstRecord.getCreateTime(), LocalDateTime.now());
+ // 2. 初始化签到信息
+ MemberSignInRecordDO signInRecord = new MemberSignInRecordDO().setUserId(userId)
+ .setDay(Integer.parseInt(Long.toString(day))) // 设置签到天数
+ .setPoint(0) // 设置签到积分默认为 0
+ .setExperience(0); // 设置签到经验默认为 0
+
+
+ // 3. 获取签到对应的积分数
+ MemberSignInConfigDO lastConfig = signInConfigs.get(signInConfigs.size() - 1); // 最大签到天数
+ if (day > lastConfig.getDay()) { // 超出范围按第一天的经验计算
+ signInRecord.setPoint(signInConfigs.get(0).getPoint());
+ signInRecord.setExperience(signInConfigs.get(0).getExperience());
+ return signInRecord;
+ }
+ MemberSignInConfigDO signInConfig = CollUtil.findOne(signInConfigs, config -> ObjUtil.equal(config.getDay(), day));
+ if (signInConfig == null) {
+ return signInRecord;
+ }
+ signInRecord.setPoint(signInConfig.getPoint());
+ signInRecord.setExperience(signInConfig.getExperience());
+ return signInRecord;
+ }
+
}
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/signin/MemberSignInRecordMapper.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/signin/MemberSignInRecordMapper.java
index 84e61a761..fcd4ae408 100644
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/signin/MemberSignInRecordMapper.java
+++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/signin/MemberSignInRecordMapper.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordPageReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@@ -35,9 +36,45 @@ public interface MemberSignInRecordMapper extends BaseMapperX selectListByUserId(Long userId){
- return selectList(new LambdaQueryWrapperX ()
+ /**
+ * 获取用户最近的签到记录信息,根据签到时间倒序
+ *
+ * @param userId 用户编号
+ * @return 签到记录列表
+ */
+ default MemberSignInRecordDO selectLastRecordByUserIdDesc(Long userId) {
+ return selectOne(new QueryWrapper()
+ .eq("user_id", userId)
+ .orderByDesc("create_time")
+ .last("limit 1"));
+ }
+
+ /**
+ * 获取用户最早的签到记录信息,根据签到时间倒序
+ *
+ * @param userId 用户编号
+ * @return 签到记录列表
+ */
+ default MemberSignInRecordDO selectLastRecordByUserIdAsc(Long userId) {
+ return selectOne(new QueryWrapper()
+ .eq("user_id", userId)
+ .orderByAsc("create_time")
+ .last("limit 1"));
+ }
+
+ default Long selectCountByUserId(Long userId) {
+ return selectCount(new LambdaQueryWrapperX()
+ .eq(MemberSignInRecordDO::getUserId, userId));
+ }
+
+ /**
+ * 获取用户的签到记录列表信息,根据签到时间倒序
+ *
+ * @param userId 用户编号
+ * @return 签到记录信息
+ */
+ default List selectListByUserId(Long userId) {
+ return selectList(new LambdaQueryWrapperX()
.eq(MemberSignInRecordDO::getUserId, userId)
.orderByDesc(MemberSignInRecordDO::getCreateTime));
}
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordService.java
index 4f1c365e0..b22ceed1a 100644
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordService.java
+++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordService.java
@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.member.service.signin;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordPageReqVO;
-import cn.iocoder.yudao.module.member.controller.app.signin.vo.AppMemberSignInSummaryRespVO;
+import cn.iocoder.yudao.module.member.controller.app.signin.vo.record.AppMemberSignInRecordSummaryRespVO;
import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO;
/**
@@ -24,7 +24,7 @@ public interface MemberSignInRecordService {
/**
* 【会员】获得签到记录分页
*
- * @param userId 用户编号
+ * @param userId 用户编号
* @param pageParam 分页查询
* @return 签到记录分页
*/
@@ -44,7 +44,7 @@ public interface MemberSignInRecordService {
* @param userId 用户编号
* @return 个人签到统计信息
*/
- AppMemberSignInSummaryRespVO getSignInRecordSummary(Long userId);
+ AppMemberSignInRecordSummaryRespVO getSignInRecordSummary(Long userId);
}
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java
index dca079dc2..586e60ac4 100644
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java
+++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java
@@ -1,19 +1,20 @@
package cn.iocoder.yudao.module.member.service.signin;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
-import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordPageReqVO;
-import cn.iocoder.yudao.module.member.controller.app.signin.vo.AppMemberSignInSummaryRespVO;
+import cn.iocoder.yudao.module.member.controller.app.signin.vo.record.AppMemberSignInRecordSummaryRespVO;
+import cn.iocoder.yudao.module.member.convert.signin.MemberSignInRecordConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInConfigDO;
import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO;
-import cn.iocoder.yudao.module.member.dal.mysql.signin.MemberSignInConfigMapper;
import cn.iocoder.yudao.module.member.dal.mysql.signin.MemberSignInRecordMapper;
-import cn.iocoder.yudao.module.member.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
import cn.iocoder.yudao.module.member.service.level.MemberLevelService;
@@ -21,17 +22,17 @@ import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDate;
-import java.time.temporal.ChronoUnit;
+import java.util.Comparator;
import java.util.List;
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.convertSet;
+import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.SIGN_IN_RECORD_TODAY_EXISTS;
/**
* 签到记录 Service 实现类
@@ -45,7 +46,7 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService
@Resource
private MemberSignInRecordMapper signInRecordMapper;
@Resource
- private MemberSignInConfigMapper signInConfigMapper;
+ private MemberSignInConfigService signInConfigService;
@Resource
private MemberPointRecordService pointRecordService;
@Resource
@@ -55,50 +56,64 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService
private MemberUserApi memberUserApi;
@Override
- public AppMemberSignInSummaryRespVO getSignInRecordSummary(Long userId) {
- AppMemberSignInSummaryRespVO vo = new AppMemberSignInSummaryRespVO();
+ public AppMemberSignInRecordSummaryRespVO getSignInRecordSummary(Long userId) {
+ // 1. 初始化默认返回信息
+ AppMemberSignInRecordSummaryRespVO vo = new AppMemberSignInRecordSummaryRespVO();
vo.setTotalDay(0);
vo.setContinuousDay(0);
vo.setTodaySignIn(false);
- //获取用户签到的记录,按照天数倒序获取
- List signInRecordDOList = signInRecordMapper.selectListByUserId(userId);
- // TODO @xiaqing:if 空的时候,直接 return;这样括号少,逻辑更简洁;
- if (!CollectionUtils.isEmpty(signInRecordDOList)) {
- //设置总签到天数
- vo.setTotalDay(signInRecordDOList.size()); // TODO @xiaqing:是不是不用读取 signInRecordDOList 所有的,而是 count下,然后另外再读取一条最后一条;
- //判断当天是否有签到复用校验方法
- // TODO @xiaqing:不要用异常实现逻辑;还是判断哈;
- try {
- validSignDay(signInRecordDOList.get(0));
- vo.setTodaySignIn(false);
- } catch (Exception e) {
- vo.setTodaySignIn(true);
- }
- //如果当天签到了则说明连续签到天数有意义,否则直接用默认值0
- if (vo.getTodaySignIn()) {
- //下方计算连续签到从2天开始,此处直接设置一天连续签到
- vo.setContinuousDay(1);
- //判断连续签到天数
- // TODO @xiaqing:这里逻辑,想想怎么在简化下,可读性可以在提升下哈;
- for (int i = 1; i < signInRecordDOList.size(); i++) {
- //前一天减1等于当前天数则说明连续,继续循环
- LocalDate cur = signInRecordDOList.get(i).getCreateTime().toLocalDate();
- LocalDate pre = signInRecordDOList.get(i - 1).getCreateTime().toLocalDate();
- if (1 == daysBetween(cur, pre)) {
- vo.setContinuousDay(i + 1);
- } else {
- break;
- }
- }
- }
-
+ // 2. 获取用户签到的记录数
+ Long signCount = signInRecordMapper.selectCountByUserId(userId);
+ if (ObjUtil.equal(signCount, 0L)) {
+ return vo;
}
+ vo.setTotalDay(signCount.intValue()); // 设置总签到天数
+
+ // 3. 校验当天是否有签到
+ MemberSignInRecordDO signInRecord = signInRecordMapper.selectLastRecordByUserIdDesc(userId);
+ if (signInRecord == null) {
+ return vo;
+ }
+ vo.setTodaySignIn(DateUtils.isToday(signInRecord.getCreateTime()));
+
+ // 4. 校验今天是否签到,没有签到则直接返回
+ if (!vo.getTodaySignIn()) {
+ return vo;
+ }
+ // 4.1. 判断连续签到天数
+ List signInRecords = signInRecordMapper.selectListByUserId(userId);
+ vo.setContinuousDay(calculateConsecutiveDays(signInRecords));
return vo;
}
- private long daysBetween(LocalDate date1, LocalDate date2) {
- return ChronoUnit.DAYS.between(date1, date2);
+ /**
+ * 计算连续签到天数
+ *
+ * @param signInRecords 签到记录列表
+ * @return int 连续签到天数
+ */
+ public int calculateConsecutiveDays(List signInRecords) {
+ int consecutiveDays = 1; // 初始连续天数为1
+ LocalDate previousDate = null;
+
+ for (MemberSignInRecordDO record : signInRecords) {
+ LocalDate currentDate = record.getCreateTime().toLocalDate();
+
+ if (previousDate != null) {
+ // 检查相邻两个日期是否连续
+ if (currentDate.minusDays(1).isEqual(previousDate)) {
+ consecutiveDays++;
+ } else {
+ // 如果日期不连续,停止遍历
+ break;
+ }
+ }
+
+ previousDate = currentDate;
+ }
+
+ return consecutiveDays;
}
@Override
@@ -108,7 +123,7 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService
if (StringUtils.isNotBlank(pageReqVO.getNickname())) {
List users = memberUserApi.getUserListByNickname(pageReqVO.getNickname());
// 如果查询用户结果为空直接返回无需继续查询
- if (CollectionUtils.isEmpty(users)) {
+ if (CollUtil.isEmpty(users)) {
return PageResult.empty();
}
userIds = convertSet(users, MemberUserRespDTO::getId);
@@ -125,73 +140,40 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService
@Override
@Transactional(rollbackFor = Exception.class)
public MemberSignInRecordDO createSignRecord(Long userId) {
- // 获取当前用户签到的最大天数
- // TODO @xiaqing:db 操作,dou封装到 mapper 中;
- // TODO @xiaqing:maxSignDay,是不是变量叫 lastRecord 会更容易理解哈;
- MemberSignInRecordDO maxSignDay = signInRecordMapper.selectOne(new LambdaQueryWrapperX()
- .eq(MemberSignInRecordDO::getUserId, userId)
- .orderByDesc(MemberSignInRecordDO::getDay)
- .last("limit 1"));
- // 判断是否重复签到
- validSignDay(maxSignDay);
+ // 1. 获取当前用户最近的签到
+ MemberSignInRecordDO lastRecord = signInRecordMapper.selectLastRecordByUserIdDesc(userId);
+ // 1.1. 判断是否重复签到
+ validateSigned(lastRecord);
- // 1. 查询出当前签到的天数
- MemberSignInRecordDO sign = new MemberSignInRecordDO().setUserId(userId); // TODO @xiaqing:应该使用 record 变量,会更合适
- sign.setDay(1); // 设置签到初始化天数
- sign.setPoint(0); // 设置签到积分默认为 0
- sign.setExperience(0); // 设置签到经验默认为 0
- // 如果不为空则修改当前签到对应的天数
- // TODO @xiaqing:应该是要判断连续哈,就是昨天;
- if (maxSignDay != null) {
- sign.setDay(maxSignDay.getDay() + 1);
- }
- // 2. 获取签到对应的积分数
- // 获取所有的签到规则,按照天数排序,只获取启用的 TODO @xiaqing:不要使用 signInConfigMapper 直接查询,而是要通过 SigninConfigService;
- List configDOList = signInConfigMapper.selectList(new LambdaQueryWrapperX()
- .eq(MemberSignInConfigDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
- .orderByAsc(MemberSignInConfigDO::getDay));
- // 如果签到的天数大于最大启用的规则天数,直接给最大签到的积分数
- // TODO @xiaqing:超过最大配置的天数,应该直接重置到第一天哈;
- MemberSignInConfigDO lastConfig = configDOList.get(configDOList.size() - 1);
- if (sign.getDay() > lastConfig.getDay()) {
- sign.setPoint(lastConfig.getPoint());
- sign.setExperience(lastConfig.getExperience());
- } else {
- configDOList.forEach(el -> {
- // 循环匹配对应天数,设置对应积分数
- // TODO @xiaqing:使用 equals;另外,这种不应该去遍历比较,从可读性来说,应该 CollUtil.findOne()
- if (el.getDay() == sign.getDay()) {
- sign.setPoint(el.getPoint());
- sign.setExperience(el.getExperience());
- }
-
- });
- }
+ // 2. 获取当前用户最早的一次前端记录,用于计算今天是第几天签到
+ MemberSignInRecordDO firstRecord = signInRecordMapper.selectLastRecordByUserIdAsc(userId);
+ // 2.1. 获取所有的签到规则
+ List signInConfigs = signInConfigService.getSignInConfigList(CommonStatusEnum.ENABLE.getStatus());
+ signInConfigs.sort(Comparator.comparing(MemberSignInConfigDO::getDay));
+ // 2.2. 组合数据
+ MemberSignInRecordDO record = MemberSignInRecordConvert.INSTANCE.convert(userId, firstRecord, signInConfigs);
// 3. 插入签到记录
- signInRecordMapper.insert(sign);
+ signInRecordMapper.insert(record);
// 4. 增加积分
- if (!ObjectUtils.equalsAny(sign.getPoint(), null, 0)) {
- pointRecordService.createPointRecord(userId, sign.getPoint(), MemberPointBizTypeEnum.SIGN, String.valueOf(sign.getId()));
+ if (!ObjectUtils.equalsAny(record.getPoint(), null, 0)) {
+ pointRecordService.createPointRecord(userId, record.getPoint(), MemberPointBizTypeEnum.SIGN, String.valueOf(record.getId()));
}
// 5. 增加经验
- if (!ObjectUtils.equalsAny(sign.getPoint(), null, 0)) {
- memberLevelService.addExperience(userId, sign.getExperience(), MemberExperienceBizTypeEnum.SIGN_IN, String.valueOf(sign.getId()));
+ if (!ObjectUtils.equalsAny(record.getExperience(), null, 0)) {
+ memberLevelService.addExperience(userId, record.getExperience(), MemberExperienceBizTypeEnum.SIGN_IN, String.valueOf(record.getId()));
}
- return sign;
+ return record;
}
- // TODO @xiaqing:校验使用 validate 动词哈;可以改成 validateSigned
- private void validSignDay(MemberSignInRecordDO signInRecordDO) {
- // TODO @xiaqing:代码格式:if () {} 要有括号哈
- if (signInRecordDO == null)
+ private void validateSigned(MemberSignInRecordDO signInRecordDO) {
+ if (signInRecordDO == null) {
return;
- // TODO @xiaqing:可以直接使用 DateUtils.isToday()
- LocalDate today = LocalDate.now();
- if (today.equals(signInRecordDO.getCreateTime().toLocalDate())) {
- throw exception(ErrorCodeConstants.SIGN_IN_RECORD_TODAY_EXISTS);
+ }
+ if (DateUtils.isToday(signInRecordDO.getCreateTime())) {
+ throw exception(SIGN_IN_RECORD_TODAY_EXISTS);
}
}