Compare commits

...

3 Commits

Author SHA1 Message Date
6c1b724d93 Merge branch 'master' of http://101.43.112.107:3000/root/allLikeMall into cxw 2024-10-11 15:35:47 +08:00
7581ebfa77 秒杀活动首页显示正在进行活动修改 2024-10-11 14:23:23 +08:00
9ba1fe2fdd Merge pull request '秒杀和拼团列表过滤已过期活动' (#39) from cxw into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #39
2024-10-09 18:26:33 +08:00
6 changed files with 68 additions and 13 deletions

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.product.controller.app.spu.vo; package cn.iocoder.yudao.module.product.controller.app.spu.vo;
import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
@ -33,6 +34,8 @@ public class AppProductSpuDetailRespVO {
@Schema(description = "商品轮播图", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "商品轮播图", requiredMode = Schema.RequiredMode.REQUIRED)
private List<String> sliderPicUrls; private List<String> sliderPicUrls;
@Schema(description = "商品品牌编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long brandId;
// ========== 营销相关字段 ========= // ========== 营销相关字段 =========
// ========== SKU 相关字段 ========= // ========== SKU 相关字段 =========

View File

@ -149,4 +149,6 @@ public interface ErrorCodeConstants {
ErrorCode POINT_ACTIVITY_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS = new ErrorCode(1_013_007_007, "积分商品兑换失败,原因:商品不存在"); ErrorCode POINT_ACTIVITY_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS = new ErrorCode(1_013_007_007, "积分商品兑换失败,原因:商品不存在");
ErrorCode POINT_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1_013_007_008, "积分商品兑换失败,原因:积分商品库存不足"); ErrorCode POINT_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1_013_007_008, "积分商品兑换失败,原因:积分商品库存不足");
ErrorCode TIME_FORMAT_ERROR = new ErrorCode(1_019_007_008, "秒杀时间段格式化错误");
} }

View File

