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

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

  • 2 优惠券活动管理
    • 2.1 需求分析
      • 2.1.1 **新增优惠券活动**
        • 1)界面原型
        • 2)数据分析
        • 3)数据校验
      • 2.1.2 **查询优惠券活动**
        • 1)界面原型
      • 2.2.3 **修改优惠券活动**
        • 1) 界面原型
        • 2)数据分析
        • 3)数据校验
      • 2.2.4 查询**领取记录**
        • 1) 界面原型
        • 2)数据分析
      • 2.1.5 **撤销活动**
        • 1)界面原型
        • 2)数据校验
      • 2.1.4 自动变更活动状态
      • 2.1.5 我的优惠券
        • 1)界面原型
    • 2.3 运营端接口设计
      • 2.3.1 **新增优惠券活动**
        • 2.3.1.1 保存优惠券活动接口
      • 2.3.2 查询优惠券活动
        • 2.3.2.1 分页查询优惠券活动接口
      • 2.3.3 **修改优惠券活动**
        • 2.3.3.1 查询优惠券活动详情接口
        • 2.3.3.2 保存优惠券活动接口
      • 2.3.4 查询领取记录
        • 2.3.4.1 查询优惠券活动详情接口
        • 2.3.4.2 查询领取记录
      • 2.3.4 撤销活动
        • 2.3.4.1 撤销活动接口
    • 2.4 用户端接口设计
      • 2.4.1 我的优惠券
        • 2.4.1.1 我的优惠券列表接口
    • 2.5 定时任务
      • 2.5.1 活动状态变更定时任务
      • 2.5.2 已领取优惠券自动过期任务
  • 3 实战代码
    • 3.1 运营端接口设计
      • 3.1.1 保存优惠券活动接口
        • 3.1.1.1 controller
        • 3.1.1.2 service及实现
        • 3.1.1.3 测试
      • 3.1.2 分页查询优惠券活动接口
        • 3.1.2.1 controller
        • 3.1.2.2 service及其实现
        • 3.1.2.3 测试
      • 3.1.3 查询优惠券活动详情接口
        • 3.1.3.1 controller
        • 3.1.3.2 service及其实现
        • 3.1.3.3 测试
      • 3.1.4 查询领取记录
        • 3.1.4.1 controller
        • 3.1.4.2 service及其实现
        • 3.1.4.3 测试
      • 3.1.5 撤销活动
        • 3.1.5.1 controller
        • 3.1.5.2 service及其实现
    • 3.2 消费端接口设计
      • 3.2.1 我的优惠券列表接口
        • 3.2.1.1 controller
        • 3.2.1.2 service及其实现
    • 3.3 定时任务
      • 3.3.1 活动状态变更定时任务
        • 3.3.1.1 Handler
        • 3.3.1.2 设置间隔
      • 3.3.2 已领取优惠券自动过期任务
        • 3.3.2.1 Handler
        • 3.3.2.2 设置间隔
      • 3.3.2 测试


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 {@Resourceprivate 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 {@Resourceprivate 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);//查询结果返回DTOList<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 {@Resourceprivate 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 测试

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

在这里插入图片描述

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/450341.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt-窗口对话框QMessageBox的使用(51)

目录 前言 描述 使用 自定义按钮 简单方式创建 前言 Qt 提供了多种可复⽤的对话框类型&#xff0c;即 Qt 标准对话框。Qt 标准对话框全部继承于 QDialog类。常⽤标准对话框如下&#xff1a; 描述 消息对话框 QMessageBox 消息对话框是应⽤程序中最常⽤的界⾯元素。消息…

D3.js(五):实现组织架构图

实现组织架构图 效果初始化组织机构容器并实现缩放平移功能效果源码 渲染节点效果源码 渲染连线效果源码 完整源码 效果 初始化组织机构容器并实现缩放平移功能 效果 源码 import {useEffect} from react; import TreeData from ./json/tree-data.json;interface ITreeConfig…

crd介绍

在 Kubernetes 中&#xff0c;CRD&#xff08;Custom Resource Definition&#xff09;和 CR&#xff08;Custom Resource&#xff09;是用于扩展 Kubernetes 功能的机制。它们的关系和使用可以用一个完整案例来说明。 定义 CRD&#xff08;Custom Resource Definition&#x…

中后台 B 端产品设计

中后台 B 端产品设计 一、设计目标二、设计流程三、设计要点四、相关模块 叮嘟&#xff01;这里是小啊呜的学习课程资料整理。好记性不如烂笔头&#xff0c;今天也是努力进步的一天。一起加油进阶吧&#xff01; 中后台B端产品设计&#xff1a; 是指针对企业内部业务人员和管理…

python+appium+雷电模拟器安卓自动化及踩坑

一、环境安装 环境&#xff1a;window11 1.1 安装Android SDK AndroidDevTools - Android开发工具 Android SDK下载 Android Studio下载 Gradle下载 SDK Tools下载 这里面任选一个就可以&#xff0c;最终下载完主要要安装操作安卓的工具adb&#xff0c;安装这个步骤的前提是要…

Linux驱动开发——设备树

文章目录 1 什么是设备树&#xff1f;2 DTS、DTB和DTC3 DTS语法3.1 dtsi头文件3.2 设备节点3.3 标准属性3.4 根节点compatible属性3.5 向节点追加或修改内容 4 创建小型模板设备树5 设备树在系统中的体现6 绑定信息文档7 设备树常用OF操作函数7.1 查找节点的OF函数7.2 查找父/子…

【工具变量】上市公司当年是否发生财务重述指标整理Stata代码(2000-2023年)

计算说明&#xff1a;使用财务重述公告中所更正年报对应的年度作为财务重述的年度&#xff0c;若企业年报中发生财务重述取1&#xff0c;否则取0。本示例的财务重述是指上市公司对以前年度财务报表中的会计差错进行更正和披露&#xff0c;不包括股票拆分、股票红利、终止经营、…

Java 类和对象详解(上 )

个人主页&#xff1a; 鲤鱼王打挺-CSDN博客 Java专栏&#xff1a;https://blog.csdn.net/2401_83779763/category_12801101.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12801101&sharereferPC&sharesource2401_83779763&sharefromfrom_link &…

SwiftUI 如何取得 @Environment 中 @Observable 对象的绑定?

概述 从 SwiftUI 5.0&#xff08;iOS 17&#xff09;开始&#xff0c;苹果推出了全新的 Observation 框架。它作为下一代内容改变响应者全面参与到数据流和事件流的系统中。 有了 Observation 框架的加持&#xff0c;原本需要多种状态类型的 SwiftUI 视图现在只需要 3 种即可大…

R语言详解predict函数

R语言中predict函数在建立模型&#xff0c;研究关系时常用。但是不同type得到的结果常常被混为一谈&#xff0c;接下来&#xff0c;探讨predict得到的不同结果。 #数据 set.seed(123) n<-1000 age<-rnorm(n,mean50,sd10) gender<-rbinom(n,1,0.5) disease<-rbinom…

CDC变更数据捕捉技术是什么?和ETL有什么不同?

一、什么是CDC技术? 变更数据捕获&#xff08;Change Data Capture&#xff0c;简称 CDC&#xff09;是一种用于识别和跟踪数据源中发生变化的数据的技术。 工作原理&#xff1a; 1.监测数据源&#xff1a;CDC 工具会持续监测指定的数据源&#xff0c;如数据库表、文件系统…

【踩坑随笔】Tensorflow-GPU训练踩坑

一个无语的坑&#xff0c;4060单卡训练&#xff0c;8G内存本来就不够&#xff0c;还没开始训练就已经爆内存了&#xff0c;但是居然正常跑完了训练&#xff0c;然后一推理发现结果就是一坨。。。往回翻日志才发现原来中间有异常。 首先解决第一个问题&#xff1a;Could not lo…

k8s部署Kafka集群超详细讲解

准备部署环境 Kubernetes集群信息 NAMEVERSIONk8s-masterv1.29.2k8s-node01v1.29.2k8s-node02v1.29.2 Kafka&#xff1a;3.7.1版本&#xff0c;apche版本 Zookeeper&#xff1a;3.6.3版本 准备StorageClass # kubectl get sc NAME PROVISIONER RECLA…

音频文件处理 m4a 格式转为 wav 格式 - python 实现

在做音频算法开发时&#xff0c;有时获取的样本为 .m4a格式需要将其转为 .wav,方便之后的数据处理。 安装 python 库&#xff1a; pip install AudioSegment 代码实现具体如下&#xff1a; #-*-coding:utf-8-*- # date:2024-10 # Author: DataBall - XIAN # Function: 音频文件…

LIN从节点:波特率测试

文章目录 1、为什么需要测&#xff1f;2、如何实现测试&#xff1f;3、测试结果4、注意事项 1、为什么需要测&#xff1f; 调节波特率的变化&#xff0c;使主节点同步场位速率变化&#xff0c;验证从节点能否通过同步段进行调节自身位速率。对应ISO17987协议。 2、如何实现测…

锥线性规划【分布鲁棒、两阶段鲁棒方向知识点】

1 锥线性对偶理论 本部分看似和分布鲁棒、两阶段鲁棒优化没什么关系&#xff0c;但值得优先学习&#xff0c;原因将在最后揭晓。 二阶锥 二阶锥&#xff08;second-order cone&#xff0c;又称ice-cream/Lorentz cone&#xff09;的形式为&#xff1a; 非负象限锥 半正定锥 …

jmeter出参保存到文件,保存失败解决

1、添加JSON提取 2、添加beanshell FileWriter writer new FileWriter("C:/Users/xxx/Desktop/signUrl.csv", true); writer.write(vars.get("company_name")"\t"vars.get("signUrl")"\n"); writer.close(); 写文件的两个…

python的多线程和多进程

首先需要明确的是&#xff0c;多进程和其他语言的一样&#xff0c;能够利用多核cpu&#xff0c;但是python由于GIL的存在&#xff0c;多线程在执行的时候&#xff0c;实际上&#xff0c;每一时刻只有一个线程在执行。相当于是单线程。然而多线程在某些情况下&#xff0c;还是能…

Go-知识泛型

Go-知识泛型 1. 认识泛型1.1 不使用泛型1.2 使用泛型 2. 泛型的特点2.1 函数泛化2.2 类型泛化 3. 类型约束3.1 类型集合3.2 interface 类型集合3.2.1 内置interface类型集合3.2.2 自定义interface类型集合3.2.2.1 任意类型元素3.2.2.2 近似类型元素3.2.2.3 联合类型元素 3.2.3 …

Windows上安装Go并配置环境变量(图文步骤)

前言 1. 本文主要讲解的是在windows上安装Go语言的环境和配置环境变量&#xff1b; Go语言版本&#xff1a;1.23.2 Windows版本&#xff1a;win11&#xff08;win10通用&#xff09; 下载Go环境 下载go环境&#xff1a;Go下载官网链接(https://golang.google.cn/dl/) 等待…