设置秒杀活动为自动开启
This commit is contained in:
parent
5c32fd9d7c
commit
16cc989cdf
@ -17,29 +17,29 @@ import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 买家端,限时抢购接口
|
||||
* 买家端,秒杀活动接口
|
||||
*
|
||||
* @author paulG
|
||||
* @date 2020/11/17 2:30 下午
|
||||
*/
|
||||
@Api(tags = "买家端,限时抢购接口")
|
||||
@Api(tags = "买家端,秒杀活动接口")
|
||||
@RestController
|
||||
@RequestMapping("/buyer/promotion/seckill")
|
||||
public class SeckillBuyerController {
|
||||
|
||||
/**
|
||||
* 限时抢购
|
||||
* 秒杀活动
|
||||
*/
|
||||
@Autowired
|
||||
private SeckillApplyService seckillApplyService;
|
||||
|
||||
@ApiOperation(value = "获取当天限时抢购信息")
|
||||
@ApiOperation(value = "获取当天秒杀活动信息")
|
||||
@GetMapping
|
||||
public ResultMessage<List<SeckillTimelineVO>> getSeckillTime() {
|
||||
return ResultUtil.data(seckillApplyService.getSeckillTimeline());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取某个时刻的限时抢购商品信息")
|
||||
@ApiOperation(value = "获取某个时刻的秒杀活动商品信息")
|
||||
@GetMapping("/{timeline}")
|
||||
public ResultMessage<List<SeckillGoodsVO>> getSeckillGoods(@PathVariable Integer timeline) {
|
||||
return ResultUtil.data(seckillApplyService.getSeckillGoods(timeline));
|
||||
|
@ -3,15 +3,21 @@ package cn.lili.timetask.handler.impl.promotion;
|
||||
import cn.lili.modules.order.cart.entity.vo.FullDiscountVO;
|
||||
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
|
||||
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
|
||||
import cn.lili.modules.promotion.entity.dos.Seckill;
|
||||
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
|
||||
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
|
||||
import cn.lili.modules.promotion.entity.vos.CouponVO;
|
||||
import cn.lili.modules.promotion.entity.vos.PintuanVO;
|
||||
import cn.lili.modules.promotion.service.*;
|
||||
import cn.lili.modules.search.service.EsGoodsIndexService;
|
||||
import cn.lili.modules.system.entity.dos.Setting;
|
||||
import cn.lili.modules.system.entity.dto.SeckillSetting;
|
||||
import cn.lili.modules.system.entity.enums.SettingEnum;
|
||||
import cn.lili.modules.system.service.SettingService;
|
||||
import cn.lili.timetask.handler.EveryDayExecute;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.google.gson.Gson;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
@ -53,6 +59,12 @@ public class PromotionEverydayExecute implements EveryDayExecute {
|
||||
//促销商品
|
||||
@Autowired
|
||||
private PromotionGoodsService promotionGoodsService;
|
||||
//设置
|
||||
@Autowired
|
||||
private SettingService settingService;
|
||||
@Autowired
|
||||
private SeckillService seckillService;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@ -68,7 +80,35 @@ public class PromotionEverydayExecute implements EveryDayExecute {
|
||||
query.addCriteria(Criteria.where("endTime").lt(new Date()));
|
||||
|
||||
List<String> promotionIds = new ArrayList<>();
|
||||
//关闭满减活动
|
||||
endFullDiscount(promotionIds,query);
|
||||
//关闭拼团活动
|
||||
endPintuan(promotionIds,query);
|
||||
//关闭优惠券
|
||||
endCoupon(promotionIds,query);
|
||||
//每日新增秒杀活动
|
||||
addSeckill();
|
||||
promotionGoodsService.update(this.getUpdatePromotionGoodsWrapper(promotionIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加秒杀活动
|
||||
* 从系统设置中获取秒杀活动的配置
|
||||
* 添加30天后的秒杀活动
|
||||
*/
|
||||
private void addSeckill(){
|
||||
Setting setting = settingService.get(SettingEnum.SECKILL_SETTING.name());
|
||||
SeckillSetting seckillSetting=new Gson().fromJson(setting.getSettingValue(), SeckillSetting.class);
|
||||
Seckill seckill=new Seckill(seckillSetting.getHours(),seckillSetting.getSeckillRule());
|
||||
seckillService.saveSeckill(seckill);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改满额活动下的商品
|
||||
* @param promotionIds 促销活动ID
|
||||
* @param query 查询Wrapper
|
||||
*/
|
||||
private void endFullDiscount(List<String> promotionIds,Query query){
|
||||
//关闭满减活动
|
||||
List<FullDiscountVO> fullDiscountVOS = mongoTemplate.find(query, FullDiscountVO.class);
|
||||
if (!fullDiscountVOS.isEmpty()) {
|
||||
@ -87,7 +127,14 @@ public class PromotionEverydayExecute implements EveryDayExecute {
|
||||
fullDiscountService.update(this.getUpdatePromotionWrapper(ids));
|
||||
promotionIds.addAll(ids);
|
||||
}
|
||||
//关闭拼团活动
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改拼团活动下的商品
|
||||
* @param promotionIds 促销活动ID
|
||||
* @param query 查询Wrapper
|
||||
*/
|
||||
private void endPintuan(List<String> promotionIds,Query query){
|
||||
List<PintuanVO> pintuanVOS = mongoTemplate.find(query, PintuanVO.class);
|
||||
if (!pintuanVOS.isEmpty()) {
|
||||
//准备修改活动的id
|
||||
@ -106,8 +153,14 @@ public class PromotionEverydayExecute implements EveryDayExecute {
|
||||
pintuanService.update(this.getUpdatePromotionWrapper(ids));
|
||||
promotionIds.addAll(ids);
|
||||
}
|
||||
}
|
||||
|
||||
//关闭优惠券活动
|
||||
/**
|
||||
* 修改优惠券下的商品
|
||||
* @param promotionIds 促销活动ID
|
||||
* @param query 查询Wrapper
|
||||
*/
|
||||
private void endCoupon(List<String> promotionIds,Query query){
|
||||
List<CouponVO> couponVOS = mongoTemplate.find(query, CouponVO.class);
|
||||
if (!couponVOS.isEmpty()) {
|
||||
List<String> ids = new ArrayList<>();
|
||||
@ -123,19 +176,19 @@ public class PromotionEverydayExecute implements EveryDayExecute {
|
||||
ids.add(vo.getId());
|
||||
}
|
||||
couponService.update(this.getUpdatePromotionWrapper(ids));
|
||||
LambdaUpdateWrapper<MemberCoupon> memberCouponLambdaUpdateWrapper = new LambdaUpdateWrapper<MemberCoupon>().in(MemberCoupon::getCouponId, ids).set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
|
||||
LambdaUpdateWrapper<MemberCoupon> memberCouponLambdaUpdateWrapper = new LambdaUpdateWrapper<MemberCoupon>()
|
||||
.in(MemberCoupon::getCouponId, ids)
|
||||
.eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name())
|
||||
.set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
|
||||
memberCouponService.update(memberCouponLambdaUpdateWrapper);
|
||||
promotionIds.addAll(ids);
|
||||
}
|
||||
|
||||
promotionGoodsService.update(this.getUpdatePromotionGoodsWrapper(promotionIds));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取促销修改查询条件 修改活动状态
|
||||
* @param ids
|
||||
* @return
|
||||
* @param ids 促销活动ID
|
||||
* @return 促销活动商品查询Wrapper
|
||||
*/
|
||||
private UpdateWrapper getUpdatePromotionWrapper(List<String> ids) {
|
||||
UpdateWrapper updateWrapper = new UpdateWrapper<>();
|
||||
@ -145,8 +198,8 @@ public class PromotionEverydayExecute implements EveryDayExecute {
|
||||
}
|
||||
/**
|
||||
* 获取商品的促销修改查询条件 修改商品状态
|
||||
* @param ids
|
||||
* @return
|
||||
* @param ids 促销活动ID
|
||||
* @return 促销活动商品修改Wrapper
|
||||
*/
|
||||
private UpdateWrapper getUpdatePromotionGoodsWrapper(List<String> ids) {
|
||||
UpdateWrapper updateWrapper = new UpdateWrapper<>();
|
||||
|
@ -219,7 +219,7 @@ public enum CachePrefix {
|
||||
STORE_ID_FULL_DISCOUNT,
|
||||
|
||||
/**
|
||||
* 限时抢购活动缓存key前缀
|
||||
* 秒杀活动活动缓存key前缀
|
||||
*/
|
||||
STORE_ID_SECKILL,
|
||||
|
||||
|
@ -15,7 +15,7 @@ public enum OrderOutTypeEnum {
|
||||
* 出库类型枚举
|
||||
*/
|
||||
GOODS("商品"),
|
||||
SECKILL_GOODS("限时抢购商品");
|
||||
SECKILL_GOODS("秒杀活动商品");
|
||||
|
||||
|
||||
private final String description;
|
||||
|
@ -1,11 +1,16 @@
|
||||
package cn.lili.modules.promotion.entity.dos;
|
||||
|
||||
import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.lili.modules.promotion.entity.dto.BasePromotion;
|
||||
import cn.lili.modules.promotion.entity.enums.PromotionStatusEnum;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
@ -13,7 +18,7 @@ import javax.validation.constraints.NotNull;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 限时抢购实体类
|
||||
* 秒杀活动实体类
|
||||
*
|
||||
* @author Chopper
|
||||
* @date 2020-03-19 10:44 上午
|
||||
@ -22,7 +27,8 @@ import java.util.Date;
|
||||
@Entity
|
||||
@Table(name = "li_seckill")
|
||||
@TableName("li_seckill")
|
||||
@ApiModel(value = "限时抢购活动")
|
||||
@ApiModel(value = "秒杀活动活动")
|
||||
@NoArgsConstructor
|
||||
public class Seckill extends BasePromotion {
|
||||
|
||||
private static final long serialVersionUID = -9116425737163730836L;
|
||||
@ -44,4 +50,30 @@ public class Seckill extends BasePromotion {
|
||||
*/
|
||||
@ApiModelProperty(value = "商家id集合以逗号分隔")
|
||||
private String storeIds;
|
||||
|
||||
@ApiModelProperty(value = "商品数量")
|
||||
private Integer goodsNum;
|
||||
|
||||
@ApiModelProperty(value = "店铺数量")
|
||||
private Integer storeNum;
|
||||
|
||||
public Seckill(String hours,String seckillRule){
|
||||
//默认创建30天后的秒杀活动
|
||||
DateTime dateTime= DateUtil.beginOfDay(DateUtil.offset(new DateTime(), DateField.DAY_OF_YEAR, 30));
|
||||
this.applyEndTime=dateTime;
|
||||
this.hours=hours;
|
||||
this.seckillRule=seckillRule;
|
||||
this.goodsNum=0;
|
||||
this.storeNum=0;
|
||||
|
||||
//BasePromotion
|
||||
setStoreName("platform");
|
||||
setStoreId("platform");
|
||||
setPromotionName(DateUtil.formatDate(dateTime)+" 秒杀活动");
|
||||
setStartTime(dateTime);
|
||||
setEndTime(DateUtil.endOfDay(dateTime));
|
||||
setPromotionStatus(PromotionStatusEnum.NEW.name());
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 限时抢购申请实体类
|
||||
* 秒杀活动申请实体类
|
||||
*
|
||||
* @author Chopper
|
||||
* @date 2020-03-19 10:44 上午
|
||||
@ -22,7 +22,7 @@ import javax.validation.constraints.NotNull;
|
||||
@Entity
|
||||
@Table(name = "li_seckill_apply")
|
||||
@TableName("li_seckill_apply")
|
||||
@ApiModel(value = "限时抢购申请")
|
||||
@ApiModel(value = "秒杀活动申请")
|
||||
public class SeckillApply extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 5440164641970820989L;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cn.lili.modules.promotion.entity.enums;
|
||||
|
||||
/**
|
||||
* 限时抢购状态枚举
|
||||
* 秒杀活动状态枚举
|
||||
*
|
||||
* @author paulG
|
||||
* @date 2020/8/26
|
||||
@ -9,7 +9,7 @@ package cn.lili.modules.promotion.entity.enums;
|
||||
public enum SeckillApplyStatusEnum {
|
||||
|
||||
/**
|
||||
* 当前店铺对当前限时抢购的申请状态
|
||||
* 当前店铺对当前秒杀活动的申请状态
|
||||
*/
|
||||
APPLIED("已经申请过"), NOT_APPLY("未报名"), EXPIRE("过期的");
|
||||
|
||||
|
@ -5,7 +5,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 限时抢购申请视图对象
|
||||
* 秒杀活动申请视图对象
|
||||
*
|
||||
* @author paulG
|
||||
* @date 2020/8/21
|
||||
|
@ -6,7 +6,7 @@ import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 限时抢购商品视图对象
|
||||
* 秒杀活动商品视图对象
|
||||
*
|
||||
* @author paulG
|
||||
* @date 2020/8/26
|
||||
|
@ -17,7 +17,7 @@ import java.util.Date;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 限时抢购查询通用类
|
||||
* 秒杀活动查询通用类
|
||||
*
|
||||
* @author paulG
|
||||
* @date 2020/8/21
|
||||
@ -27,7 +27,7 @@ public class SeckillSearchParams implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4052716630253333681L;
|
||||
|
||||
@ApiModelProperty(value = "限时抢购活动编号")
|
||||
@ApiModelProperty(value = "秒杀活动活动编号")
|
||||
private String seckillId;
|
||||
|
||||
@ApiModelProperty(value = "活动名称")
|
||||
|
@ -7,7 +7,7 @@ import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 限时抢购时刻视图对象
|
||||
* 秒杀活动时刻视图对象
|
||||
*
|
||||
* @author paulG
|
||||
* @date 2020/8/27
|
||||
@ -26,7 +26,7 @@ public class SeckillTimelineVO implements Serializable {
|
||||
@ApiModelProperty(value = "距离本组活动开始的时间,秒为单位。如果活动的开始时间是10点,服务器时间为8点,距离开始还有多少时间")
|
||||
private Long distanceStartTime;
|
||||
|
||||
@ApiModelProperty(value = "本组活动内的限时抢购商品列表")
|
||||
@ApiModelProperty(value = "本组活动内的秒杀活动商品列表")
|
||||
private List<SeckillGoodsVO> seckillGoodsList;
|
||||
|
||||
}
|
||||
|
@ -1,19 +1,14 @@
|
||||
package cn.lili.modules.promotion.entity.vos;
|
||||
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.utils.DateUtil;
|
||||
import cn.lili.modules.promotion.entity.dos.Seckill;
|
||||
import cn.lili.modules.promotion.entity.dos.SeckillApply;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 限时抢购视图对象
|
||||
* 秒杀活动视图对象
|
||||
*
|
||||
* @author paulG
|
||||
* @date 2020/8/20
|
||||
@ -30,60 +25,8 @@ public class SeckillVO extends Seckill {
|
||||
private String seckillApplyStatus;
|
||||
|
||||
/**
|
||||
* 当前限时抢购下所有的秒杀申请信息
|
||||
* 当前秒杀活动下所有的秒杀申请信息
|
||||
*/
|
||||
private List<SeckillApply> seckillApplyList;
|
||||
|
||||
/**
|
||||
* 检查当前时间
|
||||
*/
|
||||
public void checkTime() {
|
||||
String[] timeRange = this.getHours().split(",");
|
||||
int[] hoursSored = Arrays.stream(timeRange).mapToInt(Integer::parseInt).toArray();
|
||||
Arrays.sort(hoursSored);
|
||||
int lastTime = 0;
|
||||
for (int s : hoursSored) {
|
||||
if (lastTime == s) {
|
||||
throw new ServiceException("抢购区间的值不能重复");
|
||||
} else {
|
||||
lastTime = s;
|
||||
}
|
||||
|
||||
if (s < 0 || s > 23) {
|
||||
throw new ServiceException("抢购区间必须在0点到23点的整点时刻");
|
||||
}
|
||||
}
|
||||
|
||||
// 活动开始时间
|
||||
long startTime = this.getStartTime().getTime() / 1000;
|
||||
// 报名截止时间
|
||||
long applyEndTime = this.getApplyEndTime().getTime() / 1000;
|
||||
|
||||
int timeHour = hoursSored[0];
|
||||
int endTimeHour = hoursSored[hoursSored.length - 1];
|
||||
//获取活动开始当天0点的时间
|
||||
String startDate = DateUtil.toString(startTime, DateUtil.STANDARD_DATE_FORMAT) + " " + (timeHour > 10 ? timeHour : "0" + timeHour) + ":00:00";
|
||||
long startDayTime = cn.hutool.core.date.DateUtil.parse(startDate, DateUtil.STANDARD_FORMAT).getTime() / 1000;
|
||||
// 结束时间
|
||||
String endDate = DateUtil.toString(startTime, DateUtil.STANDARD_DATE_FORMAT) + " " + (endTimeHour > 10 ? endTimeHour : "0" + endTimeHour) + ":59:00";
|
||||
long endDayTime = cn.hutool.core.date.DateUtil.parse(endDate, DateUtil.STANDARD_FORMAT).getTime() / 1000;
|
||||
//活动时间小于当天开始时间
|
||||
if (startDayTime < DateUtil.startOfTodDay()) {
|
||||
throw new ServiceException("活动时间不能小于当前时间");
|
||||
}
|
||||
|
||||
//报名截止时间小于当前时间
|
||||
if (applyEndTime < DateUtil.getDateline()) {
|
||||
throw new ServiceException("报名截止时间不能小于当前时间");
|
||||
}
|
||||
|
||||
//报名截止时间大于活动开始当天的起始时间
|
||||
if (applyEndTime >= startDayTime) {
|
||||
throw new ServiceException("报名截止时间不能大于等于活动开始时间");
|
||||
}
|
||||
|
||||
this.setStartTime(new Date(startDayTime * 1000));
|
||||
this.setEndTime(new Date(endDayTime * 1000));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import cn.lili.modules.promotion.entity.dos.SeckillApply;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* 限时抢购申请数据处理层
|
||||
* 秒杀活动申请数据处理层
|
||||
*
|
||||
* @author Chopper
|
||||
* @date 2020/8/21
|
||||
|
@ -4,7 +4,7 @@ import cn.lili.modules.promotion.entity.dos.Seckill;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* 限时抢购数据处理层
|
||||
* 秒杀活动数据处理层
|
||||
*
|
||||
* @author Chopper
|
||||
* @date 2020/8/21
|
||||
|
@ -10,7 +10,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 秒杀申请业务层
|
||||
@ -22,82 +21,46 @@ public interface SeckillApplyService extends IService<SeckillApply> {
|
||||
|
||||
|
||||
/**
|
||||
* 获取当天限时抢购信息列表(时刻及对应时刻下的商品)
|
||||
* 获取当天秒杀活动信息列表(时刻及对应时刻下的商品)
|
||||
*
|
||||
* @return 限时抢购信息列表
|
||||
* @return 秒杀活动信息列表
|
||||
*/
|
||||
List<SeckillTimelineVO> getSeckillTimeline();
|
||||
|
||||
|
||||
/**
|
||||
* 获取当天某个时刻的限时抢购商品列表
|
||||
* 获取当天某个时刻的秒杀活动商品列表
|
||||
*
|
||||
* @param timeline 指定时刻
|
||||
* @return 限时抢购商品列表
|
||||
* @return 秒杀活动商品列表
|
||||
*/
|
||||
List<SeckillGoodsVO> getSeckillGoods(Integer timeline);
|
||||
|
||||
/**
|
||||
* 审核一批申请
|
||||
*
|
||||
* @param ids 限时抢购申请编号
|
||||
* @param seckillId 限时抢购编号
|
||||
* @param applyStatus 审批状态
|
||||
* @param failReason 驳回原因
|
||||
*/
|
||||
void auditBatchApply(String[] ids, String seckillId, String applyStatus, String failReason);
|
||||
|
||||
/**
|
||||
* 分页查询限时请购申请列表
|
||||
*
|
||||
* @param queryParam 限时抢购申请查询参数
|
||||
* @param pageVo 分页参数
|
||||
* @return 限时请购申请列表
|
||||
*/
|
||||
IPage<SeckillApply> getSeckillApplyFromMysql(SeckillSearchParams queryParam, PageVO pageVo);
|
||||
|
||||
/**
|
||||
* 从mongo中分页查询限时请购申请列表
|
||||
*
|
||||
* @param queryParam 限时抢购申请查询参数
|
||||
* @param queryParam 秒杀活动申请查询参数
|
||||
* @param pageVo 分页参数
|
||||
* @return 限时请购申请列表
|
||||
*/
|
||||
IPage<SeckillApply> getSeckillApplyFromMongo(SeckillSearchParams queryParam, PageVO pageVo);
|
||||
|
||||
/**
|
||||
* 添加限时抢购申请
|
||||
* 添加秒杀活动申请
|
||||
* 检测是否商品是否同时参加多个活动
|
||||
* 将秒杀商品信息存入秒杀活动中,更新mogo信息
|
||||
* 保存秒杀活动商品,促销商品信息
|
||||
*
|
||||
* @param seckillId 限时抢购编号
|
||||
* @param seckillId 秒杀活动编号
|
||||
* @param storeId 商家id
|
||||
* @param seckillApplyList 限时抢购申请列表
|
||||
* @param seckillApplyList 秒杀活动申请列表
|
||||
*/
|
||||
void addSeckillApply(String seckillId, String storeId, List<SeckillApplyVO> seckillApplyList);
|
||||
|
||||
/**
|
||||
* 批量删除限时抢购申请
|
||||
* 批量删除秒杀活动申请
|
||||
*
|
||||
* @param seckillId 限时抢购活动id
|
||||
* @param ids 限时抢购申请id集合
|
||||
* @param seckillId 秒杀活动活动id
|
||||
* @param ids 秒杀活动申请id集合
|
||||
*/
|
||||
void removeSeckillApplyByIds(String seckillId, List<String> ids);
|
||||
|
||||
/**
|
||||
* 更新限时抢购库存数量
|
||||
*
|
||||
* @param id 限时抢购申请(限时抢购商品)id
|
||||
* @param num 数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateSeckillStock(String id, Integer num);
|
||||
|
||||
|
||||
/**
|
||||
* 更新限时抢购库存数量
|
||||
*
|
||||
* @param map key 为 限时抢购申请(限时抢购商品)id, value 为数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateSeckillStock(Map<String, Integer> map);
|
||||
|
||||
}
|
@ -17,78 +17,79 @@ public interface SeckillService extends IService<Seckill> {
|
||||
|
||||
|
||||
/**
|
||||
* 从mysql中根据条件获取限时抢购分页列表
|
||||
* 从mysql中根据条件获取秒杀活动分页列表
|
||||
*
|
||||
* @param queryParam 查询参数
|
||||
* @param pageVo 分页参数
|
||||
* @return 限时抢购分页列表
|
||||
* @return 秒杀活动分页列表
|
||||
*/
|
||||
IPage<Seckill> getSeckillByPageFromMysql(SeckillSearchParams queryParam, PageVO pageVo);
|
||||
|
||||
/**
|
||||
* 从mongo中根据条件获取限时抢购分页列表
|
||||
* 从mongo中根据条件获取秒杀活动分页列表
|
||||
*
|
||||
* @param queryParam 查询参数
|
||||
* @param pageVo 分页参数
|
||||
* @return 限时抢购分页列表
|
||||
* @return 秒杀活动分页列表
|
||||
*/
|
||||
IPage<SeckillVO> getSeckillByPageFromMongo(SeckillSearchParams queryParam, PageVO pageVo);
|
||||
|
||||
/**
|
||||
* 从mongo中获取限时抢购信息
|
||||
* 从mongo中获取秒杀活动信息
|
||||
*
|
||||
* @param id 限时抢购id
|
||||
* @return 限时抢购信息
|
||||
* @param id 秒杀活动id
|
||||
* @return 秒杀活动信息
|
||||
*/
|
||||
SeckillVO getSeckillByIdFromMongo(String id);
|
||||
|
||||
/**
|
||||
* 保存限时抢购
|
||||
* 保存秒杀活动
|
||||
*
|
||||
* @param seckill 限时抢购信息
|
||||
* @param seckill 秒杀活动
|
||||
* @return 是否保存成功
|
||||
*/
|
||||
boolean saveSeckill(SeckillVO seckill);
|
||||
boolean saveSeckill(Seckill seckill);
|
||||
|
||||
/**
|
||||
* 商家报名限时抢购活动
|
||||
* 商家报名秒杀活动活动
|
||||
*
|
||||
* @param storeId 商家编号
|
||||
* @param seckillId 限时抢购编号
|
||||
* @param seckillId 秒杀活动编号
|
||||
*/
|
||||
void storeApply(String storeId, String seckillId);
|
||||
|
||||
/**
|
||||
* 修改限时抢购
|
||||
* 修改秒杀活动
|
||||
*
|
||||
* @param seckillVO 限时抢购信息
|
||||
* @param seckillVO 秒杀活动信息
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
boolean modifySeckill(SeckillVO seckillVO);
|
||||
|
||||
/**
|
||||
* 删除限时抢购
|
||||
* 删除秒杀活动
|
||||
*
|
||||
* @param id 限时抢购编号
|
||||
* @param id 秒杀活动编号
|
||||
*/
|
||||
void deleteSeckill(String id);
|
||||
|
||||
/**
|
||||
* 开启一个限时抢购
|
||||
* 开启一个秒杀活动
|
||||
*
|
||||
* @param id 限时抢购编号
|
||||
* @param id 秒杀活动编号
|
||||
*/
|
||||
void openSeckill(String id);
|
||||
|
||||
/**
|
||||
* 关闭一个限时抢购
|
||||
* 关闭一个秒杀活动
|
||||
*
|
||||
* @param id 限时抢购编号
|
||||
* @param id 秒杀活动编号
|
||||
*/
|
||||
void closeSeckill(String id);
|
||||
|
||||
/**
|
||||
* 获取当前可参与的活动数量
|
||||
*
|
||||
* @return 可参与活动数量
|
||||
*/
|
||||
Integer getApplyNum();
|
||||
|
@ -505,11 +505,11 @@ public class PintuanServiceImpl extends ServiceImpl<PintuanMapper, Pintuan> impl
|
||||
}
|
||||
// 查询是否在同一时间段参与了拼团活动
|
||||
Integer count = promotionGoodsService.findInnerOverlapPromotionGoods(PromotionTypeEnum.SECKILL.name(), promotionGood.getSkuId(), pintuan.getStartTime(), pintuan.getEndTime());
|
||||
// 查询是否在同一时间段参与了限时抢购活动
|
||||
// 查询是否在同一时间段参与了秒杀活动活动
|
||||
count += promotionGoodsService.findInnerOverlapPromotionGoods(PromotionTypeEnum.PINTUAN.name(), promotionGood.getSkuId(), pintuan.getStartTime(), pintuan.getEndTime());
|
||||
if (count > 0) {
|
||||
log.error("商品[" + promotionGood.getGoodsName() + "]已经在重叠的时间段参加了限时抢购或拼团活动,不能参加拼团活动");
|
||||
throw new ServiceException("商品[" + promotionGood.getGoodsName() + "]已经在重叠的时间段参加了限时抢购或拼团活动,不能参加拼团活动");
|
||||
log.error("商品[" + promotionGood.getGoodsName() + "]已经在重叠的时间段参加了秒杀活动或拼团活动,不能参加拼团活动");
|
||||
throw new ServiceException("商品[" + promotionGood.getGoodsName() + "]已经在重叠的时间段参加了秒杀活动或拼团活动,不能参加拼团活动");
|
||||
}
|
||||
}
|
||||
LambdaQueryWrapper<PromotionGoods> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
@ -64,7 +64,7 @@ public class PromotionGoodsServiceImpl extends ServiceImpl<PromotionGoodsMapper,
|
||||
//Redis
|
||||
@Autowired
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
//限时抢购申请
|
||||
//秒杀活动申请
|
||||
@Autowired
|
||||
private SeckillApplyService seckillApplyService;
|
||||
//规格商品
|
||||
@ -306,7 +306,7 @@ public class PromotionGoodsServiceImpl extends ServiceImpl<PromotionGoodsMapper,
|
||||
queryWrapper.eq(SeckillApply::getSeckillId, promotionId).eq(SeckillApply::getSkuId, skuId);
|
||||
SeckillApply seckillApply = seckillApplyService.getOne(queryWrapper);
|
||||
if (seckillApply == null) {
|
||||
throw new ServiceException("当前限时抢购商品不存在!");
|
||||
throw new ServiceException("当前秒杀活动商品不存在!");
|
||||
}
|
||||
LambdaUpdateWrapper<SeckillApply> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(SeckillApply::getSeckillId, promotionId).eq(SeckillApply::getSkuId, skuId);
|
||||
|
@ -33,7 +33,7 @@ public class PromotionPriceServiceImpl implements PromotionPriceService {
|
||||
//ES商品
|
||||
@Autowired
|
||||
private EsGoodsSearchService goodsSearchService;
|
||||
//限时抢购申请
|
||||
//秒杀活动申请
|
||||
@Autowired
|
||||
private SeckillApplyService seckillApplyService;
|
||||
//促销商品
|
||||
@ -180,7 +180,7 @@ public class PromotionPriceServiceImpl implements PromotionPriceService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 促销计算(限时抢购,拼团)
|
||||
* 促销计算(秒杀活动,拼团)
|
||||
*
|
||||
* @param promotionMap 当前商品所有参加的促销活动
|
||||
* @param goodsSkuPromotionPrice 商品SKU促销计算信息
|
||||
@ -189,11 +189,11 @@ public class PromotionPriceServiceImpl implements PromotionPriceService {
|
||||
*/
|
||||
private void calculationPromotionMap(Map<String, Object> promotionMap, GoodsSkuPromotionPriceDTO goodsSkuPromotionPrice, EsGoodsIndex esGoodsIndex, String pintuanId) {
|
||||
if (promotionMap != null && !promotionMap.isEmpty()) {
|
||||
// 检查当前商品是否存在限时抢购活动
|
||||
// 检查当前商品是否存在秒杀活动活动
|
||||
Optional<String> existSeckill = promotionMap.keySet().parallelStream().filter(i -> i.contains(PromotionTypeEnum.SECKILL.name())).findFirst();
|
||||
if (existSeckill.isPresent()) {
|
||||
Seckill seckill = (Seckill) promotionMap.get(existSeckill.get());
|
||||
// 计算限时抢购促销
|
||||
// 计算秒杀活动促销
|
||||
this.calculationSeckill(seckill, goodsSkuPromotionPrice);
|
||||
seckill.setPromotionName(PromotionTypeEnum.SECKILL.name());
|
||||
goodsSkuPromotionPrice.getJoinPromotion().add(seckill);
|
||||
@ -338,9 +338,9 @@ public class PromotionPriceServiceImpl implements PromotionPriceService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算限时抢购
|
||||
* 计算秒杀活动
|
||||
*
|
||||
* @param seckill 限时抢购信息
|
||||
* @param seckill 秒杀活动信息
|
||||
* @param promotionPrice 商品SKU的计算促销信息
|
||||
*/
|
||||
private void calculationSeckill(Seckill seckill, GoodsSkuPromotionPriceDTO promotionPrice) {
|
||||
@ -358,7 +358,7 @@ public class PromotionPriceServiceImpl implements PromotionPriceService {
|
||||
promotionPrice.setDiscountPrice(discountPrice);
|
||||
promotionPrice.setFinalePrice(seckillApply.getPrice());
|
||||
} else {
|
||||
log.error("购买数量超出限时抢购剩余数量");
|
||||
log.error("购买数量超出秒杀活动剩余数量");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ public class PromotionServiceImpl implements PromotionService {
|
||||
queryWrapper.eq("promotion_status", PromotionStatusEnum.START.name());
|
||||
queryWrapper.gt("start_time", new Date());
|
||||
queryWrapper.lt("end_time", new Date());
|
||||
// 获取当前进行的限时抢购活动
|
||||
// 获取当前进行的秒杀活动活动
|
||||
List<Seckill> seckillList = seckillService.list(queryWrapper);
|
||||
if (seckillList != null && !seckillList.isEmpty()) {
|
||||
for (Seckill seckill : seckillList) {
|
||||
@ -375,7 +375,7 @@ public class PromotionServiceImpl implements PromotionService {
|
||||
parseEndTime = cn.hutool.core.date.DateUtil.parse((format + " " + nextHour + ":59:59"), DateUtil.STANDARD_FORMAT);
|
||||
}
|
||||
seckill1.setStartTime(parseStartTime);
|
||||
// 当时商品的限时抢购活动结束时间为下个时间段的开始
|
||||
// 当时商品的秒杀活动活动结束时间为下个时间段的开始
|
||||
seckill1.setEndTime(parseEndTime);
|
||||
this.goodsIndexService.updateEsGoodsIndex(seckillApply.getSkuId(), seckill1, promotionTypeEnum.name() + "-" + seckillApply.getTimeLine(), seckillApply.getPrice());
|
||||
}
|
||||
|
@ -3,12 +3,10 @@ package cn.lili.modules.promotion.serviceimpl;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.lili.common.cache.Cache;
|
||||
import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.utils.DateUtil;
|
||||
import cn.lili.common.utils.PageUtil;
|
||||
import cn.lili.common.utils.StringUtils;
|
||||
import cn.lili.common.vo.PageVO;
|
||||
import cn.lili.modules.goods.entity.dos.GoodsSku;
|
||||
import cn.lili.modules.goods.service.GoodsSkuService;
|
||||
@ -27,12 +25,9 @@ import cn.lili.modules.promotion.tools.PromotionCacheKeys;
|
||||
import cn.lili.modules.promotion.tools.PromotionTools;
|
||||
import cn.lili.modules.search.service.EsGoodsIndexService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
@ -75,15 +70,15 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
|
||||
@Override
|
||||
public List<SeckillTimelineVO> getSeckillTimeline() {
|
||||
List<SeckillTimelineVO> timelineVoS = new ArrayList<>();
|
||||
// 限时抢购缓存key
|
||||
String seckillCacheKey = PromotionCacheKeys.getSeckillTimelineKey(DateUtil.toString(DateUtil.startOfTodDay(), DateUtil.STANDARD_DATE_NO_UNDERLINE_FORMAT));
|
||||
// 秒杀活动缓存key
|
||||
String seckillCacheKey = PromotionCacheKeys.getSeckillTimelineKey(DateUtil.format(DateUtil.beginOfDay(new DateTime()), "yyyyMMdd"));
|
||||
Map<Object, Object> cacheSeckill = cache.getHash(seckillCacheKey);
|
||||
if (cacheSeckill == null || cacheSeckill.isEmpty()) {
|
||||
// 如缓存中不存在,则单独获取
|
||||
try {
|
||||
timelineVoS = getSeckillTimelineToCache(seckillCacheKey);
|
||||
} catch (Exception e) {
|
||||
log.error("获取限时抢购信息发生错误!", e);
|
||||
log.error("获取秒杀活动信息发生错误!", e);
|
||||
}
|
||||
} else {
|
||||
// 如缓存中存在,则取缓存中转为展示的信息
|
||||
@ -98,8 +93,8 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
|
||||
@Override
|
||||
public List<SeckillGoodsVO> getSeckillGoods(Integer timeline) {
|
||||
List<SeckillGoodsVO> seckillGoodsVoS = new ArrayList<>();
|
||||
// 限时抢购缓存key
|
||||
String seckillCacheKey = PromotionCacheKeys.getSeckillTimelineKey(DateUtil.toString(DateUtil.startOfTodDay(), DateUtil.STANDARD_DATE_NO_UNDERLINE_FORMAT));
|
||||
// 秒杀活动缓存key
|
||||
String seckillCacheKey = PromotionCacheKeys.getSeckillTimelineKey(DateUtil.format(DateUtil.beginOfDay(new DateTime()), "yyyyMMdd"));
|
||||
Map<Object, Object> cacheSeckill = cache.getHash(seckillCacheKey);
|
||||
if (cacheSeckill == null || cacheSeckill.isEmpty()) {
|
||||
// 如缓存中不存在,则单独获取
|
||||
@ -116,57 +111,6 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
|
||||
return seckillGoodsVoS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void auditBatchApply(String[] ids, String seckillId, String applyStatus, String failReason) {
|
||||
if (ids == null || ids.length <= 0) {
|
||||
throw new ServiceException("请提供要审核的商品");
|
||||
}
|
||||
if (StringUtils.isEmpty(applyStatus) || PromotionApplyStatusEnum.valueOf(applyStatus).name().isEmpty()) {
|
||||
throw new ServiceException("提供的审批状态值不正确");
|
||||
}
|
||||
if (PromotionApplyStatusEnum.REFUSE.name().equals(applyStatus)) {
|
||||
boolean isEmpty = StringUtils.isEmpty(failReason);
|
||||
if (isEmpty) {
|
||||
throw new ServiceException("在驳回状态下驳回原因必填");
|
||||
}
|
||||
}
|
||||
|
||||
SeckillVO seckillVO = this.mongoTemplate.findById(seckillId, SeckillVO.class);
|
||||
if (seckillVO == null) {
|
||||
log.error("编号为【" + seckillId + "】限时抢购请不存在");
|
||||
throw new ServiceException();
|
||||
}
|
||||
List<SeckillApply> seckillApplyList = seckillVO.getSeckillApplyList();
|
||||
|
||||
for (String id : ids) {
|
||||
|
||||
Optional<SeckillApply> seckillApplyOptional = seckillApplyList.stream().filter(i -> i.getId().equals(id)).findFirst();
|
||||
SeckillApply seckillApply;
|
||||
if (seckillApplyOptional.isPresent()) {
|
||||
seckillApply = seckillApplyOptional.get();
|
||||
} else {
|
||||
log.error("编号为【" + id + "】限时抢购的申请不存在");
|
||||
throw new ServiceException();
|
||||
}
|
||||
|
||||
seckillApply.setPromotionApplyStatus(PromotionApplyStatusEnum.valueOf(applyStatus).name());
|
||||
seckillApply.setFailReason(failReason);
|
||||
this.updateById(seckillApply);
|
||||
if (PromotionApplyStatusEnum.PASS.name().equals(applyStatus)) {
|
||||
//检查缓存中是否存在相同商品参与的限时抢购活动
|
||||
checkCache(seckillVO.getStartTime().getTime());
|
||||
}
|
||||
}
|
||||
seckillVO.setSeckillApplyList(seckillApplyList);
|
||||
mongoTemplate.save(seckillVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<SeckillApply> getSeckillApplyFromMysql(SeckillSearchParams queryParam, PageVO pageVo) {
|
||||
QueryWrapper<SeckillApply> queryWrapper = queryParam.wrapper();
|
||||
return page(PageUtil.initPage(pageVo), queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<SeckillApply> getSeckillApplyFromMongo(SeckillSearchParams queryParam, PageVO pageVo) {
|
||||
IPage<SeckillApply> seckillApplyIPage = new Page<>();
|
||||
@ -201,133 +145,67 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
|
||||
public void addSeckillApply(String seckillId, String storeId, List<SeckillApplyVO> seckillApplyList) {
|
||||
SeckillVO seckill = mongoTemplate.findById(seckillId, SeckillVO.class);
|
||||
if (seckill == null) {
|
||||
throw new ServiceException("当前参与的限时抢购不存在!");
|
||||
throw new ServiceException("当前参与的秒杀活动不存在!");
|
||||
}
|
||||
seckill.checkTime();
|
||||
// 检查限时抢购申请是否合法
|
||||
checkSeckillApplyList(seckill.getApplyEndTime().getTime(), seckill.getHours(), seckillApplyList, storeId);
|
||||
String storeIds = seckill.getStoreIds() != null ? seckill.getStoreIds() : "";
|
||||
boolean containsStore = false;
|
||||
List<String> storeIdList = Arrays.asList(storeIds.split(","));
|
||||
// 检查是否为已参加活动的店铺
|
||||
if (CharSequenceUtil.isNotEmpty(seckillId) && !storeIdList.contains(storeId)) {
|
||||
if (!CharSequenceUtil.isEmpty(storeIds)) {
|
||||
String[] storeIdSplit = storeIds.split(",");
|
||||
for (String s : storeIdSplit) {
|
||||
if (s.equals(seckillId)) {
|
||||
containsStore = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
storeIds = seckill.getStoreIds() + storeId + ",";
|
||||
} else {
|
||||
storeIds = storeId + ",";
|
||||
}
|
||||
seckill.setStoreIds(storeIds);
|
||||
}
|
||||
|
||||
List<SeckillApply> originList = seckill.getSeckillApplyList();
|
||||
// 检查秒杀活动申请是否合法
|
||||
checkSeckillApplyList(seckill.getHours(), seckillApplyList, storeId);
|
||||
//获取已参与活动的秒杀活动活动申请列表
|
||||
List<SeckillApply> originList = seckill.getSeckillApplyList() != null ? seckill.getSeckillApplyList() : new ArrayList<>();
|
||||
List<PromotionGoods> promotionGoodsList = new ArrayList<>();
|
||||
if (originList == null) {
|
||||
originList = new ArrayList<>();
|
||||
}
|
||||
for (SeckillApplyVO seckillApply : seckillApplyList) {
|
||||
//获取参与活动的商品信息
|
||||
GoodsSku goodsSku = goodsSkuService.getGoodsSkuByIdFromCache(seckillApply.getSkuId());
|
||||
//活动库存不能大于商品库存
|
||||
if (goodsSku.getQuantity() < seckillApply.getQuantity()) {
|
||||
throw new ServiceException(seckillApply.getGoodsName() + ",此商品库存不足");
|
||||
}
|
||||
|
||||
/*
|
||||
*************两种情况:******************
|
||||
团购时间段: |________________|
|
||||
秒杀时间段: |_____| |_______|
|
||||
|
||||
************第三种情况:******************
|
||||
团购时间段: |______|
|
||||
秒杀时间段: |________________|
|
||||
|
||||
************第四种情况:******************
|
||||
团购时间段: |________________|
|
||||
秒杀时间段: |______|
|
||||
|
||||
这个商品的开始时间计算要用他参与的时间段来计算,结束时间是当天晚上23:59:59
|
||||
*/
|
||||
String startTimeStr = DateUtil.toString(seckill.getStartTime(), DateUtil.STANDARD_DATE_FORMAT) + " " + (seckillApply.getTimeLine() > 10 ? ("0" + seckillApply.getTimeLine()) : seckillApply.getTimeLine()) + ":00:00";
|
||||
String endTimeStr = DateUtil.toString(seckill.getStartTime(), "yyyy-MM-dd") + " 23:59:59";
|
||||
|
||||
// 查询是否在同一时间段参与了拼团活动
|
||||
Integer count = promotionGoodsService.findInnerOverlapPromotionGoods(PromotionTypeEnum.PINTUAN.name(), goodsSku.getId(), DateUtil.toDate(startTimeStr, DateUtil.STANDARD_FORMAT), DateUtil.toDate(endTimeStr, DateUtil.STANDARD_FORMAT));
|
||||
// 查询是否在同一时间段参与了限时抢购活动
|
||||
count += promotionGoodsService.findInnerOverlapPromotionGoods(PromotionTypeEnum.SECKILL.name(), goodsSku.getId(), DateUtil.toDate(startTimeStr, DateUtil.STANDARD_FORMAT), DateUtil.toDate(endTimeStr, DateUtil.STANDARD_FORMAT));
|
||||
if (count > 0) {
|
||||
throw new ServiceException("商品[" + goodsSku.getGoodsName() + "]已经在重叠的时间段参加了团购或限时抢购活动,不能参加限时抢购活动");
|
||||
}
|
||||
//获取秒杀活动时间段
|
||||
DateTime startTime = DateUtil.offsetHour(seckill.getStartTime(), seckillApply.getTimeLine());
|
||||
//检测是否可以发布促销商品
|
||||
checkSeckillGoodsSKU(seckill, goodsSku, startTime);
|
||||
//设置秒杀申请默认内容
|
||||
seckillApply.setOriginalPrice(goodsSku.getPrice());
|
||||
seckillApply.setPromotionApplyStatus(PromotionApplyStatusEnum.APPLY.name());
|
||||
seckillApply.setPromotionApplyStatus(PromotionApplyStatusEnum.PASS.name());
|
||||
seckillApply.setSalesNum(0);
|
||||
|
||||
Optional<SeckillApply> first = originList.stream().filter(i -> i.getSkuId().equals(seckillApply.getSkuId())).findFirst();
|
||||
if (first.isPresent() && (first.get().getPromotionApplyStatus().equals(PromotionApplyStatusEnum.REFUSE.name()) || first.get().getPromotionApplyStatus().equals(PromotionApplyStatusEnum.APPLY.name()))) {
|
||||
originList = originList.stream().filter(i -> !i.getSkuId().equals(seckillApply.getSkuId())).collect(Collectors.toList());
|
||||
} else if (first.isPresent() && first.get().getPromotionApplyStatus().equals(PromotionApplyStatusEnum.PASS.name())) {
|
||||
continue;
|
||||
}
|
||||
originList.add(seckillApply);
|
||||
PromotionGoods promotionGoods = new PromotionGoods(goodsSku);
|
||||
promotionGoods.setPrice(seckillApply.getPrice());
|
||||
promotionGoods.setQuantity(seckillApply.getQuantity());
|
||||
// 设置单独每个促销商品的结束时间
|
||||
int nextHour = 23;
|
||||
String[] split = seckill.getHours().split(",");
|
||||
int[] hoursSored = Arrays.stream(split).mapToInt(Integer::parseInt).toArray();
|
||||
Arrays.sort(hoursSored);
|
||||
for (int i : hoursSored) {
|
||||
if (seckillApply.getTimeLine() < i) {
|
||||
nextHour = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String format = cn.hutool.core.date.DateUtil.format(seckill.getStartTime(), DateUtil.STANDARD_DATE_FORMAT);
|
||||
DateTime parseStartTime = cn.hutool.core.date.DateUtil.parse((format + " " + seckillApply.getTimeLine()), "yyyy-MM-dd HH");
|
||||
DateTime parseEndTime = cn.hutool.core.date.DateUtil.parse((format + " " + nextHour), "yyyy-MM-dd HH");
|
||||
// 如果是当天最后的时间段则设置到当天结束时间的59分59秒
|
||||
if (nextHour == seckillApply.getTimeLine()) {
|
||||
parseEndTime = cn.hutool.core.date.DateUtil.parse((format + " " + nextHour + ":59:59"), DateUtil.STANDARD_FORMAT);
|
||||
}
|
||||
promotionGoods.setStartTime(parseStartTime);
|
||||
promotionGoods.setEndTime(parseEndTime);
|
||||
//获取促销商品
|
||||
PromotionGoods promotionGoods = this.setSeckillGoods(goodsSku, seckillApply, seckill);
|
||||
promotionGoodsList.add(promotionGoods);
|
||||
}
|
||||
//保存秒杀活动申请
|
||||
this.saveOrUpdateBatch(originList);
|
||||
//设置秒杀活动下的申请列表
|
||||
seckill.setSeckillApplyList(originList);
|
||||
//mongo保存秒杀活动信息
|
||||
this.mongoTemplate.save(seckill);
|
||||
//保存促销活动商品信息
|
||||
if (!promotionGoodsList.isEmpty()) {
|
||||
LambdaQueryWrapper<PromotionGoods> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(PromotionGoods::getSkuId, promotionGoodsList.stream().map(PromotionGoods::getSkuId).collect(Collectors.toList())).eq(PromotionGoods::getStoreId, storeId);
|
||||
queryWrapper.in(PromotionGoods::getSkuId, promotionGoodsList.stream().map(PromotionGoods::getSkuId).collect(Collectors.toList()))
|
||||
.eq(PromotionGoods::getStoreId, storeId);
|
||||
promotionGoodsService.remove(queryWrapper);
|
||||
//初始化促销商品
|
||||
PromotionTools.promotionGoodsInit(promotionGoodsList, seckill, PromotionTypeEnum.SECKILL);
|
||||
promotionGoodsService.saveBatch(promotionGoodsList);
|
||||
}
|
||||
|
||||
if (Boolean.FALSE.equals(containsStore)) {
|
||||
seckillService.storeApply(storeId, seckill.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量删除限时抢购申请
|
||||
* 批量删除秒杀活动申请
|
||||
*
|
||||
* @param seckillId 限时抢购活动id
|
||||
* @param ids 限时抢购申请id集合
|
||||
* @param seckillId 秒杀活动活动id
|
||||
* @param ids 秒杀活动申请id集合
|
||||
*/
|
||||
@Override
|
||||
public void removeSeckillApplyByIds(String seckillId, List<String> ids) {
|
||||
SeckillVO seckillVO = this.mongoTemplate.findById(seckillId, SeckillVO.class);
|
||||
if (seckillVO == null) {
|
||||
throw new ServiceException("当前限时抢购活动不存在!");
|
||||
throw new ServiceException("当前秒杀活动活动不存在!");
|
||||
}
|
||||
if (seckillVO.getPromotionStatus().equals(PromotionStatusEnum.START.name())) {
|
||||
throw new ServiceException("当前限时抢购活动已经开始,无法修改!");
|
||||
throw new ServiceException("当前秒杀活动活动已经开始,无法修改!");
|
||||
}
|
||||
seckillVO.getSeckillApplyList().removeIf(seckillApply -> ids.contains(seckillApply.getId()));
|
||||
this.mongoTemplate.save(seckillVO);
|
||||
@ -335,78 +213,26 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新限时抢购库存数量
|
||||
* 检查秒杀活动申请列表参数信息
|
||||
*
|
||||
* @param id 限时抢购申请(限时抢购商品)id
|
||||
* @param num 数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
public boolean updateSeckillStock(String id, Integer num) {
|
||||
List<String> promotionIds = this.esGoodsIndexService.getPromotionIdByPromotionType(id, PromotionTypeEnum.SECKILL);
|
||||
for (String promotionId : promotionIds) {
|
||||
SeckillVO seckillVO = this.mongoTemplate.findById(promotionId, SeckillVO.class);
|
||||
if (seckillVO == null) {
|
||||
log.error("限时抢购活动id为" + promotionId + "的限时抢购活动不存在!");
|
||||
break;
|
||||
}
|
||||
if (seckillVO.getSeckillApplyList() != null && !seckillVO.getSeckillApplyList().isEmpty()) {
|
||||
Optional<SeckillApply> seckillApplyOptional = seckillVO.getSeckillApplyList().stream().filter(i -> i.getSkuId().equals(id)).findFirst();
|
||||
if (seckillApplyOptional.isPresent()) {
|
||||
SeckillApply seckillApply = seckillApplyOptional.get();
|
||||
// 设置售卖数量
|
||||
Integer countNum = seckillApply.getSalesNum() + num;
|
||||
seckillApply.setSalesNum(countNum);
|
||||
LambdaUpdateWrapper<SeckillApply> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(SeckillApply::getId, seckillApply.getId());
|
||||
updateWrapper.set(SeckillApply::getQuantity, seckillApply.getQuantity() - num);
|
||||
updateWrapper.set(SeckillApply::getSalesNum, countNum);
|
||||
this.update(updateWrapper);
|
||||
this.mongoTemplate.save(seckillVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新限时抢购库存数量
|
||||
*
|
||||
* @param map key 为 限时抢购申请(限时抢购商品)id, value 为数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
public boolean updateSeckillStock(Map<String, Integer> map) {
|
||||
boolean result = false;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
result = this.updateSeckillStock(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查限时抢购申请列表参数信息
|
||||
*
|
||||
* @param applyEndTime 申请结束时间
|
||||
* @param hours 限时抢购时间段
|
||||
* @param seckillApplyList 限时抢购申请列表
|
||||
* @param hours 秒杀活动时间段
|
||||
* @param seckillApplyList 秒杀活动申请列表
|
||||
* @param storeId 当前申请商家编号
|
||||
*/
|
||||
private void checkSeckillApplyList(Long applyEndTime, String hours, List<SeckillApplyVO> seckillApplyList, String storeId) {
|
||||
private void checkSeckillApplyList(String hours, List<SeckillApplyVO> seckillApplyList, String storeId) {
|
||||
List<String> existSku = new ArrayList<>();
|
||||
for (SeckillApplyVO seckillApply : seckillApplyList) {
|
||||
seckillApply.setStoreId(storeId);
|
||||
if (seckillApply.getPrice() > seckillApply.getOriginalPrice()) {
|
||||
throw new ServiceException("活动价格不能大于商品原价");
|
||||
}
|
||||
|
||||
// 检查限时抢购申请的时刻,是否存在在限时抢购的时间段内
|
||||
// 检查秒杀活动申请的时刻,是否存在在秒杀活动的时间段内
|
||||
String[] rangeHours = hours.split(",");
|
||||
boolean containsSame = Arrays.stream(rangeHours).anyMatch(i -> i.equals(seckillApply.getTimeLine().toString()));
|
||||
if (!containsSame) {
|
||||
throw new ServiceException("时刻参数异常");
|
||||
}
|
||||
|
||||
//检查商品是否参加多个时间段的活动
|
||||
if (existSku.contains(seckillApply.getSkuId())) {
|
||||
throw new ServiceException(seckillApply.getGoodsName() + "该商品不能同时参加多个时间段的活动");
|
||||
} else {
|
||||
@ -419,13 +245,13 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
|
||||
/**
|
||||
* 组装促销商品信息
|
||||
*
|
||||
* @param seckillApply 限时抢购申请信息
|
||||
* @param seckillStartTime 当前限时抢购申请的开始时间
|
||||
* @param seckillApply 秒杀活动申请信息
|
||||
* @param seckillStartTime 当前秒杀活动申请的开始时间
|
||||
* @return 促销商品信息
|
||||
*/
|
||||
private PromotionGoods setPromotionGoods(SeckillApply seckillApply, Date seckillStartTime) {
|
||||
PromotionGoods promotionGoods = new PromotionGoods();
|
||||
promotionGoods.setTitle("限时抢购");
|
||||
promotionGoods.setTitle("秒杀活动");
|
||||
promotionGoods.setSkuId(seckillApply.getSkuId());
|
||||
promotionGoods.setPromotionType(PromotionTypeEnum.SECKILL.name());
|
||||
promotionGoods.setPromotionId(seckillApply.getSeckillId());
|
||||
@ -435,9 +261,9 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
|
||||
promotionGoods.setPromotionStatus(PromotionStatusEnum.NEW.name());
|
||||
//商品活动的开始时间为当前商品的参加时间段
|
||||
int timeLine = seckillApply.getTimeLine();
|
||||
String date = DateUtil.toString(seckillStartTime, DateUtil.STANDARD_DATE_FORMAT);
|
||||
long startTime = DateUtil.getDateline(date + " " + timeLine + ":00:00", DateUtil.STANDARD_FORMAT);
|
||||
long endTime = DateUtil.getDateline(date + " 23:59:59", DateUtil.STANDARD_FORMAT);
|
||||
String date = cn.lili.common.utils.DateUtil.toString(seckillStartTime, cn.lili.common.utils.DateUtil.STANDARD_DATE_FORMAT);
|
||||
long startTime = cn.lili.common.utils.DateUtil.getDateline(date + " " + timeLine + ":00:00", cn.lili.common.utils.DateUtil.STANDARD_FORMAT);
|
||||
long endTime = cn.lili.common.utils.DateUtil.getDateline(date + " 23:59:59", cn.lili.common.utils.DateUtil.STANDARD_FORMAT);
|
||||
|
||||
promotionGoods.setStartTime(new Date(startTime));
|
||||
promotionGoods.setEndTime(new Date(endTime));
|
||||
@ -445,30 +271,30 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查缓存中是否存在相同商品参与的限时抢购活动
|
||||
* 检查缓存中是否存在相同商品参与的秒杀活动活动
|
||||
*
|
||||
* @param startTime 限时抢购开始时间
|
||||
* @param startTime 秒杀活动开始时间
|
||||
*/
|
||||
private void checkCache(Long startTime) {
|
||||
String seckillCacheKey = PromotionCacheKeys.getSeckillTimelineKey(DateUtil.toString(startTime, DateUtil.STANDARD_DATE_NO_UNDERLINE_FORMAT));
|
||||
String seckillCacheKey = PromotionCacheKeys.getSeckillTimelineKey(cn.lili.common.utils.DateUtil.toString(startTime, cn.lili.common.utils.DateUtil.STANDARD_DATE_NO_UNDERLINE_FORMAT));
|
||||
Map<Object, Object> hash = cache.getHash(seckillCacheKey);
|
||||
//如果缓存中存在当前审核商品参与的限时抢购活动商品信息,清除
|
||||
//如果缓存中存在当前审核商品参与的秒杀活动活动商品信息,清除
|
||||
if (hash != null && !hash.isEmpty()) {
|
||||
cache.remove(seckillCacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中获取限时抢购信息
|
||||
* 从缓存中获取秒杀活动信息
|
||||
*
|
||||
* @param seckillCacheKey 限时抢购缓存键
|
||||
* @return 限时抢购信息
|
||||
* @param seckillCacheKey 秒杀活动缓存键
|
||||
* @return 秒杀活动信息
|
||||
*/
|
||||
private List<SeckillTimelineVO> getSeckillTimelineToCache(String seckillCacheKey) {
|
||||
List<SeckillTimelineVO> timelineList = new ArrayList<>();
|
||||
LambdaQueryWrapper<Seckill> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// 查询当天时间段内的且状态不为结束或关闭的限时抢购活动
|
||||
queryWrapper.gt(Seckill::getStartTime, new Date(DateUtil.startOfTodDay() * 1000)).lt(Seckill::getEndTime, DateUtil.endOfDate())
|
||||
// 查询当天时间段内的且状态不为结束或关闭的秒杀活动活动
|
||||
queryWrapper.gt(Seckill::getStartTime, new Date(cn.lili.common.utils.DateUtil.startOfTodDay() * 1000)).lt(Seckill::getEndTime, cn.lili.common.utils.DateUtil.endOfDate())
|
||||
.and(i -> i.eq(Seckill::getPromotionStatus, PromotionStatusEnum.NEW.name())
|
||||
.or(j -> j.eq(Seckill::getPromotionStatus, PromotionStatusEnum.START.name())));
|
||||
List<Seckill> seckillList = seckillService.list(queryWrapper);
|
||||
@ -483,14 +309,14 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
|
||||
for (int i = 0; i < hoursSored.length; i++) {
|
||||
SeckillTimelineVO tempTimeline = new SeckillTimelineVO();
|
||||
if (hoursSored[i] >= hour || ((i + 1) < hoursSored.length && hoursSored[i + 1] > hour)) {
|
||||
SimpleDateFormat format = new SimpleDateFormat(DateUtil.STANDARD_DATE_FORMAT);
|
||||
SimpleDateFormat format = new SimpleDateFormat(cn.lili.common.utils.DateUtil.STANDARD_DATE_FORMAT);
|
||||
String date = format.format(new Date());
|
||||
//当前时间的秒数
|
||||
long currentTime = DateUtil.getDateline();
|
||||
//限时抢购的时刻
|
||||
long timeLine = DateUtil.getDateline(date + " " + hoursSored[i], "yyyy-MM-dd HH");
|
||||
long currentTime = cn.lili.common.utils.DateUtil.getDateline();
|
||||
//秒杀活动的时刻
|
||||
long timeLine = cn.lili.common.utils.DateUtil.getDateline(date + " " + hoursSored[i], "yyyy-MM-dd HH");
|
||||
if ((i + 1) < hoursSored.length && hour > hoursSored[i] && hour <= hoursSored[i + 1]) {
|
||||
timeLine = DateUtil.getDateline(date + " " + hoursSored[i + 1], "yyyy-MM-dd HH");
|
||||
timeLine = cn.lili.common.utils.DateUtil.getDateline(date + " " + hoursSored[i + 1], "yyyy-MM-dd HH");
|
||||
}
|
||||
Long distanceTime = timeLine - currentTime < 0 ? 0 : timeLine - currentTime;
|
||||
tempTimeline.setDistanceStartTime(distanceTime);
|
||||
@ -507,16 +333,16 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装当时间限时抢购的商品数据
|
||||
* 组装当时间秒杀活动的商品数据
|
||||
* w
|
||||
*
|
||||
* @param startTimeline 限时抢购开始时刻
|
||||
* @return 当时间限时抢购的商品数据
|
||||
* @param startTimeline 秒杀活动开始时刻
|
||||
* @return 当时间秒杀活动的商品数据
|
||||
*/
|
||||
private List<SeckillGoodsVO> wrapperSeckillGoods(Integer startTimeline) {
|
||||
List<SeckillGoodsVO> seckillGoodsVoS = new ArrayList<>();
|
||||
LambdaQueryWrapper<Seckill> seckillLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
seckillLambdaQueryWrapper.gt(Seckill::getStartTime, new Date(DateUtil.startOfTodDay() * 1000)).lt(Seckill::getEndTime, DateUtil.endOfDate())
|
||||
seckillLambdaQueryWrapper.gt(Seckill::getStartTime, new Date(cn.lili.common.utils.DateUtil.startOfTodDay() * 1000)).lt(Seckill::getEndTime, cn.lili.common.utils.DateUtil.endOfDate())
|
||||
.and(i -> i.eq(Seckill::getPromotionStatus, PromotionStatusEnum.NEW.name())
|
||||
.or(j -> j.eq(Seckill::getPromotionStatus, PromotionStatusEnum.START.name())));
|
||||
List<Seckill> seckillList = this.seckillService.list(seckillLambdaQueryWrapper);
|
||||
@ -539,4 +365,53 @@ public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, Sec
|
||||
}
|
||||
return seckillGoodsVoS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测秒杀申请的商品
|
||||
*
|
||||
* @param seckill 秒杀活动
|
||||
* @param goodsSku 商品SKU
|
||||
* @param startTime 秒杀时段开启时间
|
||||
*/
|
||||
private void checkSeckillGoodsSKU(SeckillVO seckill, GoodsSku goodsSku, DateTime startTime) {
|
||||
// 查询是否在同一时间段参与了拼团活动
|
||||
if (promotionGoodsService.findInnerOverlapPromotionGoods(PromotionTypeEnum.PINTUAN.name(), goodsSku.getId(), startTime, seckill.getEndTime()) > 0) {
|
||||
throw new ServiceException("商品[" + goodsSku.getGoodsName() + "]已经在重叠的时间段参加了拼团活动,不能参加秒杀活动");
|
||||
}
|
||||
// 查询是否在同一时间段参与了秒杀活动活动
|
||||
if (promotionGoodsService.findInnerOverlapPromotionGoods(PromotionTypeEnum.SECKILL.name(), goodsSku.getId(), startTime, seckill.getEndTime()) > 0) {
|
||||
throw new ServiceException("商品[" + goodsSku.getGoodsName() + "]已经在重叠的时间段参加了秒杀活动,不能参加秒杀活动活动");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取秒杀活动促销商品
|
||||
*
|
||||
* @param goodsSku 商品SKU
|
||||
* @param seckillApply 秒杀活动申请
|
||||
* @param seckill 秒杀活动
|
||||
* @return 秒杀活动促销商品
|
||||
*/
|
||||
private PromotionGoods setSeckillGoods(GoodsSku goodsSku, SeckillApply seckillApply, Seckill seckill) {
|
||||
//设置促销商品默认内容
|
||||
PromotionGoods promotionGoods = new PromotionGoods(goodsSku);
|
||||
promotionGoods.setPrice(seckillApply.getPrice());
|
||||
promotionGoods.setQuantity(seckillApply.getQuantity());
|
||||
// 设置单独每个促销商品的结束时间
|
||||
int nextHour = 23;
|
||||
String[] split = seckill.getHours().split(",");
|
||||
int[] hoursSored = Arrays.stream(split).mapToInt(Integer::parseInt).toArray();
|
||||
Arrays.sort(hoursSored);
|
||||
for (int i : hoursSored) {
|
||||
if (seckillApply.getTimeLine() < i) {
|
||||
nextHour = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DateTime startTime = DateUtil.offsetHour(seckill.getStartTime(), seckillApply.getTimeLine());
|
||||
DateTime parseEndTime = DateUtil.offsetSecond(DateUtil.offsetHour(seckill.getStartTime(), nextHour), 1);
|
||||
promotionGoods.setStartTime(startTime);
|
||||
promotionGoods.setEndTime(parseEndTime);
|
||||
return promotionGoods;
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ import cn.lili.common.exception.ServiceException;
|
||||
import cn.lili.common.trigger.interfaces.TimeTrigger;
|
||||
import cn.lili.common.trigger.model.TimeExecuteConstant;
|
||||
import cn.lili.common.trigger.model.TimeTriggerMsg;
|
||||
import cn.lili.common.utils.BeanUtil;
|
||||
import cn.lili.common.utils.DateUtil;
|
||||
import cn.lili.common.utils.PageUtil;
|
||||
import cn.lili.common.utils.StringUtils;
|
||||
@ -43,7 +44,7 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 限时抢购业务层实现
|
||||
* 秒杀活动业务层实现
|
||||
*
|
||||
* @author Chopper
|
||||
* @date 2020/8/21
|
||||
@ -77,13 +78,6 @@ public class SeckillServiceImpl extends ServiceImpl<SeckillMapper, Seckill> impl
|
||||
return page(PageUtil.initPage(pageVo), queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从mongo中根据条件获取限时抢购分页列表
|
||||
*
|
||||
* @param queryParam 查询参数
|
||||
* @param pageVo 分页参数
|
||||
* @return 限时抢购分页列表
|
||||
*/
|
||||
@Override
|
||||
public IPage<SeckillVO> getSeckillByPageFromMongo(SeckillSearchParams queryParam, PageVO pageVo) {
|
||||
IPage<SeckillVO> seckill = new Page<>(pageVo.getPageNumber(), pageVo.getPageSize());
|
||||
@ -101,27 +95,24 @@ public class SeckillServiceImpl extends ServiceImpl<SeckillMapper, Seckill> impl
|
||||
return seckill;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从mongo中获取限时抢购信息
|
||||
*
|
||||
* @param id 限时抢购id
|
||||
* @return 限时抢购信息
|
||||
*/
|
||||
@Override
|
||||
public SeckillVO getSeckillByIdFromMongo(String id) {
|
||||
return this.checkSeckillExist(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveSeckill(SeckillVO seckill) {
|
||||
// 检查限时抢购参数
|
||||
checkSeckillParam(seckill, seckill.getStoreId());
|
||||
seckill.setPromotionStatus(PromotionStatusEnum.NEW.name());
|
||||
public boolean saveSeckill(Seckill seckill) {
|
||||
|
||||
SeckillVO seckillVO=new SeckillVO();
|
||||
BeanUtil.copyProperties(seckill,seckillVO);
|
||||
// 检查秒杀活动参数
|
||||
checkSeckillParam(seckillVO, seckill.getStoreId());
|
||||
// 保存到MYSQL中
|
||||
boolean result = this.save(seckill);
|
||||
// 保存到MONGO中
|
||||
this.mongoTemplate.save(seckill);
|
||||
this.addSeckillStartTask(seckill);
|
||||
//添加秒杀延时任务
|
||||
this.addSeckillStartTask(seckillVO);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -135,17 +126,18 @@ public class SeckillServiceImpl extends ServiceImpl<SeckillMapper, Seckill> impl
|
||||
storeIds = storeId + ",";
|
||||
}
|
||||
seckill.setStoreIds(storeIds);
|
||||
|
||||
this.updateById(seckill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean modifySeckill(SeckillVO seckillVO) {
|
||||
// 检查该限时抢购是否存在
|
||||
// 检查该秒杀活动是否存在
|
||||
SeckillVO seckill = checkSeckillExist(seckillVO.getId());
|
||||
if (PromotionStatusEnum.START.name().equals(seckillVO.getPromotionStatus())) {
|
||||
throw new ServiceException("活动已经开始,不能进行编辑删除操作");
|
||||
}
|
||||
// 检查限时抢购参数
|
||||
// 检查秒杀活动参数
|
||||
this.checkSeckillParam(seckillVO, seckillVO.getStoreId());
|
||||
|
||||
// 更新到MYSQL中
|
||||
@ -170,7 +162,7 @@ public class SeckillServiceImpl extends ServiceImpl<SeckillMapper, Seckill> impl
|
||||
public void deleteSeckill(String id) {
|
||||
Seckill seckill = checkSeckillExist(id);
|
||||
if (PromotionStatusEnum.CLOSE.name().equals(seckill.getPromotionStatus()) || PromotionStatusEnum.END.name().equals(seckill.getPromotionStatus())) {
|
||||
// 更新限时抢购状态为关闭,标示删除标志
|
||||
// 更新秒杀活动状态为关闭,标示删除标志
|
||||
LambdaUpdateWrapper<Seckill> updateWrapper = new LambdaUpdateWrapper<Seckill>().eq(Seckill::getId, id).set(Seckill::getDeleteFlag, true).set(Seckill::getPromotionStatus, PromotionStatusEnum.CLOSE.name());
|
||||
this.update(updateWrapper);
|
||||
LambdaUpdateWrapper<SeckillApply> seckillApplyLambdaUpdateWrapper = new LambdaUpdateWrapper<SeckillApply>().eq(SeckillApply::getSeckillId, id).set(SeckillApply::getDeleteFlag, true);
|
||||
@ -183,14 +175,14 @@ public class SeckillServiceImpl extends ServiceImpl<SeckillMapper, Seckill> impl
|
||||
DelayQueueTools.wrapperUniqueKey(DelayQueueType.PROMOTION, (PromotionTypeEnum.SECKILL.name() + seckill.getId())),
|
||||
rocketmqCustomProperties.getPromotionTopic());
|
||||
} else {
|
||||
throw new ServiceException("该限时抢购活动的状态不能删除");
|
||||
throw new ServiceException("该秒杀活动活动的状态不能删除");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启一个限时抢购
|
||||
* 开启一个秒杀活动
|
||||
*
|
||||
* @param id 限时抢购编号
|
||||
* @param id 秒杀活动编号
|
||||
*/
|
||||
@Override
|
||||
public void openSeckill(String id) {
|
||||
@ -227,7 +219,7 @@ public class SeckillServiceImpl extends ServiceImpl<SeckillMapper, Seckill> impl
|
||||
rocketmqCustomProperties.getPromotionTopic());
|
||||
}
|
||||
} else {
|
||||
throw new ServiceException("该限时抢购活动的状态不能关闭");
|
||||
throw new ServiceException("该秒杀活动活动的状态不能关闭");
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,6 +232,10 @@ public class SeckillServiceImpl extends ServiceImpl<SeckillMapper, Seckill> impl
|
||||
return this.count(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加秒杀活动延时任务
|
||||
* @param seckill 秒杀活动
|
||||
*/
|
||||
private void addSeckillStartTask(SeckillVO seckill) {
|
||||
PromotionMessage promotionMessage = new PromotionMessage(seckill.getId(), PromotionTypeEnum.SECKILL.name(), PromotionStatusEnum.START.name(), seckill.getStartTime(), seckill.getEndTime());
|
||||
TimeTriggerMsg timeTriggerMsg = new TimeTriggerMsg(TimeExecuteConstant.PROMOTION_EXECUTOR,
|
||||
@ -252,27 +248,26 @@ public class SeckillServiceImpl extends ServiceImpl<SeckillMapper, Seckill> impl
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查该限时抢购是否存在
|
||||
* 检查该秒杀活动是否存在
|
||||
*
|
||||
* @param id 限时抢购编号
|
||||
* @return 限时抢购信息
|
||||
* @param id 秒杀活动编号
|
||||
* @return 秒杀活动信息
|
||||
*/
|
||||
private SeckillVO checkSeckillExist(String id) {
|
||||
SeckillVO seckill = this.mongoTemplate.findById(id, SeckillVO.class);
|
||||
if (seckill == null) {
|
||||
throw new ServiceException("当前限时抢购活动不存在");
|
||||
throw new ServiceException("当前秒杀活动活动不存在");
|
||||
}
|
||||
return seckill;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查限时抢购参数
|
||||
* 检查秒杀活动参数
|
||||
*
|
||||
* @param seckill 限时抢购信息
|
||||
* @param seckill 秒杀活动信息
|
||||
* @param storeId 卖家编号
|
||||
*/
|
||||
private void checkSeckillParam(SeckillVO seckill, String storeId) {
|
||||
seckill.checkTime();
|
||||
// 同一时间段内相同的活动
|
||||
QueryWrapper<Seckill> queryWrapper = PromotionTools.checkActiveTime(seckill.getStartTime(), seckill.getEndTime(), PromotionTypeEnum.SECKILL, storeId, seckill.getId());
|
||||
int sameNum = this.count(queryWrapper);
|
||||
|
@ -28,7 +28,7 @@ public class PromotionCacheKeys {
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取满优惠redis key
|
||||
* 读取秒杀活动redis key
|
||||
* @param timeStr 时间字符串(格式为 yyyyMMdd)
|
||||
* @return 满优惠redis key
|
||||
*/
|
||||
|
@ -0,0 +1,25 @@
|
||||
package cn.lili.modules.system.entity.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 秒杀活动设置
|
||||
*
|
||||
* @author Bulbasaur
|
||||
* @date: 2021/5/24 3:27 下午
|
||||
*/
|
||||
@Data
|
||||
public class SeckillSetting implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "开启几点场 例如:6,8,12")
|
||||
@NotNull(message = "活动时间段不能为空")
|
||||
private String hours;
|
||||
|
||||
@ApiModelProperty(value = "秒杀规则")
|
||||
@NotNull(message = "秒杀规则不能为空")
|
||||
private String seckillRule;
|
||||
}
|
@ -29,6 +29,8 @@ public enum SettingEnum {
|
||||
POINT_SETTING,
|
||||
//经验值设置
|
||||
EXPERIENCE_SETTING,
|
||||
//经验值设置
|
||||
SECKILL_SETTING,
|
||||
|
||||
//微信 联合登陆设置
|
||||
WECHAT_CONNECT,
|
||||
|
@ -27,8 +27,8 @@ import org.springframework.web.bind.annotation.*;
|
||||
* @date: 2021/5/21 7:11 下午
|
||||
*/
|
||||
@RestController
|
||||
@Api(tags = "管理端,优惠券接口")
|
||||
@RequestMapping("/manager/promotion/coupon")
|
||||
@Api(tags = "管理端,优惠券活动接口")
|
||||
@RequestMapping("/manager/promotion/couponActivity")
|
||||
public class CouponActivityManagerController {
|
||||
|
||||
@Autowired
|
||||
|
@ -19,13 +19,13 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 管理端,限时抢购接口
|
||||
* 管理端,秒杀活动接口
|
||||
*
|
||||
* @author paulG
|
||||
* @date 2020/8/20
|
||||
**/
|
||||
@RestController
|
||||
@Api(tags = "管理端,限时抢购接口")
|
||||
@Api(tags = "管理端,秒杀活动接口")
|
||||
@RequestMapping("/manager/promotion/seckill")
|
||||
public class SeckillManagerController {
|
||||
@Autowired
|
||||
@ -34,7 +34,7 @@ public class SeckillManagerController {
|
||||
private SeckillApplyService seckillApplyService;
|
||||
|
||||
@PostMapping
|
||||
@ApiOperation(value = "添加限时抢购")
|
||||
@ApiOperation(value = "添加秒杀活动")
|
||||
public ResultMessage<Seckill> addSeckill(SeckillVO seckillVO) {
|
||||
AuthUser currentUser = UserContext.getCurrentUser();
|
||||
seckillVO.setStoreId(currentUser.getId());
|
||||
@ -45,7 +45,7 @@ public class SeckillManagerController {
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@ApiOperation(value = "修改限时抢购")
|
||||
@ApiOperation(value = "修改秒杀活动")
|
||||
public ResultMessage<Seckill> updateSeckill(SeckillVO seckillVO) {
|
||||
AuthUser currentUser = UserContext.getCurrentUser();
|
||||
seckillVO.setStoreId(currentUser.getId());
|
||||
@ -62,7 +62,7 @@ public class SeckillManagerController {
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@ApiOperation(value = "分页查询限时抢购列表")
|
||||
@ApiOperation(value = "分页查询秒杀活动列表")
|
||||
public ResultMessage<IPage<SeckillVO>> getAll(SeckillSearchParams param, PageVO pageVo) {
|
||||
pageVo.setNotConvert(true);
|
||||
IPage<SeckillVO> page = seckillService.getSeckillByPageFromMongo(param, pageVo);
|
||||
@ -70,38 +70,31 @@ public class SeckillManagerController {
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@ApiOperation(value = "删除一个限时抢购")
|
||||
@ApiOperation(value = "删除一个秒杀活动")
|
||||
public ResultMessage<Object> deleteSeckill(@PathVariable String id) {
|
||||
seckillService.deleteSeckill(id);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
@PutMapping("/close/{id}")
|
||||
@ApiOperation(value = "关闭一个限时抢购")
|
||||
@ApiOperation(value = "关闭一个秒杀活动")
|
||||
public ResultMessage<Object> closeSeckill(@PathVariable String id) {
|
||||
seckillService.closeSeckill(id);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
@PutMapping("/open/{id}")
|
||||
@ApiOperation(value = "一个限时抢购")
|
||||
@ApiOperation(value = "一个秒杀活动")
|
||||
public ResultMessage<Object> openSeckill(@PathVariable String id) {
|
||||
seckillService.openSeckill(id);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
@GetMapping("/apply")
|
||||
@ApiOperation(value = "获取限时抢购申请列表")
|
||||
@ApiOperation(value = "获取秒杀活动申请列表")
|
||||
public ResultMessage<IPage<SeckillApply>> getSeckillApply(SeckillSearchParams param, PageVO pageVo) {
|
||||
IPage<SeckillApply> seckillApply = seckillApplyService.getSeckillApplyFromMongo(param, pageVo);
|
||||
return ResultUtil.data(seckillApply);
|
||||
}
|
||||
|
||||
@PutMapping("/apply/audit/{ids}")
|
||||
@ApiOperation(value = "审核多个限时抢购申请")
|
||||
public ResultMessage<Object> auditSeckillApply(@PathVariable String[] ids, String seckillId, String applyStatus, String failReason) {
|
||||
seckillApplyService.auditBatchApply(ids, seckillId, applyStatus, failReason);
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -83,11 +83,4 @@ class SeckillTest {
|
||||
Assertions.assertTrue(true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void audit() {
|
||||
seckillApplyService.auditBatchApply(new String[]{"1327169604003061760"}, "123456", PromotionApplyStatusEnum.PASS.name(), "");
|
||||
Assertions.assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,13 +22,13 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 店铺端,限时抢购接口
|
||||
* 店铺端,秒杀活动接口
|
||||
*
|
||||
* @author paulG
|
||||
* @date 2020/8/26
|
||||
**/
|
||||
@RestController
|
||||
@Api(tags = "店铺端,限时抢购接口")
|
||||
@Api(tags = "店铺端,秒杀活动接口")
|
||||
@RequestMapping("/store/promotion/seckill")
|
||||
public class SeckillStoreController {
|
||||
@Autowired
|
||||
@ -37,14 +37,14 @@ public class SeckillStoreController {
|
||||
private SeckillApplyService seckillApplyService;
|
||||
|
||||
@GetMapping
|
||||
@ApiOperation(value = "获取限时抢购列表")
|
||||
@ApiOperation(value = "获取秒杀活动列表")
|
||||
public ResultMessage<IPage<SeckillVO>> getSeckillPage(SeckillSearchParams queryParam, PageVO pageVo) {
|
||||
IPage<SeckillVO> seckillPage = seckillService.getSeckillByPageFromMongo(queryParam, pageVo);
|
||||
return ResultUtil.data(seckillPage);
|
||||
}
|
||||
|
||||
@GetMapping("/apply")
|
||||
@ApiOperation(value = "获取限时抢购申请列表")
|
||||
@ApiOperation(value = "获取秒杀活动申请列表")
|
||||
public ResultMessage<IPage<SeckillApply>> getSeckillApplyPage(SeckillSearchParams queryParam, PageVO pageVo) {
|
||||
String storeId = UserContext.getCurrentUser().getStoreId();
|
||||
queryParam.setStoreId(storeId);
|
||||
@ -53,19 +53,19 @@ public class SeckillStoreController {
|
||||
}
|
||||
|
||||
@GetMapping("/{seckillId}")
|
||||
@ApiOperation(value = "获取限时抢购")
|
||||
@ApiOperation(value = "获取秒杀活动")
|
||||
public ResultMessage<Seckill> getSeckill(@PathVariable String seckillId) {
|
||||
return ResultUtil.data(seckillService.getSeckillByIdFromMongo(seckillId));
|
||||
}
|
||||
|
||||
@GetMapping("/apply/{seckillApplyId}")
|
||||
@ApiOperation(value = "获取限时抢购申请")
|
||||
@ApiOperation(value = "获取秒杀活动申请")
|
||||
public ResultMessage<SeckillApply> getSeckillApply(@PathVariable String seckillApplyId) {
|
||||
return ResultUtil.data(seckillApplyService.getById(seckillApplyId));
|
||||
}
|
||||
|
||||
@PostMapping(path = "/apply/{seckillId}", consumes = "application/json", produces = "application/json")
|
||||
@ApiOperation(value = "添加限时抢购申请")
|
||||
@ApiOperation(value = "添加秒杀活动申请")
|
||||
public ResultMessage<String> addSeckillApply(@PathVariable String seckillId, @RequestBody List<SeckillApplyVO> applyVos) {
|
||||
String storeId = UserContext.getCurrentUser().getStoreId();
|
||||
seckillApplyService.addSeckillApply(seckillId, storeId, applyVos);
|
||||
@ -73,7 +73,7 @@ public class SeckillStoreController {
|
||||
}
|
||||
|
||||
@DeleteMapping("/apply/{seckillId}/{ids}")
|
||||
@ApiOperation(value = "删除限时抢购申请")
|
||||
@ApiOperation(value = "删除秒杀活动申请")
|
||||
public ResultMessage<String> deleteSeckillApply(@PathVariable("seckillId") String seckillId, @PathVariable("ids") String ids) {
|
||||
String[] idsSplit = ids.split(",");
|
||||
seckillApplyService.removeSeckillApplyByIds(seckillId, Arrays.asList(idsSplit));
|
||||
|
Loading…
x
Reference in New Issue
Block a user