Commit c76d95425c24f7869ed72450ceb14b6245bd070b

Authored by 王富生
2 parents 100cd3bc d845e6f7

Merge remote-tracking branch 'origin/dev' into dev

urbanops-framework/urbanops-common/src/main/java/com/zteits/urbanops/framework/common/util/date/DateUtils.java
... ... @@ -3,6 +3,7 @@ package com.zteits.urbanops.framework.common.util.date;
3 3 import cn.hutool.core.date.LocalDateTimeUtil;
4 4  
5 5 import java.time.*;
  6 +import java.time.format.DateTimeFormatter;
6 7 import java.util.Calendar;
7 8 import java.util.Date;
8 9  
... ... @@ -18,6 +19,9 @@ public class DateUtils {
18 19 */
19 20 public static final String TIME_ZONE_DEFAULT = "GMT+8";
20 21  
  22 + public static final ZoneId DEFAULT_ZONE = ZoneId.of("GMT+8"); // 东八区
  23 +
  24 +
21 25 /**
22 26 * 秒转换成毫秒
23 27 */
... ... @@ -27,6 +31,9 @@ public class DateUtils {
27 31  
28 32 public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";
29 33  
  34 + public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
  35 +
  36 +
30 37 /**
31 38 * 将 LocalDateTime 转换成 Date
32 39 *
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/assigntasks/vo/AssignTasksSaveReqVO.java
... ... @@ -47,7 +47,8 @@ public class AssignTasksSaveReqVO {
47 47 pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND,
48 48 timezone = "GMT+8",
49 49 shape = JsonFormat.Shape.STRING
50   - ) private Date finishTime;
  50 + )
  51 + private Date finishTime;
51 52  
52 53 @Schema(description = "任务备注(如:特殊要求、注意事项等)")
53 54 private String note;
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/assigntasks/AssignTasksServiceImpl.java
... ... @@ -3,6 +3,7 @@ package com.zteits.urbanops.module.garden.service.assigntasks;
3 3 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 4 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
5 5 import com.zteits.urbanops.framework.common.pojo.PageResult;
  6 +import com.zteits.urbanops.framework.common.util.date.DateUtils;
6 7 import com.zteits.urbanops.framework.common.util.object.BeanUtils;
7 8 import com.zteits.urbanops.framework.security.core.util.SecurityFrameworkUtils;
8 9 import com.zteits.urbanops.module.bpm.api.task.BpmProcessInstanceApi;
... ... @@ -15,11 +16,14 @@ import com.zteits.urbanops.module.garden.dal.mysql.assigntasks.AssignTasksMapper
15 16 import com.zteits.urbanops.module.garden.dal.mysql.assigntasksinfo.AssignTasksInfoMapper;
16 17 import com.zteits.urbanops.module.garden.enums.AssignTasksConstants;
17 18 import com.zteits.urbanops.module.garden.service.assigntasksinfo.AssignTasksInfoService;
  19 +import com.zteits.urbanops.module.garden.service.assigntasksinfo.QuartzRemindService;
  20 +import com.zteits.urbanops.module.garden.service.unitintegraltotal.UnitIntegralService;
18 21 import com.zteits.urbanops.module.system.api.permission.RoleApi;
19 22 import com.zteits.urbanops.module.system.api.user.AdminUserApi;
20 23 import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO;
21 24 import jakarta.annotation.Resource;
22 25 import lombok.extern.slf4j.Slf4j;
  26 +import org.quartz.SchedulerException;
23 27 import org.springframework.stereotype.Service;
24 28 import org.springframework.transaction.annotation.Transactional;
25 29 import org.springframework.util.CollectionUtils;
... ... @@ -68,6 +72,10 @@ public class AssignTasksServiceImpl implements AssignTasksService {
68 72  
69 73 @Resource
70 74 private BpmProcessInstanceApi processInstanceApi;
  75 + @Resource
  76 + private UnitIntegralService unitIntegralService;
  77 + @Resource
  78 + private QuartzRemindService quartzRemindService;
71 79  
72 80 @Transactional(rollbackFor = Exception.class)
73 81 @Override
... ... @@ -125,8 +133,21 @@ public class AssignTasksServiceImpl implements AssignTasksService {
125 133 //修改派单信息
126 134 taskInfo.setTaskName(updateReqVO.getTaskName());
127 135 taskInfo.setTaskType(updateReqVO.getTaskType());
128   - taskInfo.setDeadline(updateReqVO.getDeadline().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
  136 + // 核心转换逻辑
  137 + Date deadlineDate = updateReqVO.getDeadline();
  138 + // 空值判断 + Date转LocalDateTime(绑定东八区,避免时区偏差)
  139 + LocalDateTime deadlineLdt = deadlineDate != null
  140 + ? deadlineDate.toInstant().atZone(DateUtils.DEFAULT_ZONE).toLocalDateTime()
  141 + : null;
  142 + taskInfo.setDeadline(deadlineLdt);
129 143 assignTasksInfoMapper.updateById(taskInfo);
  144 + try {
  145 + //删除定时提醒
  146 + quartzRemindService.removeRemindJob(taskInfo.getId());
  147 + assignTasksInfoService.createRemindJob(taskInfo.getDeadline(), taskInfo.getId());
  148 + } catch (SchedulerException exception) {
  149 + throw exception0(BAD_REQUEST.getCode(),"创建到期定时提醒异常");
  150 + }
130 151 }
131 152 }
132 153 }
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/assigntasksinfo/AssignTasksInfoService.java
... ... @@ -9,6 +9,7 @@ import com.zteits.urbanops.module.garden.dal.dataobject.assigntasksinfo.AssignTa
9 9 import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO;
10 10 import jakarta.validation.Valid;
11 11  
  12 +import java.time.LocalDateTime;
12 13 import java.util.List;
13 14  
14 15 /**
... ... @@ -111,4 +112,13 @@ public interface AssignTasksInfoService {
111 112 * @Param companyId
112 113 */
113 114 List<AdminUserRespDTO> getUsersByCompanyId(Long companyId);
  115 + /**
  116 + * @Author wangqian
  117 + * @Description 创建到期提醒定时器
  118 + * @Date 2026/3/12 20:51
  119 + * @Param deadline
  120 + * @param id
  121 + * @Return void
  122 + */
  123 + public void createRemindJob(LocalDateTime deadline, Long id);
114 124 }
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/assigntasksinfo/AssignTasksInfoServiceImpl.java
... ... @@ -178,47 +178,45 @@ public class AssignTasksInfoServiceImpl implements AssignTasksInfoService {
178 178 assignTasksInfoMapper.insert(assignTaskInfo);
179 179 // add by 20260307 初始化单位积分
180 180 unitIntegralService.createUnitIntegral(CommonConstants.UNIT_INTEGRAL_UNIT_TYPE_01, String.valueOf(companyId), assignTaskInfo.getCompanyName());
181   - try {
182   - // 1. 获取截止时间并校验非空
183   - LocalDateTime deadline = assignTasks.getDeadline();
184   - if (deadline == null) {
185   - log.warn("创建定时任务失败:任务ID={},截止时间为空", assignTaskInfo.getId());
186   - // 可根据业务需求抛出异常或直接返回
187   - return;
188   - }
  181 + //注册到期提醒定时器
  182 + createRemindJob(assignTaskInfo.getDeadline(), assignTaskInfo.getId());
  183 + }
  184 + }
  185 + }
