Commit 9fa6ecb74222e26a177ea51e2b0ffd43e15c9cc1
1 parent
f0a8bead
派单增加到期前3小时短信提醒任务
Showing
5 changed files
with
346 additions
and
4 deletions
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/assigntasksinfo/AssignTasksInfoController.java
| @@ -16,6 +16,7 @@ import com.zteits.urbanops.module.garden.dal.dataobject.assigntasks.AssignTasksD | @@ -16,6 +16,7 @@ import com.zteits.urbanops.module.garden.dal.dataobject.assigntasks.AssignTasksD | ||
| 16 | import com.zteits.urbanops.module.garden.dal.dataobject.assigntasksinfo.AssignTasksInfoDO; | 16 | import com.zteits.urbanops.module.garden.dal.dataobject.assigntasksinfo.AssignTasksInfoDO; |
| 17 | import com.zteits.urbanops.module.garden.service.assigntasks.AssignTasksService; | 17 | import com.zteits.urbanops.module.garden.service.assigntasks.AssignTasksService; |
| 18 | import com.zteits.urbanops.module.garden.service.assigntasksinfo.AssignTasksInfoService; | 18 | import com.zteits.urbanops.module.garden.service.assigntasksinfo.AssignTasksInfoService; |
| 19 | +import com.zteits.urbanops.module.garden.service.assigntasksinfo.QuartzRemindService; | ||
| 19 | import com.zteits.urbanops.module.garden.service.unitintegraltotal.UnitIntegralService; | 20 | import com.zteits.urbanops.module.garden.service.unitintegraltotal.UnitIntegralService; |
| 20 | import io.swagger.v3.oas.annotations.Operation; | 21 | import io.swagger.v3.oas.annotations.Operation; |
| 21 | import io.swagger.v3.oas.annotations.Parameter; | 22 | import io.swagger.v3.oas.annotations.Parameter; |
| @@ -28,7 +29,10 @@ import org.springframework.validation.annotation.Validated; | @@ -28,7 +29,10 @@ import org.springframework.validation.annotation.Validated; | ||
| 28 | import org.springframework.web.bind.annotation.*; | 29 | import org.springframework.web.bind.annotation.*; |
| 29 | 30 | ||
| 30 | import java.io.IOException; | 31 | import java.io.IOException; |
| 32 | +import java.time.LocalDateTime; | ||
| 33 | +import java.time.ZoneId; | ||
| 31 | import java.util.ArrayList; | 34 | import java.util.ArrayList; |
| 35 | +import java.util.Date; | ||
| 32 | import java.util.List; | 36 | import java.util.List; |
| 33 | import java.util.stream.Collectors; | 37 | import java.util.stream.Collectors; |
| 34 | 38 | ||
| @@ -166,4 +170,26 @@ public class AssignTasksInfoController { | @@ -166,4 +170,26 @@ public class AssignTasksInfoController { | ||
| 166 | public CommonResult feedback(@RequestBody AssignTasksInfoUpdReqVO assignTaskCompany) { | 170 | public CommonResult feedback(@RequestBody AssignTasksInfoUpdReqVO assignTaskCompany) { |
| 167 | return success(assignTasksInfoService.feedbackAssignTaskCompany(assignTaskCompany)); | 171 | return success(assignTasksInfoService.feedbackAssignTaskCompany(assignTaskCompany)); |
| 168 | } | 172 | } |
| 173 | + | ||
| 174 | + | ||
| 175 | + @Resource | ||
| 176 | + private QuartzRemindService quartzRemindService; | ||
| 177 | + | ||
| 178 | + @Operation(summary = "到期提醒") | ||
| 179 | + @GetMapping(value = "/createDeadlineRemind") | ||
| 180 | + public void deadlineRemindTest(@RequestParam("id") Long id) { | ||
| 181 | + // 2. 注册Quartz任务:到期前3小时触发 | ||
| 182 | + try { | ||
| 183 | + LocalDateTime now = LocalDateTime.now(); | ||
| 184 | + LocalDateTime triggerTime = now.plusHours(3).plusMinutes(3); // 现在往后推3小时3分钟 | ||
| 185 | + Date triggerDate = Date.from( | ||
| 186 | + triggerTime.atZone(ZoneId.systemDefault()) // 绑定时区 | ||
| 187 | + .toInstant() // 转为Instant(含时区的时间戳) | ||
| 188 | + ); | ||
| 189 | + quartzRemindService.registerRemindJob(id, triggerDate); | ||
| 190 | + } catch (Exception e) { | ||
| 191 | + throw new RuntimeException("任务创建失败"); | ||
| 192 | + } | ||
| 193 | + } | ||
| 194 | + | ||
| 169 | } | 195 | } |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/job/task/ExpireRemindJob.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.job.task; | ||
| 2 | + | ||
| 3 | +import com.alibaba.fastjson.JSONObject; | ||
| 4 | +import com.baomidou.mybatisplus.core.toolkit.StringUtils; | ||
| 5 | +import com.zteits.urbanops.module.garden.dal.dataobject.assigntasksinfo.AssignTasksInfoDO; | ||
| 6 | +import com.zteits.urbanops.module.garden.enums.AssignTasksConstants; | ||
| 7 | +import com.zteits.urbanops.module.garden.service.assigntasksinfo.AssignTasksInfoService; | ||
| 8 | +import com.zteits.urbanops.module.garden.service.assigntasksinfo.QuartzRemindService; | ||
| 9 | +import com.zteits.urbanops.module.system.api.sms.SmsCodeApi; | ||
| 10 | +import com.zteits.urbanops.module.system.api.sms.dto.code.SmsCodeSendReqDTO; | ||
| 11 | +import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO; | ||
| 12 | +import jakarta.annotation.Resource; | ||
| 13 | +import org.quartz.Job; | ||
| 14 | +import org.quartz.JobExecutionContext; | ||
| 15 | +import org.quartz.JobExecutionException; | ||
| 16 | +import org.quartz.SchedulerException; | ||
| 17 | +import org.slf4j.Logger; | ||
| 18 | +import org.slf4j.LoggerFactory; | ||
| 19 | +import org.springframework.stereotype.Service; | ||
| 20 | + | ||
| 21 | +import java.time.LocalDateTime; | ||
| 22 | +import java.time.ZoneId; | ||
| 23 | +import java.time.format.DateTimeFormatter; | ||
| 24 | +import java.util.HashMap; | ||
| 25 | +import java.util.List; | ||
| 26 | +import java.util.Map; | ||
| 27 | +import java.util.Objects; | ||
| 28 | + | ||
| 29 | +import static com.zteits.urbanops.framework.common.util.servlet.ServletUtils.getClientIP; | ||
| 30 | +import static com.zteits.urbanops.module.garden.service.assigntasksinfo.AssignTasksInfoServiceImpl.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||
| 31 | + | ||
| 32 | +/** | ||
| 33 | + * @Classname ExpireRemindJob | ||
| 34 | + * @Description 任务到期提醒Job(Quartz一次性触发) | ||
| 35 | + * @Date 2026/3/9 19:27 | ||
| 36 | + * @Created by wangqian | ||
| 37 | + */ | ||
| 38 | +@Service | ||
| 39 | +public class ExpireRemindJob implements Job { | ||
| 40 | + private static final Logger log = LoggerFactory.getLogger(ExpireRemindJob.class); | ||
| 41 | + private static final DateTimeFormatter DEADLINE_FORMATTER = DateTimeFormatter | ||
| 42 | + .ofPattern(FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 43 | + .withZone(ZoneId.of("GMT+8")); // 时区与之前配置一致,避免偏移 | ||
| 44 | + @Resource | ||
| 45 | + private AssignTasksInfoService assignTasksInfoService; | ||
| 46 | + @Resource | ||
| 47 | + private QuartzRemindService quartzRemindService; | ||
| 48 | + | ||
| 49 | + @Resource | ||
| 50 | + private SmsCodeApi smsCodeApi; | ||
| 51 | + | ||
| 52 | + @Override | ||
| 53 | + public void execute(JobExecutionContext context) throws JobExecutionException { | ||
| 54 | + // 1. 从JobDataMap获取任务ID,增加空值校验和日志上下文 | ||
| 55 | + Long taskId = (Long) context.getMergedJobDataMap().get("taskId"); | ||
| 56 | + if (taskId == null) { | ||
| 57 | + log.error("【到期提醒Job】执行失败:任务ID为空"); | ||
| 58 | + return; | ||
| 59 | + } | ||
| 60 | + log.info("【到期提醒Job】开始执行,任务ID:{}", taskId); | ||
| 61 | + | ||
| 62 | + // 2. 统一封装任务移除逻辑,避免重复代码 | ||
| 63 | + try { | ||
| 64 | + // 2.1 查询任务信息,增加空指针和业务状态校验 | ||
| 65 | + AssignTasksInfoDO task = assignTasksInfoService.getAssignTasksInfo(taskId); | ||
| 66 | + if (task == null) { | ||
| 67 | + log.warn("【到期提醒Job】任务不存在,任务ID:{},执行移除触发器", taskId); | ||
| 68 | + removeRemindJobSafely(taskId); | ||
| 69 | + return; | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + // 2.2 任务已完成(finish=1),无需提醒,直接移除触发器 | ||
| 73 | + if (1 == task.getFinish()) { | ||
| 74 | + log.info("【到期提醒Job】任务已完成,无需提醒,任务ID:{},执行移除触发器", taskId); | ||
| 75 | + removeRemindJobSafely(taskId); | ||
| 76 | + return; | ||
| 77 | + } | ||
| 78 | + // 2.3 新增判断:到期时间距离当前时间小于3小时,无需提醒 | ||
| 79 | + LocalDateTime deadline = task.getDeadline(); | ||
| 80 | + LocalDateTime now = LocalDateTime.now(); | ||
| 81 | + // 计算当前时间到到期时间的时长(单位:小时) | ||
| 82 | + long hoursUntilDeadline = java.time.Duration.between(now, deadline).toHours(); | ||
| 83 | + // 核心判断:到期前不足3小时(包括已过期),不提醒 | ||
| 84 | + if (hoursUntilDeadline < 3) { | ||
| 85 | + log.info("【到期提醒Job】任务到期前不足3小时,无需提醒,任务ID:{},到期时间:{},当前时间:{}", | ||
| 86 | + taskId, deadline, now); | ||
| 87 | + removeRemindJobSafely(taskId); | ||
| 88 | + return; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + // 3. 核心提醒逻辑(示例:短信/站内信/邮件) | ||
| 92 | + //executeRemindLogic(task); | ||
| 93 | + | ||
| 94 | + // 4. 提醒成功后,更新任务状态+移除触发器(核心优化:成功也移除) | ||
| 95 | + updateTaskRemindStatus(taskId); | ||
| 96 | + removeRemindJobSafely(taskId); | ||
| 97 | + log.info("【到期提醒Job】执行成功,任务ID:{}", taskId); | ||
| 98 | + | ||
| 99 | + } catch (Exception e) { | ||
| 100 | + // 5. 全局异常捕获,保证Job不中断,记录详细日志+尝试移除触发器 | ||
| 101 | + log.error("【到期提醒Job】执行异常,任务ID:{}", taskId, e); | ||
| 102 | + removeRemindJobSafely(taskId); | ||
| 103 | + // 可选:抛出异常让Quartz标记Job执行失败(根据业务需求决定) | ||
| 104 | + // throw new JobExecutionException("到期提醒任务执行失败", e, false); | ||
| 105 | + } | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + /** | ||
| 109 | + * 执行具体的提醒逻辑(解耦核心业务,便于维护) | ||
| 110 | + * @param task 任务信息 | ||
| 111 | + */ | ||
| 112 | + private void executeRemindLogic(AssignTasksInfoDO task) { | ||
| 113 | + String taskName = task.getTaskName(); | ||
| 114 | + LocalDateTime deadline = task.getDeadline(); | ||
| 115 | + String formattedDeadline = Objects.nonNull(deadline) | ||
| 116 | + ? DEADLINE_FORMATTER.format(deadline) | ||
| 117 | + : ""; // 或 null | ||
| 118 | + String remindContent = String.format("任务【%s】即将到期,到期时间:%s,请及时处理", taskName, deadline); | ||
| 119 | + | ||
| 120 | + List<AdminUserRespDTO> matchUserList = assignTasksInfoService.getUsersByCompanyId(task.getCompanyId()); | ||
| 121 | + Map<String, Object> templateParams = new HashMap<String, Object>(); | ||
| 122 | + templateParams.put("companyName", task.getCompanyName()); | ||
| 123 | + templateParams.put("taskName", task.getTaskName()); | ||
| 124 | + templateParams.put("deadline", formattedDeadline); | ||
| 125 | + // 5. 发送短信通知 | ||
| 126 | + log.info("【到期提醒逻辑】发送短信 signMap: {}", JSONObject.toJSONString(templateParams)); | ||
| 127 | + Boolean sendFlag = false; | ||
| 128 | + for (AdminUserRespDTO adminUserRespDTO : matchUserList) { | ||
| 129 | + String phonenumber = adminUserRespDTO.getMobile(); | ||
| 130 | + if (StringUtils.isEmpty(phonenumber)) { | ||
| 131 | + continue; | ||
| 132 | + } | ||
| 133 | + SmsCodeSendReqDTO reqDTO = new SmsCodeSendReqDTO(); | ||
| 134 | + reqDTO.setScene(AssignTasksConstants.ASSIGN_TASK_SCENE); | ||
| 135 | + reqDTO.setMobile(phonenumber);//手机号 | ||
| 136 | + reqDTO.setTemplateParams(templateParams);//短信参数 | ||
| 137 | + reqDTO.setCreateIp(getClientIP()); | ||
| 138 | + //smsCodeApi.openSendSmsCode(reqDTO); | ||
| 139 | + log.info("提交单位任务成功,已通知填报人:手机号:{},任务ID={}", phonenumber, task.getId()); | ||
| 140 | + sendFlag = true; | ||
| 141 | + } | ||
| 142 | + log.info("【到期提醒逻辑】执行提醒,任务名称:{},到期时间:{},提醒内容:{}", taskName, deadline, remindContent); | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + /** | ||
| 146 | + * 更新任务提醒状态(解耦状态更新逻辑,便于扩展) | ||
| 147 | + * @param taskId 任务ID | ||
| 148 | + */ | ||
| 149 | + private void updateTaskRemindStatus(Long taskId) { | ||
| 150 | + try { | ||
| 151 | + // 实际业务:更新数据库中任务的提醒状态(如remind_status=1 表示已提醒) | ||
| 152 | + //assignTasksInfoService.updateRemindStatus(taskId, 1); | ||
| 153 | + log.debug("【到期提醒Job】更新任务提醒状态成功,任务ID:{}", taskId); | ||
| 154 | + } catch (Exception e) { | ||
| 155 | + // 状态更新失败单独捕获,不影响触发器移除 | ||
| 156 | + log.error("【到期提醒Job】更新任务提醒状态失败,任务ID:{}", taskId, e); | ||
| 157 | + } | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + /** | ||
| 161 | + * 安全移除提醒任务(封装移除逻辑,避免重复try-catch,保证移除操作不抛异常) | ||
| 162 | + * @param taskId 任务ID | ||
| 163 | + */ | ||
| 164 | + private void removeRemindJobSafely(Long taskId) { | ||
| 165 | + if (taskId == null) { | ||
| 166 | + return; | ||
| 167 | + } | ||
| 168 | + try { | ||
| 169 | + quartzRemindService.removeRemindJob(taskId); | ||
| 170 | + log.debug("【到期提醒Job】移除触发器成功,任务ID:{}", taskId); | ||
| 171 | + } catch (SchedulerException e) { | ||
| 172 | + // 移除失败仅记录日志,不中断主流程 | ||
| 173 | + log.error("【到期提醒Job】移除触发器失败,任务ID:{}", taskId, e); | ||
| 174 | + } | ||
| 175 | + } | ||
| 176 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/assigntasksinfo/AssignTasksInfoService.java
| @@ -6,6 +6,7 @@ import com.zteits.urbanops.module.garden.controller.admin.assigntasksinfo.vo.Ass | @@ -6,6 +6,7 @@ import com.zteits.urbanops.module.garden.controller.admin.assigntasksinfo.vo.Ass | ||
| 6 | import com.zteits.urbanops.module.garden.controller.admin.assigntasksinfo.vo.AssignTasksInfoUpdReqVO; | 6 | import com.zteits.urbanops.module.garden.controller.admin.assigntasksinfo.vo.AssignTasksInfoUpdReqVO; |
| 7 | import com.zteits.urbanops.module.garden.dal.dataobject.assigntasks.AssignTasksDO; | 7 | import com.zteits.urbanops.module.garden.dal.dataobject.assigntasks.AssignTasksDO; |
| 8 | import com.zteits.urbanops.module.garden.dal.dataobject.assigntasksinfo.AssignTasksInfoDO; | 8 | import com.zteits.urbanops.module.garden.dal.dataobject.assigntasksinfo.AssignTasksInfoDO; |
| 9 | +import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO; | ||
| 9 | import jakarta.validation.Valid; | 10 | import jakarta.validation.Valid; |
| 10 | 11 | ||
| 11 | import java.util.List; | 12 | import java.util.List; |
| @@ -102,4 +103,12 @@ public interface AssignTasksInfoService { | @@ -102,4 +103,12 @@ public interface AssignTasksInfoService { | ||
| 102 | * @Return int | 103 | * @Return int |
| 103 | */ | 104 | */ |
| 104 | public int feedbackAssignTaskCompany(@Valid AssignTasksInfoUpdReqVO tdAssignTaskCompany); | 105 | public int feedbackAssignTaskCompany(@Valid AssignTasksInfoUpdReqVO tdAssignTaskCompany); |
| 106 | + | ||
| 107 | + /** | ||
| 108 | + * @Author wangqian | ||
| 109 | + * @Description 根据单位获取单位管理员 | ||
| 110 | + * @Date 2026/3/9 20:45 | ||
| 111 | + * @Param companyId | ||
| 112 | + */ | ||
| 113 | + List<AdminUserRespDTO> getUsersByCompanyId(Long companyId); | ||
| 105 | } | 114 | } |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/assigntasksinfo/AssignTasksInfoServiceImpl.java
| @@ -25,6 +25,7 @@ import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO; | @@ -25,6 +25,7 @@ import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO; | ||
| 25 | import jakarta.annotation.Resource; | 25 | import jakarta.annotation.Resource; |
| 26 | import lombok.extern.slf4j.Slf4j; | 26 | import lombok.extern.slf4j.Slf4j; |
| 27 | import org.apache.commons.collections4.CollectionUtils; | 27 | import org.apache.commons.collections4.CollectionUtils; |
| 28 | +import org.quartz.SchedulerException; | ||
| 28 | import org.springframework.stereotype.Service; | 29 | import org.springframework.stereotype.Service; |
| 29 | import org.springframework.transaction.annotation.Transactional; | 30 | import org.springframework.transaction.annotation.Transactional; |
| 30 | import org.springframework.validation.annotation.Validated; | 31 | import org.springframework.validation.annotation.Validated; |
| @@ -33,10 +34,7 @@ import java.time.LocalDateTime; | @@ -33,10 +34,7 @@ import java.time.LocalDateTime; | ||
| 33 | import java.time.ZoneId; | 34 | import java.time.ZoneId; |
| 34 | import java.time.format.DateTimeFormatter; | 35 | import java.time.format.DateTimeFormatter; |
| 35 | import java.time.temporal.ChronoUnit; | 36 | import java.time.temporal.ChronoUnit; |
| 36 | -import java.util.HashMap; | ||
| 37 | -import java.util.List; | ||
| 38 | -import java.util.Map; | ||
| 39 | -import java.util.Objects; | 37 | +import java.util.*; |
| 40 | import java.util.stream.Collectors; | 38 | import java.util.stream.Collectors; |
| 41 | 39 | ||
| 42 | import static com.zteits.urbanops.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; | 40 | import static com.zteits.urbanops.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; |
| @@ -76,6 +74,9 @@ public class AssignTasksInfoServiceImpl implements AssignTasksInfoService { | @@ -76,6 +74,9 @@ public class AssignTasksInfoServiceImpl implements AssignTasksInfoService { | ||
| 76 | @Resource | 74 | @Resource |
| 77 | private UnitIntegralService unitIntegralService; | 75 | private UnitIntegralService unitIntegralService; |
| 78 | 76 | ||
| 77 | + @Resource | ||
| 78 | + private QuartzRemindService quartzRemindService; | ||
| 79 | + | ||
| 79 | // 时间格式常量(与之前保持一致) | 80 | // 时间格式常量(与之前保持一致) |
| 80 | public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss"; | 81 | public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss"; |
| 81 | 82 | ||
| @@ -169,6 +170,16 @@ public class AssignTasksInfoServiceImpl implements AssignTasksInfoService { | @@ -169,6 +170,16 @@ public class AssignTasksInfoServiceImpl implements AssignTasksInfoService { | ||
| 169 | assignTasksInfoMapper.insert(assignTaskInfo); | 170 | assignTasksInfoMapper.insert(assignTaskInfo); |
| 170 | // add by 20260307 初始化单位积分 | 171 | // add by 20260307 初始化单位积分 |
| 171 | unitIntegralService.createUnitIntegral(CommonConstants.UNIT_INTEGRAL_UNIT_TYPE_01, String.valueOf(companyId), assignTaskInfo.getCompanyName()); | 172 | unitIntegralService.createUnitIntegral(CommonConstants.UNIT_INTEGRAL_UNIT_TYPE_01, String.valueOf(companyId), assignTaskInfo.getCompanyName()); |
| 173 | + try { | ||
| 174 | + //保存成功后创建定时器,3小时执行 | ||
| 175 | + Date triggerDate = Date.from( | ||
| 176 | + assignTasks.getDeadline().atZone(ZoneId.systemDefault()) // 绑定时区 | ||
| 177 | + .toInstant() // 转为Instant(含时区的时间戳) | ||
| 178 | + ); | ||
| 179 | + quartzRemindService.registerRemindJob(assignTaskInfo.getId(), triggerDate); | ||
| 180 | + } catch (SchedulerException exception) { | ||
| 181 | + throw exception0(BAD_REQUEST.getCode(),"创建到期定时提醒异常"); | ||
| 182 | + } | ||
| 172 | } | 183 | } |
| 173 | } | 184 | } |
| 174 | } | 185 | } |
| @@ -330,6 +341,36 @@ public class AssignTasksInfoServiceImpl implements AssignTasksInfoService { | @@ -330,6 +341,36 @@ public class AssignTasksInfoServiceImpl implements AssignTasksInfoService { | ||
| 330 | throw exception(ASSIGN_TASKS_INFO_NOT_EXISTS); | 341 | throw exception(ASSIGN_TASKS_INFO_NOT_EXISTS); |
| 331 | } | 342 | } |
| 332 | } | 343 | } |
| 344 | + | ||
| 345 | + @Override | ||
| 346 | + public List<AdminUserRespDTO> getUsersByCompanyId(Long companyId) { | ||
| 347 | + //用户角色 | ||
| 348 | + List<Long> userIds = roleApi.getUserIdsByRoleCode(AssignTasksConstants.ASSIGN_ROLE_KEY); | ||
| 349 | + if (CollectionUtils.isEmpty(userIds)) { | ||
| 350 | + //未配置 | ||
| 351 | + throw exception0(BAD_REQUEST.getCode(),"未配置子公司管理员角色"); | ||
| 352 | + } | ||
| 353 | + //填报人信息 | ||
| 354 | + List<AdminUserRespDTO> users = adminUserApi.getUserList(userIds); | ||
| 355 | + if(CollectionUtils.isEmpty(users)) { | ||
| 356 | + //没有权限 | ||
| 357 | + throw exception0(BAD_REQUEST.getCode(),"未配置分公司管理员"); | ||
| 358 | + } | ||
| 359 | + | ||
| 360 | + // 收集所有匹配companyId的用户,无匹配则返回空集合(而非null) | ||
| 361 | + List<AdminUserRespDTO> matchUserList = users.stream() | ||
| 362 | + .filter(user -> { | ||
| 363 | + // 防御性判空:过滤掉null用户或deptId为空的用户 | ||
| 364 | + if (user == null || user.getDeptId() == null) { | ||
| 365 | + return false; | ||
| 366 | + } | ||
| 367 | + // 安全比较companyId和deptId(兼容null) | ||
| 368 | + return Objects.equals(companyId, user.getDeptId()); | ||
| 369 | + }) | ||
| 370 | + .collect(Collectors.toList()); | ||
| 371 | + return matchUserList; | ||
| 372 | + } | ||
| 373 | + | ||
| 333 | /** | 374 | /** |
| 334 | * @Author wangqian | 375 | * @Author wangqian |
| 335 | * @Description 获取单位当前积分 | 376 | * @Description 获取单位当前积分 |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/assigntasksinfo/QuartzRemindService.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.service.assigntasksinfo; | ||
| 2 | + | ||
| 3 | +import com.zteits.urbanops.module.garden.job.task.ExpireRemindJob; | ||
| 4 | +import lombok.extern.slf4j.Slf4j; | ||
| 5 | +import org.quartz.*; | ||
| 6 | +import org.quartz.impl.matchers.GroupMatcher; | ||
| 7 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 8 | +import org.springframework.stereotype.Service; | ||
| 9 | + | ||
| 10 | +import java.text.SimpleDateFormat; | ||
| 11 | +import java.util.Date; | ||
| 12 | +import java.util.Set; | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * 动态注册到期提醒Quartz任务的服务 | ||
| 16 | + */ | ||
| 17 | +@Service | ||
| 18 | +@Slf4j | ||
| 19 | +public class QuartzRemindService { | ||
| 20 | + // 任务组名(自定义,便于管理) | ||
| 21 | + private static final String REMIND_JOB_GROUP = "EXPIRE_REMIND_GROUP"; | ||
| 22 | + | ||
| 23 | + @Autowired | ||
| 24 | + private Scheduler scheduler; | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 动态注册“到期前3小时提醒”任务 | ||
| 28 | + * | ||
| 29 | + * @param jobId 待提醒的任务信息 | ||
| 30 | + * @throws SchedulerException 调度器异常 | ||
| 31 | + */ | ||
| 32 | + public void registerRemindJob(Long jobId, Date expireTime) throws SchedulerException { | ||
| 33 | + // 1. 校验参数 | ||
| 34 | + if (jobId == null || expireTime == null) { | ||
| 35 | + throw new IllegalArgumentException("任务信息不完整,无法注册提醒"); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + // 2. 计算触发时间:到期时间 - 3小时 | ||
| 39 | + Date triggerTime = new Date(expireTime.getTime() - 3 * 60 * 60 * 1000L); | ||
| 40 | + | ||
| 41 | + // 3. 定义JobKey(唯一标识:任务ID + 组名) | ||
| 42 | + JobKey jobKey = new JobKey("REMIND_JOB_" + jobId, REMIND_JOB_GROUP); | ||
| 43 | + | ||
| 44 | + // 4. 检查任务是否已存在,存在则先删除 | ||
| 45 | + if (scheduler.checkExists(jobKey)) { | ||
| 46 | + scheduler.deleteJob(jobKey); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + // 5. 构建JobDetail(绑定自定义的ExpireRemindJob) | ||
| 50 | + JobDetail jobDetail = JobBuilder.newJob(ExpireRemindJob.class).withIdentity(jobKey) | ||
| 51 | + // 传递参数(任务ID)到Job中 | ||
| 52 | + .usingJobData("taskId", jobId).storeDurably(false).build(); | ||
| 53 | + | ||
| 54 | + // 6. 构建Trigger(一次性触发,触发时间为计算的“到期前3小时”) | ||
| 55 | + Trigger trigger = TriggerBuilder.newTrigger() | ||
| 56 | + .withIdentity("REMIND_TRIGGER_" + jobId, REMIND_JOB_GROUP) | ||
| 57 | + .startAt(triggerTime) | ||
| 58 | + // 只触发一次(到期提醒只需一次) | ||
| 59 | + .withSchedule(SimpleScheduleBuilder.simpleSchedule().withMisfireHandlingInstructionFireNow()).build(); | ||
| 60 | + | ||
| 61 | + // 7. 注册任务到调度器 | ||
| 62 | + scheduler.scheduleJob(jobDetail, trigger); | ||
| 63 | + SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
| 64 | + log.info("【动态注册到期提醒任务成功】任务ID:{},触发时间:{}", jobId, sf.format(triggerTime)); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + /** | ||
| 68 | + * 移除指定的提醒任务 | ||
| 69 | + * | ||
| 70 | + * @param taskId 任务ID | ||
| 71 | + * @throws SchedulerException 调度器异常 | ||
| 72 | + */ | ||
| 73 | + public void removeRemindJob(Long taskId) throws SchedulerException { | ||
| 74 | + JobKey jobKey = new JobKey("REMIND_JOB_" + taskId, REMIND_JOB_GROUP); | ||
| 75 | + if (scheduler.checkExists(jobKey)) { | ||
| 76 | + scheduler.deleteJob(jobKey); | ||
| 77 | + log.info("【移除到期提醒任务成功】任务ID:{}", taskId); | ||
| 78 | + } | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + /** | ||
| 82 | + * 查看所有已注册的提醒任务 | ||
| 83 | + * | ||
| 84 | + * @return 任务Key集合 | ||
| 85 | + * @throws SchedulerException 调度器异常 | ||
| 86 | + */ | ||
| 87 | + public Set<JobKey> listAllRemindJobs() throws SchedulerException { | ||
| 88 | + return scheduler.getJobKeys(GroupMatcher.jobGroupEquals(REMIND_JOB_GROUP)); | ||
| 89 | + } | ||
| 90 | +} |