【云岚到家】-day07-5-实战项目-优惠券活动-活动管理

【云岚到家】-day07-5-实战项目-优惠券活动-活动管理


0 本期代码仓库

https://github.com/bblb-sjb/jzo2o-market.git
如果直接想要现成的源码,可以看看我的afd主页,包含后序开发的各个分支 https://afdian.com/a/bblb9527,一张电影票即可获取全部源码及分支。

2 优惠券活动管理

2.1 需求分析

2.1.1 新增优惠券活动

1)界面原型

运营人员进入优惠券活动管理界面,点击“新增优惠券”进入如下界面。

优惠券新增页包括两部分内容:配置优惠券活动的基本信息和发放规则。

  1. 选择满减

在这里插入图片描述

  1. 选择折扣

在这里插入图片描述

优惠券类型说明

优惠券类型说明逻辑规则举例
满减满x元减y元,例如满100元减20元;其中,x为满额限制,可为0;y为抵扣金额。满额限制为0时即为无满额要求的优惠券,通常称为立减券或无门槛优惠券。满额限制为订单金额需满足多少钱后,方可使用优惠;若满额限制=0时,订单金额>0就可参加; 抵扣金额为优惠券的金额;若抵扣金额 > 订单金额,则实际抵扣金额 = 订单金额; 注意:该满减 不等于 每满减,优惠金额不叠加满0元减10元:订单金额20元,实付金额=20-10=10元; 满0元减10元:订单金额5元,实付金额=5-5=0元; 满100元减10元:订单金额500元,实付金额=500-10=490元;
折扣规则结构为:满x元享y%折扣,其中,x为满额限制,可为0;y为折扣,百分比格式。满额限制同上,当满足条件后,优惠金额=订单金额*折扣%满10元打8折:订单金额10元,实付金额=10×80%=8元满0元打8折:订单金额1元,实付金额=1×80%=0.8元
2)数据分析

表单内容如下:

属性含义举例
活动名称营销活动的名称双12五折大促,尊享双十一活动
优惠券类型包括:满减和折扣满减:满x元减y元,例如满100元减20元;折扣:满x元享y%折扣,例如满100元享10%折扣
满额限制设置满多少钱享受优惠,0表示无门槛金额格式:整数,单位:元金额大小:0=<满额限制200.00:表示满200元
抵扣金额用于满减类型金额格式:整数,单位:元金额大小:0<折扣满额限制20元
抵扣比例用于折扣类型金额格式:整数,单位:无金额大小:0<折扣满额限制<10085表示85%,即85折
发放时间优惠券活动创建成功后到达发放时间将会在前台进行展示,用户即可进行抢券。发放结束时间:即活动结束,活动结束后不可以领券。格式:年月日时分秒~年月日时分秒发放时间开始时间至少设置在距离当前时间的1个小时之后2023-09-22 00:00 ~ 2023-09-29 00:00
使用期限单位:天从领取优惠时间加上使用期限是该优惠券的有效期限比如:2023-09-01 07:00:00领取的优惠券,使用期限为7天,2023-09-08 07:00:00后优惠券无法使用7天
发放数量整数,规则:0<发放数量,单位:张1)发放数量= 发放数量为优惠券的总数量,当领取数量=发放数量时,优惠券将在前台显示已抢光;2)每人限领= 每个人最多领取1张优惠券;40张
活动状态活动状态包括:1:待生效,2:进行中,3:已失效 4: 作废’新增后的状态为:待生效到达发放开始时间状态改为“进行中”。到达发放结束时间状态改为“已失效”撤销后状态为“作废”
3)数据校验

本项目优惠券只支持满减与折扣两种类型。

优惠券类型,1:满减,2:折扣

如果满减:

1、折扣金额必须输入

2、折扣金额必须大于0的整数

如果是折扣:

1、折扣比例必须输入

2、折扣比例必须大于0,小于100的整数

发放时间开始时间不能小于当前时间

发放结束时间不能早于发放开始时间

2.1.2 查询优惠券活动

1)界面原型

登录运营端进入“优惠券管理”界面,如下图:

按条件查询优惠券活动信息。

在这里插入图片描述

在这里插入图片描述

2.2.3 修改优惠券活动

1) 界面原型

待生效的活动信息可以进行修改。

在这里插入图片描述

进入修改页面进行修改:

在这里插入图片描述

2)数据分析

参考新增优惠券。

3)数据校验

注意:只允许对待生效的的活动进行修改,且发放开始时间不能早于当前时间。