189 186  
190   - // 2. 计算:当前时间 + 3小时 是否超过截止时间(即截止时间不足3小时)
191   - LocalDateTime now = LocalDateTime.now(DEFAULT_ZONE); // 当前东八区时间
192   - LocalDateTime remindThreshold = now.plusHours(REMIND_ADVANCE_HOURS);
193   -
194   - // 核心判断:截止时间 <= (当前时间+3小时),不创建定时任务
195   - if (deadline.isBefore(remindThreshold)) {
196   - String formattedDeadline = deadline.format(DATE_FORMATTER);
197   - String formattedThreshold = remindThreshold.format(DATE_FORMATTER);
198   - log.info("任务ID={} 无需创建定时任务:截止时间={},不足{}小时(阈值时间={})",
199   - assignTaskInfo.getId(), formattedDeadline, REMIND_ADVANCE_HOURS, formattedThreshold);
200   - return; // 直接返回,不创建定时任务
201   - }
  187 + public void createRemindJob(LocalDateTime deadline, Long id){
202 188  
203   - // 3. 安全转换LocalDateTime到Date(指定东八区,避免时区问题)
204   - Date triggerDate = Date.from(
205   - deadline.atZone(DEFAULT_ZONE) // 绑定东八区(业务时区)
206   - .toInstant() // 转为Instant
207   - );
208   -
209   - // 4. 规范日志输出(使用占位符,格式化时间)
210   - String formattedDeadline = deadline.format(DATE_FORMATTER);
211   - log.info("创建定时任务:任务ID={}, 截止时间(LocalDateTime)={}, 转换后Date时间={}",
212   - assignTaskInfo.getId(),
213   - formattedDeadline,
214   - triggerDate);
215   -
216   - // 5. 注册定时任务
217   - quartzRemindService.registerRemindJob(assignTaskInfo.getId(), triggerDate);
218   - } catch (SchedulerException exception) {
219   - throw exception0(BAD_REQUEST.getCode(),"创建到期定时提醒异常");
220   - }
221   - }
  189 + // 2. 计算:当前时间 + 3小时 是否超过截止时间(即截止时间不足3小时)
  190 + LocalDateTime now = LocalDateTime.now(DEFAULT_ZONE); // 当前东八区时间
  191 + LocalDateTime remindThreshold = now.plusHours(REMIND_ADVANCE_HOURS);
  192 +
  193 + // 核心判断:截止时间 <= (当前时间+3小时),不创建定时任务
  194 + if (deadline.isBefore(remindThreshold)) {
  195 + String formattedDeadline = deadline.format(DATE_FORMATTER);
  196 + String formattedThreshold = remindThreshold.format(DATE_FORMATTER);
  197 + log.info("任务ID={} 无需创建定时任务:截止时间={},不足{}小时(阈值时间={})",
  198 + id, formattedDeadline, REMIND_ADVANCE_HOURS, formattedThreshold);
  199 + return; // 直接返回,不创建定时任务
  200 + }
  201 +
  202 + // 3. 安全转换LocalDateTime到Date(指定东八区,避免时区问题)
  203 + Date triggerDate = Date.from(
  204 + deadline.atZone(DEFAULT_ZONE) // 绑定东八区(业务时区)
  205 + .toInstant() // 转为Instant
  206 + );
  207 +
  208 + // 4. 规范日志输出(使用占位符,格式化时间)
  209 + String formattedDeadline = deadline.format(DATE_FORMATTER);
  210 + log.info("创建定时任务:任务ID={}, 截止时间(LocalDateTime)={}, 转换后Date时间={}",
  211 + id,
  212 + formattedDeadline,
  213 + triggerDate);
  214 +
  215 + // 5. 注册定时任务
  216 + try {
  217 + quartzRemindService.registerRemindJob(id, triggerDate);
  218 + } catch (SchedulerException e) {
  219 + throw exception0(BAD_REQUEST.getCode(),"创建到期定时提醒异常");
222 220 }
223 221 }
224 222  
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/assigntasksinfo/QuartzRemindService.java
... ... @@ -11,6 +11,7 @@ import java.text.SimpleDateFormat;
11 11 import java.util.Date;
12 12 import java.util.Set;
13 13  
  14 +
14 15 /**
15 16 * 动态注册到期提醒Quartz任务的服务
16 17 */
... ... @@ -36,8 +37,9 @@ public class QuartzRemindService {
36 37 }
37 38  
38 39 // 2. 计算触发时间:到期时间 - 3小时
39   - Date triggerTime = new Date(expireTime.getTime() - 3 * 60 * 60 * 1000L);
40   -
  40 + long expireTimeStamp = expireTime.getTime();
  41 + long triggerTimeStamp = expireTimeStamp - 3 * 60 * 60 * 1000L; // 3小时毫秒数
  42 + Date triggerTime = new Date(triggerTimeStamp);
41 43 // 3. 定义JobKey(唯一标识:任务ID + 组名)
42 44 JobKey jobKey = new JobKey("REMIND_JOB_" + jobId, REMIND_JOB_GROUP);
43 45  
... ... @@ -87,4 +89,5 @@ public class QuartzRemindService {
87 89 public Set<JobKey> listAllRemindJobs() throws SchedulerException {
88 90 return scheduler.getJobKeys(GroupMatcher.jobGroupEquals(REMIND_JOB_GROUP));
89 91 }
  92 +
90 93 }
... ...