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,6 +3,7 @@ package com.zteits.urbanops.framework.common.util.date;
3 import cn.hutool.core.date.LocalDateTimeUtil; 3 import cn.hutool.core.date.LocalDateTimeUtil;
4 4
5 import java.time.*; 5 import java.time.*;
  6 +import java.time.format.DateTimeFormatter;
6 import java.util.Calendar; 7 import java.util.Calendar;
7 import java.util.Date; 8 import java.util.Date;
8 9
@@ -18,6 +19,9 @@ public class DateUtils { @@ -18,6 +19,9 @@ public class DateUtils {
18 */ 19 */
19 public static final String TIME_ZONE_DEFAULT = "GMT+8"; 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,6 +31,9 @@ public class DateUtils {
27 31
28 public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss"; 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 * 将 LocalDateTime 转换成 Date 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,7 +47,8 @@ public class AssignTasksSaveReqVO {
47 pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, 47 pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND,
48 timezone = "GMT+8", 48 timezone = "GMT+8",
49 shape = JsonFormat.Shape.STRING 49 shape = JsonFormat.Shape.STRING
50 - ) private Date finishTime; 50 + )
  51 + private Date finishTime;
51 52
52 @Schema(description = "任务备注(如:特殊要求、注意事项等)") 53 @Schema(description = "任务备注(如:特殊要求、注意事项等)")
53 private String note; 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,6 +3,7 @@ package com.zteits.urbanops.module.garden.service.assigntasks;
3 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 3 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 import com.baomidou.mybatisplus.core.toolkit.Wrappers; 4 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
5 import com.zteits.urbanops.framework.common.pojo.PageResult; 5 import com.zteits.urbanops.framework.common.pojo.PageResult;
  6 +import com.zteits.urbanops.framework.common.util.date.DateUtils;
6 import com.zteits.urbanops.framework.common.util.object.BeanUtils; 7 import com.zteits.urbanops.framework.common.util.object.BeanUtils;
7 import com.zteits.urbanops.framework.security.core.util.SecurityFrameworkUtils; 8 import com.zteits.urbanops.framework.security.core.util.SecurityFrameworkUtils;
8 import com.zteits.urbanops.module.bpm.api.task.BpmProcessInstanceApi; 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,11 +16,14 @@ import com.zteits.urbanops.module.garden.dal.mysql.assigntasks.AssignTasksMapper
15 import com.zteits.urbanops.module.garden.dal.mysql.assigntasksinfo.AssignTasksInfoMapper; 16 import com.zteits.urbanops.module.garden.dal.mysql.assigntasksinfo.AssignTasksInfoMapper;
16 import com.zteits.urbanops.module.garden.enums.AssignTasksConstants; 17 import com.zteits.urbanops.module.garden.enums.AssignTasksConstants;
17 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;
  20 +import com.zteits.urbanops.module.garden.service.unitintegraltotal.UnitIntegralService;
18 import com.zteits.urbanops.module.system.api.permission.RoleApi; 21 import com.zteits.urbanops.module.system.api.permission.RoleApi;
19 import com.zteits.urbanops.module.system.api.user.AdminUserApi; 22 import com.zteits.urbanops.module.system.api.user.AdminUserApi;
20 import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO; 23 import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO;
21 import jakarta.annotation.Resource; 24 import jakarta.annotation.Resource;
22 import lombok.extern.slf4j.Slf4j; 25 import lombok.extern.slf4j.Slf4j;
  26 +import org.quartz.SchedulerException;
23 import org.springframework.stereotype.Service; 27 import org.springframework.stereotype.Service;
24 import org.springframework.transaction.annotation.Transactional; 28 import org.springframework.transaction.annotation.Transactional;
25 import org.springframework.util.CollectionUtils; 29 import org.springframework.util.CollectionUtils;
@@ -68,6 +72,10 @@ public class AssignTasksServiceImpl implements AssignTasksService { @@ -68,6 +72,10 @@ public class AssignTasksServiceImpl implements AssignTasksService {
68 72
69 @Resource 73 @Resource
70 private BpmProcessInstanceApi processInstanceApi; 74 private BpmProcessInstanceApi processInstanceApi;
  75 + @Resource
  76 + private UnitIntegralService unitIntegralService;
  77 + @Resource
  78 + private QuartzRemindService quartzRemindService;
71 79
72 @Transactional(rollbackFor = Exception.class) 80 @Transactional(rollbackFor = Exception.class)
73 @Override 81 @Override
@@ -125,8 +133,21 @@ public class AssignTasksServiceImpl implements AssignTasksService { @@ -125,8 +133,21 @@ public class AssignTasksServiceImpl implements AssignTasksService {
125 //修改派单信息 133 //修改派单信息
126 taskInfo.setTaskName(updateReqVO.getTaskName()); 134 taskInfo.setTaskName(updateReqVO.getTaskName());
127 taskInfo.setTaskType(updateReqVO.getTaskType()); 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 assignTasksInfoMapper.updateById(taskInfo); 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,6 +9,7 @@ import com.zteits.urbanops.module.garden.dal.dataobject.assigntasksinfo.AssignTa
9 import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO; 9 import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO;
10 import jakarta.validation.Valid; 10 import jakarta.validation.Valid;
11 11
  12 +import java.time.LocalDateTime;
12 import java.util.List; 13 import java.util.List;
13 14
14 /** 15 /**
@@ -111,4 +112,13 @@ public interface AssignTasksInfoService { @@ -111,4 +112,13 @@ public interface AssignTasksInfoService {
111 * @Param companyId 112 * @Param companyId
112 */ 113 */
113 List<AdminUserRespDTO> getUsersByCompanyId(Long companyId); 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,47 +178,45 @@ public class AssignTasksInfoServiceImpl implements AssignTasksInfoService {
178 assignTasksInfoMapper.insert(assignTaskInfo); 178 assignTasksInfoMapper.insert(assignTaskInfo);
179 // add by 20260307 初始化单位积分 179 // add by 20260307 初始化单位积分
180 unitIntegralService.createUnitIntegral(CommonConstants.UNIT_INTEGRAL_UNIT_TYPE_01, String.valueOf(companyId), assignTaskInfo.getCompanyName()); 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,6 +11,7 @@ import java.text.SimpleDateFormat;
11 import java.util.Date; 11 import java.util.Date;
12 import java.util.Set; 12 import java.util.Set;
13 13
  14 +
14 /** 15 /**
15 * 动态注册到期提醒Quartz任务的服务 16 * 动态注册到期提醒Quartz任务的服务
16 */ 17 */
@@ -36,8 +37,9 @@ public class QuartzRemindService { @@ -36,8 +37,9 @@ public class QuartzRemindService {
36 } 37 }
37 38
38 // 2. 计算触发时间:到期时间 - 3小时 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 // 3. 定义JobKey(唯一标识:任务ID + 组名) 43 // 3. 定义JobKey(唯一标识:任务ID + 组名)
42 JobKey jobKey = new JobKey("REMIND_JOB_" + jobId, REMIND_JOB_GROUP); 44 JobKey jobKey = new JobKey("REMIND_JOB_" + jobId, REMIND_JOB_GROUP);
43 45
@@ -87,4 +89,5 @@ public class QuartzRemindService { @@ -87,4 +89,5 @@ public class QuartzRemindService {
87 public Set<JobKey> listAllRemindJobs() throws SchedulerException { 89 public Set<JobKey> listAllRemindJobs() throws SchedulerException {
88 return scheduler.getJobKeys(GroupMatcher.jobGroupEquals(REMIND_JOB_GROUP)); 90 return scheduler.getJobKeys(GroupMatcher.jobGroupEquals(REMIND_JOB_GROUP));
89 } 91 }
  92 +
90 } 93 }