本项目优惠券只支持满减与折扣两种类型。

优惠券类型,1:满减,2:折扣

如果满减:

1、折扣金额必须输入

2、折扣金额必须大于0的整数

如果是折扣:

1、折扣比例必须输入

2、折扣比例必须大于0,小于100的整数

发放时间开始时间不能小于当前时间

发放结束时间不能早于发放开始时间

2.2.4 查询领取记录

1) 界面原型

进入优惠券活动查询界面,点击“领取记录”可查看用户领取优惠券的记录,如下图:

在这里插入图片描述

2)数据分析

1)发放数量 = 新增优惠券时指定的发放总数

2)领取数量 = 领取该优惠券的数量,领取数量<=发放数量

3)使用数量 = 用户领取优惠券后使用数量,使用数量<=领取数量

4)发放率= 领取数量/发放数量*100%;

5)使用率=使用数量/领取数量*100%;

6)用户手机号:领取优惠券的用户手机号

7)领取时间:领取优惠券的时间

8)使用时间:使用优惠券的时间

9)优惠券状态:待使用,已使用

10)使用订单:使用优惠券的订单号

显示规则:

1)列表内数据倒序进行展示;

2)发放率、使用率最多显示两位小数;

3)单页最多显示5条,没有分页,超过5条出滚动条,无限向下滚;

2.1.5 撤销活动

对于待生效及进行中的活动如果要进行终止可以执行撤销操作,执行后活动状态改为作废,用户已抢到还未使用的优惠券将作废。

1)界面原型

对于待生效及进行中的活动如果要进行终止可以执行撤销操作,执行后此活动将终止,用户已抢到还未使用的优惠券将作废。

点击【撤销】,出现【确认撤销】弹窗,如下:

在这里插入图片描述

撤销的活动可以选择发放状态:作废,进行查询

在这里插入图片描述

2)数据校验

只允许对待生效及进行中的活动进行撤销。

2.1.4 自动变更活动状态

状态变更的需求如下:

优惠券活动表的状态字段值包括:1:待生效,2:进行中,3:已失效 4:作废 几种,优惠券活动的初始状态是待生效,当到达优惠券发放时间状态将改为进行中,当到达结束时间状态改为已失效,当撤销活动后状态为作废。

状态变更不需要依赖人工操作,可由定时任务实现,每分钟更新一次状态:

1)对待生效的活动更新为进行中

到达发放开始时间状态改为“进行中”。

2)对待生效及进行中的活动更新为已失效

到达发放结束时间状态改为“已失效”

2.1.5 我的优惠券

1)界面原型

用户抢到优惠券后进入“我的”–>"我的优惠券"查询已抢到的优惠券,按抢券时间降序显示当前用户抢到的优惠券,

本查询为滚动查询,向上拖屏幕查询下一屏,一屏显示10条。

在这里插入图片描述

用户抢到优惠券有三个状态:

未使用:未过有效期的优惠券。

优惠券的有效期:从领取优惠券的时间加上优惠券的使用期限(“使用期限”在优惠券活动管理界面进行设置)。

已使用:已经在订单中使用的优惠券。

已过期:未使用且已过有效期的优惠券,已过期的优惠券将无法使用。

查询未使用的优惠券

在这里插入图片描述

查询已使用的优惠券:

在这里插入图片描述

查询已过期的优惠券:

在这里插入图片描述

2.3 运营端接口设计

优惠券活动管理模块涉及如下接口,请自行阅读接口文档完成功能开发。

2.3.1 新增优惠券活动

2.3.1.1 保存优惠券活动接口

接口名称:保存优惠券活动

接口功能:新增或修改一个优惠券活动信息,本接口支持新和修改。

接口地址:POST/market/operation/activity/save

请求数据类型: application/json

在这里插入图片描述

在这里插入图片描述

2.3.2 查询优惠券活动

2.3.2.1 分页查询优惠券活动接口

接口名称:分页查询优惠券活动

接口功能:运营端分页查询优惠券活动

接口地址:GET/market/operation/activity/page

请求数据类型: application/x-www-form-urlencoded

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.3.3 修改优惠券活动

2.3.3.1 查询优惠券活动详情接口

接口名称:查询优惠券活动详情

接口功能:进入修改页面首先调用此接口根据活动id查询优惠券活动详情在页面显示

接口地址:GET/market/operation/activity/{id}

请求数据类型: application/x-www-form-urlencoded

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.3.3.2 保存优惠券活动接口

