Browse Source

1、增加人才生日发送邮件赠送积分
2、增加奖品放弃接口和超时自动放弃

rayson 6 months ago
parent
commit
5febf5db93
12 changed files with 181 additions and 21 deletions
  1. 8 0
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/app/luck/AppLuckLotteryRecordController.java
  2. 13 0
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/dal/mysql/luck/LuckLotteryRecordMapper.java
  3. 5 0
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/service/luck/LuckLotteryRecordService.java
  4. 46 0
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/service/luck/LuckLotteryRecordServiceImpl.java
  5. 1 0
      menduner/menduner-common/src/main/java/com/citu/module/menduner/common/enums/PointBizTypeEnum.java
  6. 4 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/person/PersonInfoDO.java
  7. 28 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/person/PersonInfoMapper.java
  8. 2 12
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/job/JobAdvertisedJob.java
  9. 66 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/job/PersonBirthdayJob.java
  10. 7 8
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/job/TradeOrderAutoCancelJob.java
  11. 0 1
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/mq/consumer/UserPointConsumer.java
  12. 1 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/person/info/PersonInfoService.java

+ 8 - 0
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/app/luck/AppLuckLotteryRecordController.java

@@ -64,6 +64,14 @@ public class AppLuckLotteryRecordController {
         return success(true);
     }
 
+    @PostMapping("/give-up")
+    @PreAuthenticated
+    @Operation(summary = "放弃领取奖品")
+    public CommonResult<Boolean> giveUp(@RequestParam("id") Long id) {
+        luckLotteryRecordService.giveUp(id);
+        return success(true);
+    }
+
     @GetMapping("/get/by-order-id")
     @PreAuthenticated
     @Operation(summary = "根据订单id获取中奖记录")

+ 13 - 0
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/dal/mysql/luck/LuckLotteryRecordMapper.java

@@ -8,6 +8,7 @@ import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryReco
 import com.citu.module.promotion.dal.dataobject.luck.LuckLotteryRecordDO;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.time.LocalDateTime;
 import java.util.List;
 
 /**
@@ -47,5 +48,17 @@ public interface LuckLotteryRecordMapper extends BaseMapperX<LuckLotteryRecordDO
         );
     }
 
+    /**
+     * 获取超过10天未领取奖品的抽奖记录
+     * 条件:未领取(isReceive=false)且创建时间超过10天
+     * @return 超过10天未领取的抽奖记录列表
+     */
+    default List<LuckLotteryRecordDO> selectUnclaimedRecordsOlderThan10Days() {
+        LocalDateTime tenDaysAgo = LocalDateTime.now().minusDays(10); // 10天前的时间
+        return selectList(new LambdaQueryWrapperX<LuckLotteryRecordDO>()
+                .eq(LuckLotteryRecordDO::getIsReceive, false) // 未领取
+                .lt(LuckLotteryRecordDO::getCreateTime, tenDaysAgo) // 创建时间超过10天
+        );
+    }
 
 }

+ 5 - 0
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/service/luck/LuckLotteryRecordService.java

