diff --git a/xinnengyuan/pom.xml b/xinnengyuan/pom.xml
index 4499b51c..56b6c6d4 100644
--- a/xinnengyuan/pom.xml
+++ b/xinnengyuan/pom.xml
@@ -307,7 +307,6 @@
snail-job-client-job-core
${snailjob.version}
-
org.bouncycastle
diff --git a/xinnengyuan/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java b/xinnengyuan/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
index c2fd3709..3c4674d4 100644
--- a/xinnengyuan/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
+++ b/xinnengyuan/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
@@ -107,10 +107,10 @@ public class AuthController {
// 登录
LoginVo loginVo = IAuthStrategy.login(body, client, grantType);
- Long userId = LoginHelper.getUserId();
- scheduledExecutorService.schedule(() -> {
- chatGroupService.createSystem(userId,client.getClientKey());
- }, 5, TimeUnit.SECONDS);
+// Long userId = LoginHelper.getUserId();
+// scheduledExecutorService.schedule(() -> {
+// chatGroupService.createSystem(userId,client.getClientKey());
+// }, 5, TimeUnit.SECONDS);
return R.ok(loginVo);
}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/service/impl/DesVolumeFileServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/service/impl/DesVolumeFileServiceImpl.java
index a799d375..3bc306bf 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/service/impl/DesVolumeFileServiceImpl.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/design/service/impl/DesVolumeFileServiceImpl.java
@@ -271,18 +271,18 @@ public class DesVolumeFileServiceImpl extends ServiceImpl existingFiles = baseMapper.selectList(new LambdaQueryWrapper()
- .eq(DesVolumeFile::getVolumeCatalogId, req.getVolumeCatalogId())
- .eq(DesVolumeFile::getType, DesVolumeFile.PROCESS)
- .orderByDesc(DesVolumeFile::getVersion));
- if (!existingFiles.isEmpty()) {
- DesVolumeFile first = existingFiles.getFirst();
- if (!BusinessStatusEnum.FINISH.getStatus().equals(first.getAuditStatus())) {
- throw new ServiceException("文件尚未审核完成,请勿重复上传");
- }
- }
- }
+// if (CollectionUtil.isNotEmpty(req.getCancellationIds())) {
+// List existingFiles = baseMapper.selectList(new LambdaQueryWrapper()
+// .eq(DesVolumeFile::getVolumeCatalogId, req.getVolumeCatalogId())
+// .eq(DesVolumeFile::getType, DesVolumeFile.PROCESS)
+// .orderByDesc(DesVolumeFile::getVersion));
+// if (!existingFiles.isEmpty()) {
+// DesVolumeFile first = existingFiles.getFirst();
+// if (!BusinessStatusEnum.FINISH.getStatus().equals(first.getAuditStatus())) {
+// throw new ServiceException("文件尚未审核完成,请勿重复上传");
+// }
+// }
+// }
}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/attendance/AttendanceJobUtil.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/attendance/AttendanceJobUtil.java
new file mode 100644
index 00000000..55742223
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/attendance/AttendanceJobUtil.java
@@ -0,0 +1,182 @@
+package org.dromara.job.attendance;
+
+import com.aizuda.snailjob.client.job.core.enums.AllocationAlgorithmEnum;
+import com.aizuda.snailjob.client.job.core.enums.TriggerTypeEnum;
+import com.aizuda.snailjob.client.job.core.openapi.SnailJobOpenApi;
+import com.aizuda.snailjob.common.core.enums.BlockStrategyEnum;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.project.domain.BusAttendanceRule;
+import org.dromara.project.domain.BusProject;
+import org.dromara.project.service.IBusAttendanceRuleService;
+import org.dromara.project.service.IBusProjectService;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalTime;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Slf4j
+@Component
+public class AttendanceJobUtil {
+
+ public static final String CLOCK_IN_REMINDER = "clockInReminder";
+
+ public static final String CLOCK_OUT_REMINDER = "clockOutReminder";
+
+ @Resource
+ private IBusProjectService projectService;
+
+ @Resource
+ @Lazy
+ private IBusAttendanceRuleService attendanceRuleService;
+
+ @Async
+ public void addClusterJob(BusAttendanceRule rule) {
+
+ BusProject project = projectService.getById(rule.getProjectId());
+ String projectName = project.getProjectName();
+
+ String jobName1 = projectName + "上班打卡提醒";
+ LocalTime clockInTime = rule.getClockInTime();
+ //提前10分钟
+ LocalTime clockInReminderTime = clockInTime.minusMinutes(10);
+ String dailyCron1 = toDailyCron(clockInReminderTime);
+
+ Long execute1 = SnailJobOpenApi.addClusterJob()
+ .setRouteKey(AllocationAlgorithmEnum.RANDOM)
+ .setJobName(jobName1)
+ .setExecutorInfo(CLOCK_IN_REMINDER)
+ .setExecutorTimeout(30)
+ .setDescription("add")
+ .setBlockStrategy(BlockStrategyEnum.DISCARD)
+ .setMaxRetryTimes(1)
+ .setTriggerType(TriggerTypeEnum.CRON)
+ .setTriggerInterval(dailyCron1)
+ .addArgsStr("projectId", rule.getProjectId())
+ .setRetryInterval(3)
+ .execute();
+ rule.setClockInJobId(execute1);
+
+
+ String jobName2 = projectName + "下班打卡提醒";
+ LocalTime clockOutTime = rule.getClockOutTime();
+ //后延10分钟
+ LocalTime clockOutReminderTime = clockOutTime.plusMinutes(10);
+ String dailyCron2 = toDailyCron(clockOutReminderTime);
+
+
+ Long execute = SnailJobOpenApi.addClusterJob()
+ .setRouteKey(AllocationAlgorithmEnum.RANDOM)
+ .setJobName(jobName2)
+ .setExecutorInfo(CLOCK_OUT_REMINDER)
+ .setExecutorTimeout(30)
+ .setDescription("add")
+ .setBlockStrategy(BlockStrategyEnum.DISCARD)
+ .setMaxRetryTimes(1)
+ .setTriggerType(TriggerTypeEnum.CRON)
+ .setTriggerInterval(dailyCron2)
+ .addArgsStr("projectId", rule.getProjectId())
+ .setRetryInterval(3)
+ .execute();
+ rule.setClockOutJobId(execute);
+
+ attendanceRuleService.updateById(rule);
+ }
+
+
+ @Async
+ public void updateClusterJob(Long id) {
+ BusAttendanceRule rule = attendanceRuleService.getById(id);
+ BusProject project = projectService.getById(rule.getProjectId());
+ String projectName = project.getProjectName();
+
+ LocalTime clockInTime = rule.getClockInTime();
+ //提前10分钟
+ LocalTime clockInReminderTime = clockInTime.minusMinutes(10);
+ String dailyCron1 = toDailyCron(clockInReminderTime);
+
+ if (rule.getClockInJobId() != null) {
+ SnailJobOpenApi.updateClusterJob(rule.getClockInJobId())
+ .setTriggerType(TriggerTypeEnum.CRON)
+ .setTriggerInterval(dailyCron1)
+ .execute();
+ } else {
+ String jobName1 = projectName + "上班打卡提醒";
+ Long execute = SnailJobOpenApi.addClusterJob()
+ .setRouteKey(AllocationAlgorithmEnum.RANDOM)
+ .setJobName(jobName1)
+ .setExecutorInfo(CLOCK_IN_REMINDER)
+ .setExecutorTimeout(30)
+ .setDescription("add")
+ .setBlockStrategy(BlockStrategyEnum.DISCARD)
+ .setMaxRetryTimes(1)
+ .setTriggerType(TriggerTypeEnum.CRON)
+ .setTriggerInterval(dailyCron1)
+ .addArgsStr("projectId", rule.getProjectId())
+ .setRetryInterval(3)
+ .execute();
+ rule.setClockInJobId(execute);
+ }
+
+
+ LocalTime clockOutTime = rule.getClockOutTime();
+ //后延10分钟
+ LocalTime clockOutReminderTime = clockOutTime.plusMinutes(10);
+ String dailyCron2 = toDailyCron(clockOutReminderTime);
+
+ if (rule.getClockOutJobId() != null) {
+ SnailJobOpenApi.updateClusterJob(rule.getClockOutJobId())
+ .setTriggerType(TriggerTypeEnum.CRON)
+ .setTriggerInterval(dailyCron2)
+ .execute();
+ } else {
+ String jobName2 = projectName + "下班打卡提醒";
+ Long execute = SnailJobOpenApi.addClusterJob()
+ .setRouteKey(AllocationAlgorithmEnum.RANDOM)
+ .setJobName(jobName2)
+ .setExecutorInfo(CLOCK_OUT_REMINDER)
+ .setExecutorTimeout(30)
+ .setDescription("add")
+ .setBlockStrategy(BlockStrategyEnum.DISCARD)
+ .setMaxRetryTimes(1)
+ .setTriggerType(TriggerTypeEnum.CRON)
+ .setTriggerInterval(dailyCron2)
+ .addArgsStr("projectId", rule.getProjectId())
+ .setRetryInterval(3)
+ .execute();
+ rule.setClockOutJobId(execute);
+ }
+ attendanceRuleService.updateById(rule);
+ }
+
+ @Async
+ public void deleteClusterJob(List rules) {
+ Set jobIds = rules.stream()
+ .flatMap(rule -> Stream.of(rule.getClockInJobId(), rule.getClockOutJobId())) // 提取两个 JobId
+ .filter(Objects::nonNull) // 过滤掉 null 值
+ .collect(Collectors.toSet()); // 收集
+ rules.stream().map(BusAttendanceRule::getClockInJobId).filter(Objects::nonNull).forEach(jobIds::add);
+ SnailJobOpenApi.deleteJob(jobIds).execute();
+ }
+
+
+ /**
+ * 将LocalTime转换为每天执行的Cron表达式
+ *
+ * @param time 时间
+ * @return 每天在指定时间执行的Cron表达式
+ */
+ public String toDailyCron(LocalTime time) {
+ int hour = time.getHour();
+ int minute = time.getMinute();
+
+ // Cron格式: 秒 分 时 日 月 周 年(可选)
+ return String.format("0 %d %d * * ?", minute, hour);
+ }
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/attendance/AttendanceReminderJob.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/attendance/AttendanceReminderJob.java
new file mode 100644
index 00000000..dbcee0e1
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/attendance/AttendanceReminderJob.java
@@ -0,0 +1,109 @@
+package org.dromara.job.attendance;
+
+
+import cn.hutool.json.JSONUtil;
+import com.aizuda.snailjob.client.job.core.annotation.JobExecutor;
+import com.aizuda.snailjob.client.job.core.dto.JobArgs;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.contractor.domain.SubConstructionUser;
+import org.dromara.contractor.service.ISubConstructionUserService;
+import org.dromara.project.domain.BusAttendanceRule;
+import org.dromara.project.domain.BusProject;
+import org.dromara.project.domain.BusUserProjectRelevancy;
+import org.dromara.project.service.IBusAttendanceRuleService;
+import org.dromara.project.service.IBusProjectService;
+import org.dromara.project.service.IBusUserProjectRelevancyService;
+import org.dromara.websocket.ChatServerHandler;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component
+public class AttendanceReminderJob {
+
+ @Resource
+ private IBusUserProjectRelevancyService userProjectRelevancyService;
+
+ @Resource
+ private ChatServerHandler chatServerHandler;
+
+ @Resource
+ private IBusProjectService projectService;
+
+ @Resource
+ private IBusAttendanceRuleService attendanceRuleService;
+
+ @Resource
+ private ISubConstructionUserService constructionUserService;
+
+ @JobExecutor(name = "clockInReminder")
+ public void clockInReminder(JobArgs jobArgs) {
+ Long projectId = JSONUtil.parseObj(jobArgs.getJobParams()).getLong("projectId");
+ log.info("项目ID:{},开始执行打卡提醒任务", projectId);
+
+ BusProject project = projectService.getById(projectId);
+
+ BusAttendanceRule rule = attendanceRuleService.getOne(Wrappers.lambdaQuery()
+ .eq(BusAttendanceRule::getProjectId, projectId)
+ .last("limit 1")
+ );
+
+ if (rule == null || project == null) {
+ return;
+ }
+
+ //查询项目下的关联人员
+ List relevancyList = userProjectRelevancyService.list(Wrappers.lambdaQuery(BusUserProjectRelevancy.class)
+ .eq(BusUserProjectRelevancy::getProjectId, projectId));
+ String message = String.format("【%s项目】上班打卡提醒!请在 %s 前完成打卡。",
+ project.getProjectName(), rule.getClockInTime().toString());
+ Set collect = relevancyList.stream().map(BusUserProjectRelevancy::getUserId).collect(Collectors.toSet());
+
+ List list = constructionUserService.list(Wrappers.lambdaQuery(SubConstructionUser.class)
+ .in(SubConstructionUser::getSysUserId, collect));
+ Set list1 = list.stream().map(SubConstructionUser::getSysUserId).collect(Collectors.toSet());
+
+ for (Long userId : list1) {
+ chatServerHandler.sendSystemMessageToUser(userId, message);
+ }
+ }
+
+ @JobExecutor(name = "clockOutReminder")
+ public void clockOutReminder(JobArgs jobArgs) {
+ Long projectId = JSONUtil.parseObj(jobArgs.getJobParams()).getLong("projectId");
+ log.info("项目ID:{},开始执行打卡提醒任务", projectId);
+
+ BusProject project = projectService.getById(projectId);
+
+ BusAttendanceRule rule = attendanceRuleService.getOne(Wrappers.lambdaQuery()
+ .eq(BusAttendanceRule::getProjectId, projectId)
+ .last("limit 1")
+ );
+
+ if (rule == null || project == null) {
+ return;
+ }
+
+ //查询项目下的关联人员
+ List relevancyList = userProjectRelevancyService.list(Wrappers.lambdaQuery(BusUserProjectRelevancy.class)
+ .eq(BusUserProjectRelevancy::getProjectId, projectId));
+ String message = String.format("【%s项目】下班打卡提醒!请记得完成打卡。",
+ project.getProjectName());
+ Set collect = relevancyList.stream().map(BusUserProjectRelevancy::getUserId).collect(Collectors.toSet());
+
+ List list = constructionUserService.list(Wrappers.lambdaQuery(SubConstructionUser.class)
+ .in(SubConstructionUser::getSysUserId, collect));
+ Set list1 = list.stream().map(SubConstructionUser::getSysUserId).collect(Collectors.toSet());
+
+ for (Long userId : list1) {
+ chatServerHandler.sendSystemMessageToUser(userId, message);
+ }
+ }
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/BusAttendanceRule.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/BusAttendanceRule.java
index 125fa334..b9286e95 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/BusAttendanceRule.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/BusAttendanceRule.java
@@ -92,5 +92,14 @@ public class BusAttendanceRule extends BaseEntity {
*/
private String type;
+ /**
+ * 上班打卡提醒定时任务ID
+ */
+ private Long clockInJobId;
+
+ /**
+ * 下班打卡提醒定时任务ID
+ */
+ private Long clockOutJobId;
}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceRuleServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceRuleServiceImpl.java
index cf0c57d6..36c6ffdd 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceRuleServiceImpl.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceRuleServiceImpl.java
@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
+import org.dromara.job.attendance.AttendanceJobUtil;
import org.springframework.stereotype.Service;
import org.dromara.project.domain.bo.BusAttendanceRuleBo;
import org.dromara.project.domain.vo.BusAttendanceRuleVo;
@@ -35,6 +36,7 @@ public class BusAttendanceRuleServiceImpl extends ServiceImpl 0;
+ int i = baseMapper.updateById(update);
+ attendanceJobUtil.updateClusterJob(bo.getId());
+ return i> 0;
}
/**
@@ -208,6 +213,9 @@ public class BusAttendanceRuleServiceImpl extends ServiceImpl busAttendanceRules = baseMapper.selectList(Wrappers.lambdaQuery()
+ .in(BusAttendanceRule::getId, ids));
+ attendanceJobUtil.deleteClusterJob(busAttendanceRules);
return baseMapper.deleteByIds(ids) > 0;
}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java
index c1c15829..c0a9dd71 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java
@@ -42,6 +42,7 @@ import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ISysOssService;
import org.dromara.system.service.ISysUserService;
+import org.dromara.websocket.ChatServerHandler;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@@ -92,6 +93,8 @@ public class BusAttendanceServiceImpl extends ServiceImpl ATTENDANCE_STATUS = new HashSet<>(Arrays.asList(BusAttendanceClockStatusEnum.NORMAL.getValue(),
BusAttendanceClockStatusEnum.LATE.getValue(), BusAttendanceClockStatusEnum.LEAVEEARLY.getValue()));
@@ -303,7 +306,10 @@ public class BusAttendanceServiceImpl extends ServiceImpl