修改优惠券活动信息后请求保存优惠券活动接口。

修改优惠券活动与新增优惠券活动调用同一个接口:保存优惠券活动接口,参考新增优惠券活动章节的描述。

2.3.4 查询领取记录

在查询领取记录页面共有两部分信息需要调用两个接口获取:优惠券活动信息,领取记录。

在这里插入图片描述

2.3.4.1 查询优惠券活动详情接口

接口名称:查询优惠券活动详情

接口功能:进入修改页面首先调用此接口根据活动id查询优惠券活动详情在页面显示

接口地址:GET/market/operation/activity/{id}

请求数据类型: application/x-www-form-urlencoded

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.3.4.2 查询领取记录

接口名称:根据活动ID查询优惠券领取记录

接口功能:根据活动ID查询优惠券领取记录

接口地址:GET/market/operation/coupon/page

请求数据类型: application/x-www-form-urlencoded

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.3.4 撤销活动

2.3.4.1 撤销活动接口

接口名称:撤销活动

接口功能:撤销一个优惠券活动,对于待生效及进行中的活动如果要进行终止可以执行撤销操作,执行后活动状态改为作废,用户已抢到还未使用的优惠券将作废。

接口地址:POST/market/operation/activity/revoke/{id}

请求数据类型: application/x-www-form-urlencoded

在这里插入图片描述

在这里插入图片描述

注意:本接口除了更新活动状态为作废,还需要将所有抢到本活动优惠券的状态为未使用的记录的状态更改为“已失效” 。

2.4 用户端接口设计

2.4.1 我的优惠券

2.4.1.1 我的优惠券列表接口

接口名称:我的优惠券列表

接口功能:用户查询自己领取的优惠券

接口地址:GET/market/consumer/coupon/my

请求数据类型: application/x-www-form-urlencoded

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.5 定时任务

2.5.1 活动状态变更定时任务

活动状态包括:1:待生效,2:进行中,3:已失效 4: 作废’

对于待生效的活动:到达发放开始时间状态改为“进行中”。

对于待生效及进行中的活动:到达发放结束时间状态改为“已失效”

使用xxl-job定义定时任务,每分钟执行一次。

2.5.2 已领取优惠券自动过期任务

用户领取的优惠券如果到达有效期仍然没有使用自动改为“已失效”

使用xxl-job定义定时任务,每小时执行一次。

3 实战代码

3.1 运营端接口设计

3.1.1 保存优惠券活动接口

3.1.1.1 controller

创建com.jzo2o.market.operation.admin.ActivityController

@RestController("adminActivityController")
@RequestMapping("/operation/activity")
@Api(tags = "优惠券活动相关接口")
public class ActivityController {
    @Resource
    private IActivityService activityService;

    /**
     * 保存优惠券活动接口
     * @param activitySaveReqDTO
     */
    @ApiOperation("保存优惠券活动接口")
    @PostMapping("/save")
    public void saveActivity(@RequestBody ActivitySaveReqDTO activitySaveReqDTO) {
        activityService.saveActivity(activitySaveReqDTO);
    }
}
3.1.1.2 service及实现
/**
 * 保存优惠券活动
 * @param activitySaveReqDTO
 */
void saveActivity(ActivitySaveReqDTO activitySaveReqDTO);

实现