@ -53,7 +53,7 @@ public class AppActivityController {
private RewardActivityService rewardActivityService; private RewardActivityService rewardActivityService;
@GetMapping("/list-by-spu-id") @GetMapping("/list-by-spu-id")
@Operation(summary = "获得单个商品,近期参与的每个活动") @Operation(summary = "获得单个商品,正在参与的所有活动")
@Parameter(name = "spuId", description = "商品编号", required = true) @Parameter(name = "spuId", description = "商品编号", required = true)
public CommonResult<List<AppActivityRespVO>> getActivityListBySpuId(@RequestParam("spuId") Long spuId) { public CommonResult<List<AppActivityRespVO>> getActivityListBySpuId(@RequestParam("spuId") Long spuId) {
// 每种活动只返回一个 // 每种活动只返回一个

View File

@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
@ -18,6 +19,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService; import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService; import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -31,19 +33,21 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration; import java.time.Duration;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache; import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.findFirst; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.findFirst;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.isBetween; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.isBetween;
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.TIME_FORMAT_ERROR;
@Tag(name = "用户 App - 秒杀活动") @Tag(name = "用户 App - 秒杀活动")
@RestController @RestController
@ -113,15 +117,37 @@ public class AppSeckillActivityController {
@GetMapping("/spuList") @GetMapping("/spuList")
@Parameter(name = "count", description = "需要展示的数量", example = "6") @Parameter(name = "count", description = "需要展示的数量", example = "6")
@Operation(summary = "获得秒杀活动分页") @Operation(summary = "获得现在进行的秒杀活动分页")
public CommonResult<List<ProductSpuRespDTO>> getSeckillActivitySupList(@RequestParam(name = "count", defaultValue = "6") Integer count) { public CommonResult<List<ProductSpuRespDTO>> getSeckillActivitySupList(@RequestParam(name = "count", defaultValue = "3") Integer count) {
AppSeckillActivityPageReqVO pageReqVO = new AppSeckillActivityPageReqVO(); AppSeckillActivityPageReqVO pageReqVO = new AppSeckillActivityPageReqVO();
if (count != null && count != 0){ Page<SeckillActivityDO> page = new Page<>(1, 3);;
pageReqVO.setPageNo(1); if (count != null && count != 0) {
pageReqVO.setPageSize(count); page = new Page<>(1, count);
} }
// 先找出当前时间对应的配置时间段id
List<Long> configIdList = new ArrayList<>();
try {
List<SeckillConfigDO> timeList = configService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus());
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
// 当前时间
Date currentTime = format.parse(format.format(new Date()));
// 遍历所有配置时间段找出符合时间段的id
for (SeckillConfigDO seckillConfigDO : timeList) {
if (currentTime.before(format.parse(seckillConfigDO.getEndTime())) && currentTime.after(format.parse(seckillConfigDO.getStartTime()))) {
configIdList.add(seckillConfigDO.getId());
}
}
} catch (ParseException e) {
throw exception(TIME_FORMAT_ERROR);
}
// 对配置时间段的id数组进行判断
if (configIdList.isEmpty()) {
return success(null);
}
// 获取满足当前正在进行的活动
PageResult<SeckillActivityDO> pageResult = activityService.getRunningActivityByConfigIdsCount(configIdList, page);
// 1. 查询满足当前阶段的活动 // 1. 查询满足当前阶段的活动
PageResult<SeckillActivityDO> pageResult = activityService.getSeckillActivityAppPageByConfigId(pageReqVO); // PageResult<SeckillActivityDO> pageResult = activityService.getSeckillActivityAppPageByConfigId(pageReqVO);
if (CollUtil.isEmpty(pageResult.getList())) { if (CollUtil.isEmpty(pageResult.getList())) {
return success(null); return success(null);
} }
@ -135,7 +161,7 @@ public class AppSeckillActivityController {
HashMap<Long, Long> hashMap = new HashMap<>(); HashMap<Long, Long> hashMap = new HashMap<>();
for (AppSeckillActivityRespVO respVO : result.getList()) { for (AppSeckillActivityRespVO respVO : result.getList()) {
arrayList.add(respVO.getSpuId()); arrayList.add(respVO.getSpuId());
hashMap.put(respVO.getSpuId(),respVO.getId()); hashMap.put(respVO.getSpuId(), respVO.getId());
} }
List<ProductSpuRespDTO> list = spuApi.getSpuList(arrayList); List<ProductSpuRespDTO> list = spuApi.getSpuList(arrayList);
for (ProductSpuRespDTO respDTO : list) { for (ProductSpuRespDTO respDTO : list) {

View File

@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.Se
import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO; import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import javax.validation.Valid; import javax.validation.Valid;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -139,4 +140,11 @@ public interface SeckillActivityService {
*/ */
List<SeckillActivityDO> getSeckillActivityBySpuIdsAndStatusAndDateTimeLt(Collection<Long> spuIds, Integer status, LocalDateTime dateTime); List<SeckillActivityDO> getSeckillActivityBySpuIdsAndStatusAndDateTimeLt(Collection<Long> spuIds, Integer status, LocalDateTime dateTime);
/**
* 获取当前正在进行的秒杀活动
* @param configIdList 符合配置时间段的id
* @param page 分页
* @return cn.iocoder.yudao.framework.common.pojo.PageResult<cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO>
*/
PageResult<SeckillActivityDO> getRunningActivityByConfigIdsCount(List<Long> configIdList, Page<SeckillActivityDO> page);
} }

View File

@ -7,6 +7,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
@ -23,6 +24,8 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillConfigDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper; import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper;
import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillProductMapper; import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillProductMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -85,7 +88,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
/** /**
* 校验秒杀商品参与的活动是否存在冲突 * 校验秒杀商品参与的活动是否存在冲突
* * <p>
* 1. 校验秒杀时段是否存在 * 1. 校验秒杀时段是否存在
* 2. 秒杀商品是否参加其它活动 * 2. 秒杀商品是否参加其它活动
* *
@ -336,4 +339,17 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
convertSet(spuIdAndActivityIdMaps, map -> MapUtil.getLong(map, "activityId")), dateTime); convertSet(spuIdAndActivityIdMaps, map -> MapUtil.getLong(map, "activityId")), dateTime);
} }
@Override
public PageResult<SeckillActivityDO> getRunningActivityByConfigIdsCount(List<Long> configIdList, Page<SeckillActivityDO> page) {
LambdaQueryWrapper<SeckillActivityDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SeckillActivityDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
.ge(SeckillActivityDO::getEndTime, LocalDateTime.now())
.in(SeckillActivityDO::getConfigIds, configIdList);
Page<SeckillActivityDO> seckillActivityDOPage = seckillActivityMapper.selectPage(page, wrapper);
PageResult<SeckillActivityDO> pageResult = new PageResult<>();
pageResult.setTotal(seckillActivityDOPage.getTotal());
pageResult.setList(seckillActivityDOPage.getRecords());
return pageResult;
}
} }