@@ -98,6 +98,11 @@ public interface LuckLotteryRecordService {
      */
     void receive(AppLuckLotteryReceiveReqVO reqVO, Long userId);
 
+    /**
+     * 放弃领取奖品
+     */
+    void giveUp(Long id);
+
     /**
      * 获取最新的一条抽奖记录
      * @param lotteryId 抽奖活动id

+ 46 - 0
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/service/luck/LuckLotteryRecordServiceImpl.java

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.common.util.object.BeanUtils;
 import com.citu.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.citu.framework.tenant.core.job.TenantJob;
 import com.citu.module.menduner.system.api.user.MendunerUserApi;
 import com.citu.module.menduner.system.api.user.UserInfoRespDTO;
 import com.citu.module.promotion.api.luck.LuckRaffleReqDTO;
@@ -22,6 +23,8 @@ import com.citu.module.promotion.dal.dataobject.luck.LuckPrizeDO;
 import com.citu.module.promotion.dal.dataobject.luck.LuckUserTargetDO;
 import com.citu.module.promotion.dal.mysql.luck.LuckLotteryRecordMapper;
 import com.citu.module.promotion.dal.mysql.luck.LuckUserTargetMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
@@ -39,6 +42,7 @@ import static com.citu.module.promotion.enums.ErrorCodeConstants.LUCK_LOTTERY_RE
  * @author Rayson
  */
 @Service
+@Slf4j
 @Validated
 public class LuckLotteryRecordServiceImpl implements LuckLotteryRecordService {
 
@@ -308,6 +312,20 @@ public class LuckLotteryRecordServiceImpl implements LuckLotteryRecordService {
         }
     }
 
+    @Override
+    @DSTransactional
+    public void giveUp(Long id) {
+        LuckLotteryRecordDO record = luckLotteryRecordMapper.selectById(id);
+        if (null == record) {
+            return;
+        }
+
+        // 解冻数量
+        luckPrizeService.unfreeze(record.getPrizeId(), 1);
+        // 删除抽奖记录
+        luckLotteryRecordMapper.deleteById(record.getId());
+    }
+
     @Override
     public LuckLotteryRecordDetailRespVO getLast(Long lotteryId, Long userId) {
         LuckLotteryRecordDO record = luckLotteryRecordMapper.getLast(lotteryId, userId);
@@ -376,4 +394,32 @@ public class LuckLotteryRecordServiceImpl implements LuckLotteryRecordService {
 
         return resultMap;
     }
+
+
+    /**
+     * 处理超过10天未领取的抽奖记录
+     * 每10分钟检测一次,自动放弃未领取的记录
+     */
+    @TenantJob
+    @Scheduled(cron = "0 */10 * * * *") // 每10分钟执行一次
+    public void handleUnclaimedRecord() {
+        // 查询超过10天未领取的抽奖记录
+        List<LuckLotteryRecordDO> unclaimedRecords = luckLotteryRecordMapper.selectUnclaimedRecordsOlderThan10Days();
+        if (CollUtil.isEmpty(unclaimedRecords)) {
+            log.info("未找到超过10天未领取的抽奖记录");
+            return;
+        }
+
+        // 遍历未领取的记录,逐一放弃
+        for (LuckLotteryRecordDO record : unclaimedRecords) {
+            try {
+                log.info("开始处理未领取的记录,记录ID:{},用户ID:{},创建时间:{}",
+                        record.getId(), record.getUserId(), record.getCreateTime());
+                giveUp(record.getId()); // 放弃该记录
+                log.info("成功放弃记录,记录ID:{}", record.getId());
+            } catch (Exception e) {
+                log.error("放弃记录失败,记录ID:{},错误信息:{}", record.getId(), e.getMessage(), e);
+            }
+        }
+    }
 }

+ 1 - 0
menduner/menduner-common/src/main/java/com/citu/module/menduner/common/enums/PointBizTypeEnum.java

@@ -26,6 +26,7 @@ public enum PointBizTypeEnum {
     REDEEM(9, "积分兑换", "兑换,扣除 {} 积分", false),
     INVITE(10, "邀请注册", "邀请注册,获得 {} 积分", true),
     MEMBERSHIP(11, "购买会员套餐", "购买会员套餐,获取 {} 积分", true),
+    BIRTHDAY(12, "生日礼包", "生日礼包,获得 {} 积分", true),
     SIGN(98, "签到", "签到获得 {} 积分", true),
     EVENT(99, "事件跟踪", "[{}],{}{} 积分", true),
     RECOMMEND_TASK(100, "完成任务", "[{}],{}{} 积分", true),

+ 4 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/person/PersonInfoDO.java

@@ -67,6 +67,10 @@ public class PersonInfoDO extends TenantBaseDO {
      * 出生日期
      */
     private LocalDateTime birthday;
+    /**
+     * 出生日期礼包发放时间
+     */
+    private LocalDateTime birthdayGiftSendTime;
     /**
      * 婚姻状况(0未婚 1已婚 2离异 3暂不透露)
      */

+ 28 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/person/PersonInfoMapper.java

@@ -99,6 +99,34 @@ public interface PersonInfoMapper extends BaseMapperX<PersonInfoDO> {
         return selectOne(PersonInfoDO::getUserId, userId);
     }
 
+
+    /**
+     * 获取今天生日的用户数据
+     * birthday_update_time 时间在一年内的不获取
+     * 邮件不能为空、birthday_update_time可以为空
+     **/
+    default List<PersonInfoDO> getTodayBirthdayUserList() {
+        LocalDate today = LocalDate.now();
+        int month = today.getMonthValue(); // 获取当前月份
+        int day = today.getDayOfMonth();   // 获取当前日期
+        // 获取今年的第一天(1月1日)和明年的第一天(1月1日)
+        LocalDateTime firstDayOfYear = LocalDateTime.of(today.getYear(), 1, 1, 0, 0);
+        LocalDateTime firstDayOfNextYear = LocalDateTime.of(today.getYear() + 1, 1, 1, 0, 0);
+
+        return selectList(new LambdaQueryWrapperX<PersonInfoDO>()
+                .apply("MONTH(birthday) = {0} AND DAY(birthday) = {1}", month, day)  // 任意年的今天生日
+                .eq(PersonInfoDO::getUserId, 1L)
+                .isNotNull(PersonInfoDO::getEmail)  // 邮件不能为空
+                .and(wrapper -> wrapper
+                        .isNull(PersonInfoDO::getBirthdayGiftSendTime)  // 礼包发放时间为空
+                        .or()
+                        .lt(PersonInfoDO::getBirthdayGiftSendTime, firstDayOfYear)  // 礼包发放时间在今年之前
+                        .or()
+                        .ge(PersonInfoDO::getBirthdayGiftSendTime, firstDayOfNextYear)  // 礼包发放时间在明年及以后
+                )
+        );
+    }
+
     /**
      * 根据用户id和查询条件查询人才信息
      **/

+ 2 - 12
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/scheduled/JobAdvertisedScheduled.java → menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/job/JobAdvertisedJob.java

@@ -1,21 +1,11 @@
-package com.citu.module.menduner.system.scheduled;
+package com.citu.module.menduner.system.job;
 
-import cn.hutool.core.collection.CollUtil;
-import com.citu.framework.tenant.core.aop.TenantIgnore;
-import com.citu.module.menduner.system.dal.dataobject.interview.InterviewInviteDO;
-import com.citu.module.menduner.system.dal.dataobject.job.JobAdvertisedDO;
 import com.citu.module.menduner.system.dal.mysql.job.JobAdvertisedMapper;
-import com.citu.module.menduner.system.enums.interview.InterviewInviteStatusEnum;
-import com.citu.module.menduner.system.enums.job.JobStatusEnum;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.util.StopWatch;
 
 import javax.annotation.Resource;
-import java.util.List;
 
 /**
  * @author rayson
@@ -25,7 +15,7 @@ import java.util.List;
 @Slf4j
 @Configuration
 @RequiredArgsConstructor
-public class JobAdvertisedScheduled {
+public class JobAdvertisedJob {
 
     @Resource
     private JobAdvertisedMapper mapper;

+ 66 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/job/PersonBirthdayJob.java

@@ -0,0 +1,66 @@
+package com.citu.module.menduner.system.job;
+
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.citu.framework.tenant.core.job.TenantJob;
+import com.citu.module.menduner.common.enums.MathOperationEnum;
+import com.citu.module.menduner.common.enums.PointBizTypeEnum;
+import com.citu.module.menduner.system.dal.dataobject.person.PersonInfoDO;
+import com.citu.module.menduner.system.dal.mysql.person.PersonInfoMapper;
+import com.citu.module.menduner.system.service.record.UserAccountRecordService;
+import com.citu.module.menduner.system.util.MessageUtils;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.List;
+
+import static com.citu.module.menduner.common.CommonConstants.packBirthdayWish;
+
+/**
+ * 人才生日 Job
+ *
+ * @author Rayson
+ */
+@Component
+public class PersonBirthdayJob {
+
+    private static final Integer POINT = 500;
+    @Resource
+    private PersonInfoMapper mapper;
+    @Resource
+    private MessageUtils messageUtils;
+    @Resource
+    private UserAccountRecordService accountRecordService;
+
+    @TenantJob
+    // 每天早上8点
+    //    @Scheduled(cron = "0 0 8 * * *")
+    //    @Scheduled(cron = "*/5 * * * * *")
+    @XxlJob("personBirthdayJob")
+    public String execute() {
+        // 今日生日的用户
+        List<PersonInfoDO> list = mapper.getTodayBirthdayUserList();
+        for (PersonInfoDO person : list) {
+            // 修改时间
+            mapper.update(person, new LambdaUpdateWrapper<PersonInfoDO>()
+                    .eq(PersonInfoDO::getId, person.getId())
+                    .set(PersonInfoDO::getBirthdayGiftSendTime, LocalDateTime.now())
+            );
+            // 发送邮件
+            messageUtils.sendMail(packBirthdayWish(person.getEmail()));
+            // 加500积分
+            // 创建记录
+            accountRecordService.createPointRecord(
+                    person.getUserId(),
+                    null,
+                    PointBizTypeEnum.BIRTHDAY.getName(),
+                    MathOperationEnum.ADD,
+                    POINT,
+                    PointBizTypeEnum.BIRTHDAY,
+                    person.getUserId().toString()
+            );
+        }
+        return String.format("生日用户 %s 个", list.size());
+    }
+}

+ 7 - 8
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/scheduled/TradeOrderAutoCancelScheduled.java → menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/job/TradeOrderAutoCancelJob.java

@@ -1,9 +1,8 @@
-package com.citu.module.menduner.system.scheduled;
+package com.citu.module.menduner.system.job;
 
-import com.citu.framework.tenant.core.aop.TenantIgnore;
+import com.citu.framework.tenant.core.job.TenantJob;
 import com.citu.module.menduner.system.service.order.TradeOrderService;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.scheduling.annotation.Scheduled;
+import com.xxl.job.core.handler.annotation.XxlJob;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
@@ -14,14 +13,14 @@ import javax.annotation.Resource;
  * @author Rayson
  */
 @Component
-public class TradeOrderAutoCancelScheduled {
+public class TradeOrderAutoCancelJob {
 
     @Resource
     private TradeOrderService service;
 
-    @Async
-    @TenantIgnore
-    @Scheduled(cron = "*/5 * * * * *")
+    @TenantJob
+//    @Scheduled(cron = "*/5 * * * * *")
+    @XxlJob("tradeOrderAutoCancelJob")
     public String execute() {
         int count = service.cancelOrderBySystem();
         return String.format("过期订单 %s 个", count);

+ 0 - 1
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/mq/consumer/UserPointConsumer.java

@@ -1,6 +1,5 @@
 package com.citu.module.menduner.system.mq.consumer;
 
-import com.baomidou.dynamic.datasource.annotation.DSTransactional;
 import com.citu.module.menduner.common.enums.MathOperationEnum;
 import com.citu.module.menduner.common.enums.PointBizTypeEnum;
 import com.citu.module.menduner.common.message.UserPointSendMessage;

+ 1 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/person/info/PersonInfoService.java

@@ -75,6 +75,7 @@ public interface PersonInfoService {
      */
     Map<String, Object[]> getPersonCount(TimeRangeBaseReqVO reqVO);
 
+
     // ========== 求职端 ==========
 
     /**