@Override
public void saveActivity(ActivitySaveReqDTO activitySaveReqDTO) {
    Activity activity = new Activity();
    // 1. 校验参数
    if (activitySaveReqDTO.getId() != null) {
        //查询活动是否存在
        activity = getById(activitySaveReqDTO.getId());
        if (activity == null) {
            throw new BadRequestException("活动不存在");
        }
    }
    //1.1 优惠券类型
    Integer type = activitySaveReqDTO.getType();
    if (type.equals(1)) {
        //满减
        if (activitySaveReqDTO.getDiscountAmount() == null) {
            throw new BadRequestException("满减活动优惠金额不能为空");
        } else {
            //满减活动优惠金额必须是大于0的整数
            if (activitySaveReqDTO.getDiscountAmount().compareTo(BigDecimal.ZERO) <= 0) {
                throw new BadRequestException("满减活动优惠金额必须是大于0的整数");
            }
        }
    } else if (type.equals(2)) {
        //折扣
        if (activitySaveReqDTO.getDiscountRate() == null) {
            throw new BadRequestException("折扣活动折扣率不能为空");
        } else {
            //折扣活动折扣率必须是大于0小于100的整数
            if (activitySaveReqDTO.getDiscountRate() <= 0 || activitySaveReqDTO.getDiscountRate() >= 100) {
                throw new BadRequestException("折扣活动折扣率必须是大于0小于100的整数");
            }
        }
    } else {
        throw new BadRequestException("优惠券类型错误");
    }
    //1.2 发放时间
    LocalDateTime nowTime = LocalDateTime.now();
    LocalDateTime distributeStartTime = activitySaveReqDTO.getDistributeStartTime();
    LocalDateTime distributeEndTime = activitySaveReqDTO.getDistributeEndTime();
    //发放开始时间不能早于当前时间
    if (distributeStartTime.isBefore(nowTime)) {
        throw new BadRequestException("发放开始时间不能早于当前时间");
    }
    //发放结束时间不能早于当前时间
    if (distributeEndTime.isBefore(nowTime)) {
        throw new BadRequestException("发放结束时间不能早于当前时间");
    }
    //1.3 新增修改后的状态为:待生效;
    if (activitySaveReqDTO.getId() == null) {
        activity.setStatus(ActivityStatusEnum.NO_DISTRIBUTE.getStatus());
    }
    else {
        //到达发放开始时间状态改为“进行中”
        if (nowTime.isAfter(distributeStartTime)) {
            activity.setStatus(ActivityStatusEnum.DISTRIBUTING.getStatus());
        }
        //到达发放结束时间状态改为“已失效”
        if (nowTime.isAfter(distributeEndTime)) {
            activity.setStatus(ActivityStatusEnum.LOSE_EFFICACY.getStatus());
        }
        //撤销后状态为“作废”
        if(activity.getIsDeleted().equals(1)){
            activity.setStatus(ActivityStatusEnum.VOIDED.getStatus());
        }
    }
    // 2. 保存
    BeanUtil.copyProperties(activitySaveReqDTO, activity);
    owner.saveOrUpdate(activity);
}

因为saveOrUpdate(activity)是个事务方法,在非事务方法中使用事务方法,要将自己的代理对象注入

@Resource
private ActivityServiceImpl owner;
3.1.1.3 测试

启动前端project-xzb-pc-admin-vue3-java

启动foundation、gateway、public、market等微服务

在这里插入图片描述

输入如下活动

在这里插入图片描述

显示创建成功,查看数据库

在这里插入图片描述

3.1.2 分页查询优惠券活动接口

3.1.2.1 controller
/**
 * 分页查询优惠券活动接口
 *
 * @param activityQueryForPageReqDTO
 */
@ApiOperation("分页查询优惠券活动接口")
@GetMapping("/page")
public PageResult<ActivityInfoResDTO> pageQueryActivity(ActivityQueryForPageReqDTO activityQueryForPageReqDTO) {
    return activityService.pageQueryActivity(activityQueryForPageReqDTO);
}
3.1.2.2 service及其实现
/**
 * 分页查询优惠券活动
 * @param activityQueryForPageReqDTO
 */
PageResult<ActivityInfoResDTO> pageQueryActivity(ActivityQueryForPageReqDTO activityQueryForPageReqDTO);

实现

@Override
public PageResult<ActivityInfoResDTO> pageQueryActivity(ActivityQueryForPageReqDTO activityQueryForPageReqDTO) {
    Page<Activity> page=new Page<>(activityQueryForPageReqDTO.getPageNo(),activityQueryForPageReqDTO.getPageSize());
    LambdaQueryWrapper<Activity> queryWrapper = Wrappers.<Activity>lambdaQuery()
            .eq(ObjectUtils.isNotNull(activityQueryForPageReqDTO.getId()), Activity::getId, activityQueryForPageReqDTO.getId())
            .eq(ObjectUtils.isNotNull(activityQueryForPageReqDTO.getType()), Activity::getType, activityQueryForPageReqDTO.getType())
            .eq(ObjectUtils.isNotNull(activityQueryForPageReqDTO.getStatus()), Activity::getStatus, activityQueryForPageReqDTO.getStatus())
            .like(ObjectUtils.isNotNull(activityQueryForPageReqDTO.getName()), Activity::getName, activityQueryForPageReqDTO.getName());
    //查询
    this.page(page,queryWrapper);
    // 将查询结果转换为DTO列表
    List<ActivityInfoResDTO> activityInfoResDTOList = page.getRecords().stream()
            .map(activity ->BeanUtils.toBean(activity, ActivityInfoResDTO.class))
            .collect(Collectors.toList());
    PageResult pageResult = new PageResult();
    pageResult.setTotal(page.getTotal());
    pageResult.setList(activityInfoResDTOList);
    //返回分页结果
    return pageResult;
}
3.1.2.3 测试

测试成功

在这里插入图片描述

3.1.3 查询优惠券活动详情接口

3.1.3.1 controller
/**
 * 查询优惠券活动详情接口
 * @param id
 * @return
 */
@ApiOperation("查询优惠券活动详情接口")
@GetMapping("/{id}")
public ActivityInfoResDTO getActivityDetail(@PathVariable Long id) {
    return activityService.getActivityDetail(id);
}
3.1.3.2 service及其实现
/**
 * 查询优惠券活动详情
 * @param id
 * @return
 */
ActivityInfoResDTO getActivityDetail(Long id);

实现

@Override
public ActivityInfoResDTO getActivityDetail(Long id) {
    Activity activity = getById(id);
    if (activity == null) {
        throw new BadRequestException("活动不存在");
    }
    return BeanUtils.toBean(activity, ActivityInfoResDTO.class);
}
3.1.3.3 测试

尝试修改码农烧烤大派送变成码农洗脚大派送

在这里插入图片描述

在这里插入图片描述

测试成功

3.1.4 查询领取记录

3.1.4.1 controller

创建com.jzo2o.market.operation.admin.CouponController

@RestController("adminCouponController")
@RequestMapping("/operation/coupon")
@Api(tags = "运营端-优惠券相关接口")
public class CouponController {
    @Resource
    private ICouponService couponService;

    /**
     * 分页查询优惠券接口
     */
    @ApiOperation("分页查询优惠券接口")
    @GetMapping("/page")
    public PageResult<CouponInfoResDTO> pageQueryCoupon(CouponOperationPageQueryReqDTO couponOperationPageQueryReqDTO) {
        return couponService.pageQueryCoupon(couponOperationPageQueryReqDTO);
    }
}
3.1.4.2 service及其实现
public interface ICouponService extends IService<Coupon> {

    /**
     * 查询领取记录
     * @param couponOperationPageQueryReqDTO
     * @return
     */
    PageResult<CouponInfoResDTO> pageQueryCoupon(CouponOperationPageQueryReqDTO couponOperationPageQueryReqDTO);
}

实现

@Override
public PageResult<CouponInfoResDTO> pageQueryCoupon(CouponOperationPageQueryReqDTO couponOperationPageQueryReqDTO) {
    Page<Coupon> page = new Page<>(couponOperationPageQueryReqDTO.getPageNo(), couponOperationPageQueryReqDTO.getPageSize());
    LambdaQueryWrapper<Coupon> queryWrapper = new LambdaQueryWrapper<Coupon>()
            .eq(BeanUtils.isNotEmpty(couponOperationPageQueryReqDTO.getActivityId()), Coupon::getActivityId, couponOperationPageQueryReqDTO.getActivityId());
    this.page(page, queryWrapper);
    //查询结果返回DTO
    List<CouponInfoResDTO> couponInfoResDTOList = page.getRecords().stream()
            .map(coupon -> BeanUtils.toBean(coupon, CouponInfoResDTO.class))
            .collect(Collectors.toList());
    PageResult<CouponInfoResDTO> pageResult = new PageResult<>();
    pageResult.setTotal(page.getTotal());
    pageResult.setList(couponInfoResDTOList);
    return pageResult;
}
3.1.4.3 测试

在这里插入图片描述

3.1.5 撤销活动

3.1.5.1 controller
@ApiOperation("撤销优惠券活动接口")
@PostMapping("/revoke/{id}")
public void revokeActivity(@PathVariable Long id) {
    activityService.revokeActivity(id);
}
3.1.5.2 service及其实现
/**
 * 撤销优惠券活动
 * @param id
 */
void revokeActivity(Long id);

实现

@Override
@Transactional(rollbackFor = Exception.class)
public void revokeActivity(Long id) {
    Activity activity = getById(id);
    if (activity == null) {
        throw new BadRequestException("活动不存在");
    }
    //设置活动状态为作废
    activity.setStatus(ActivityStatusEnum.VOIDED.getStatus());
    //对应的优惠券状态更改为已失效
    couponService.update(Wrappers.<Coupon>lambdaUpdate()
            .eq(Coupon::getActivityId, id)
            .set(Coupon::getStatus, CouponStatusEnum.INVALID));
    return;
}

3.2 消费端接口设计

3.2.1 我的优惠券列表接口

3.2.1.1 controller

创建DTO,com.jzo2o.market.model.dto.request.MyCouponReqDTO

@Data
@ApiModel("我的优惠券查询模型")
public class MyCouponReqDTO {
    @ApiModelProperty(value = "优惠券状态",required = true)
    @Null(message = "请先选择优惠券状态")
    private Integer status;

    @ApiModelProperty(value = "上一次查询最后一张优惠券id",required = false)
    private Long id;
}

创建com.jzo2o.market.operation.consumer.CouponController

@RestController("consumerCouponController")
@RequestMapping("/consumer/coupon")
@Api(tags = "消费端-优惠券相关接口")
public class CouponController {
    @Resource
    private ICouponService couponService;

    @ApiOperation("我的优惠券列表接口")
    @GetMapping("/my")
    public CouponInfoResDTO myCoupon(MyCouponReqDTO myCouponReqDTO) {
        return couponService.myCoupon(myCouponReqDTO);
    }
}
3.2.1.2 service及其实现
/**
 * 领取优惠券
 * @param myCouponReqDTO
 */
CouponInfoResDTO myCoupon(MyCouponReqDTO myCouponReqDTO);

实现

@Override
public CouponInfoResDTO myCoupon(MyCouponReqDTO myCouponReqDTO) {
    Long UserId= UserContext.currentUserId();
    //查询用户领取的优惠券
    Coupon coupon = this.getOne(new LambdaQueryWrapper<Coupon>()
            .eq(Coupon::getUserId, UserId)
            .eq(Coupon::getStatus, myCouponReqDTO.getStatus()));
    return BeanUtils.toBean(coupon, CouponInfoResDTO.class);
}

3.3 定时任务

3.3.1 活动状态变更定时任务

3.3.1.1 Handler

在com.jzo2o.market.handler.XxlJobHandler中

@XxlJob("updateActivityStatus")
public void updateActivitySatus(){
    //待生效的活动
    List<Activity> notStartActivities = activityService.queryWithStatus(ActivityStatusEnum.NO_DISTRIBUTE);
    //进行中的活动
    List<Activity> distributingActivities = activityService.queryWithStatus(ActivityStatusEnum.DISTRIBUTING);

    updateActivity(notStartActivities, distributingActivities);
}

@Transactional(rollbackFor = Exception.class)
public void updateActivity(List<Activity> notStartActivities, List<Activity> distributingActivities) {
    LocalDateTime now = LocalDateTime.now();
    //对于待生效的活动:到达发放开始时间状态改为“进行中”。
    for (Activity activity : notStartActivities) {
        if (activity.getDistributeStartTime().isBefore(now)) {
            activity.setStatus(ActivityStatusEnum.DISTRIBUTING.getStatus());
        }
        if(activity.getDistributeEndTime().isBefore(now)){
            activity.setStatus(ActivityStatusEnum.LOSE_EFFICACY.getStatus());
        }
    }
    //对于待生效及进行中的活动:到达发放结束时间状态改为“已失效”
    for (Activity activity : distributingActivities) {
        if (activity.getDistributeEndTime().isBefore(now)) {
            activity.setStatus(ActivityStatusEnum.LOSE_EFFICACY.getStatus());
        }
    }
    activityService.updateBatchById(notStartActivities);
    activityService.updateBatchById(distributingActivities);
}
3.3.1.2 设置间隔

针对于updateActivityStatus,每60s运行一次

在这里插入图片描述

3.3.2 已领取优惠券自动过期任务

3.3.2.1 Handler
/**
 * 已领取优惠券自动过期任务
 */
@XxlJob("processExpireCoupon")
public void processExpireCoupon() {
    List<Coupon> coupons = couponService.queryAll();
    updateCoupon(coupons);
}

@Transactional(rollbackFor = Exception.class)
public void updateCoupon(List<Coupon> coupons) {
    LocalDateTime now = LocalDateTime.now();
    for (Coupon coupon : coupons) {
        if (coupon.getValidityTime().isBefore(now)) {
            coupon.setStatus(CouponStatusEnum.INVALID.getStatus());
        }
    }
    couponService.updateBatchById(coupons);
}
3.3.2.2 设置间隔

创建processExpireCoupon任务

在这里插入图片描述

3.3.2 测试

我们只需要测试一下有没有查询到待生效的活动就知道好着没,执行一次定时任务

在这里插入图片描述

拦截成功,说明定时任务设置成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bblb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值