1. 将子任务进度从标签式改为时间线流程图样式,更直观展示任务流转进度 2. 修复需求部门用户在"进行中任务"页面看不到自己发起的任务的问题 3. 添加子任务状态辅助函数(状态类名、标签、状态文本) 4. 在MyTasksParams中添加keyword参数支持搜索
257 lines
11 KiB
Java
257 lines
11 KiB
Java
package com.designhub.service;
|
||
|
||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||
import com.designhub.entity.Task;
|
||
import com.designhub.entity.TaskItem;
|
||
import com.designhub.entity.TaskProgressUpdateLog;
|
||
import com.designhub.entity.User;
|
||
import com.designhub.mapper.TaskMapper;
|
||
import com.designhub.mapper.TaskItemMapper;
|
||
import com.designhub.mapper.TaskProgressUpdateLogMapper;
|
||
import lombok.RequiredArgsConstructor;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.scheduling.annotation.Scheduled;
|
||
import org.springframework.stereotype.Service;
|
||
import org.springframework.transaction.annotation.Transactional;
|
||
|
||
import java.time.LocalDate;
|
||
import java.time.LocalDateTime;
|
||
import java.time.LocalTime;
|
||
import java.util.List;
|
||
|
||
/**
|
||
* 任务进度检查服务
|
||
* 每日17:30检查任务进度是否更新,并发送钉钉通知提醒设计师
|
||
*/
|
||
@Service
|
||
@RequiredArgsConstructor
|
||
@Slf4j
|
||
public class TaskProgressCheckService {
|
||
|
||
private final TaskMapper taskMapper;
|
||
private final TaskItemMapper taskItemMapper;
|
||
private final TaskProgressUpdateLogMapper progressUpdateLogMapper;
|
||
private final NotificationService notificationService;
|
||
private final UserService userService;
|
||
private final DingTalkService dingTalkService;
|
||
|
||
/**
|
||
* 每日17:30提醒设计师更新子任务进度
|
||
* cron: 秒 分 时 日 月 周
|
||
*/
|
||
@Scheduled(cron = "0 30 17 * * ?")
|
||
@Transactional
|
||
public void remindDesignersToUpdateProgress() {
|
||
log.info("=== 开始执行每日进度更新提醒任务(17:30) ===");
|
||
|
||
// 查询所有进行中的子任务
|
||
List<TaskItem> inProgressItems = taskItemMapper.selectList(
|
||
new LambdaQueryWrapper<TaskItem>()
|
||
.eq(TaskItem::getStatus, "in_progress")
|
||
.isNotNull(TaskItem::getReceiverId)
|
||
);
|
||
|
||
log.info("当前进行中的子任务数量: {}", inProgressItems.size());
|
||
|
||
int reminderSentCount = 0;
|
||
|
||
for (TaskItem item : inProgressItems) {
|
||
try {
|
||
if (item.getReceiverId() == null) continue;
|
||
|
||
// 获取主任务信息
|
||
Task mainTask = taskMapper.selectById(item.getTaskId());
|
||
if (mainTask == null) continue;
|
||
|
||
// 获取设计师信息
|
||
User designer = userService.getUserById(item.getReceiverId());
|
||
if (designer == null) continue;
|
||
|
||
String designerName = designer.getRealName() != null ? designer.getRealName() : designer.getUsername();
|
||
|
||
// 构建提醒消息内容
|
||
StringBuilder content = new StringBuilder();
|
||
content.append("### 进度更新提醒\n\n");
|
||
content.append("**设计师**:").append(designerName).append(" \n");
|
||
content.append("**任务名称**:").append(mainTask.getTitle()).append(" \n");
|
||
content.append("**子任务编号**:").append(item.getItemNo()).append(" \n");
|
||
content.append("**当前进度**:").append(item.getProgress() != null ? item.getProgress() : 0).append("% \n\n");
|
||
content.append("请及时更新您的任务进度,以便项目负责人了解任务进展情况。");
|
||
|
||
// 发送钉钉个人通知
|
||
notificationService.sendNotification(
|
||
item.getReceiverId(),
|
||
"请更新任务进度",
|
||
content.toString(),
|
||
"PROGRESS_REMINDER",
|
||
"task_item",
|
||
item.getId()
|
||
);
|
||
|
||
reminderSentCount++;
|
||
log.debug("已向设计师 {} 发送进度更新提醒,子任务: {}", designerName, item.getItemNo());
|
||
|
||
} catch (Exception e) {
|
||
log.error("发送进度更新提醒失败: itemId={}, receiverId={}",
|
||
item.getId(), item.getReceiverId(), e);
|
||
}
|
||
}
|
||
|
||
log.info("=== 每日进度更新提醒完成 === 发送提醒数: {}", reminderSentCount);
|
||
}
|
||
|
||
/**
|
||
* 每日18:00执行进度更新检查(记录未更新的任务)
|
||
* cron: 秒 分 时 日 月 周
|
||
*/
|
||
@Scheduled(cron = "0 0 18 * * ?")
|
||
@Transactional
|
||
public void checkDailyProgressUpdate() {
|
||
log.info("=== 开始执行每日进度更新检查任务 ===");
|
||
|
||
LocalDate today = LocalDate.now();
|
||
LocalDateTime todayStart = LocalDateTime.of(today, LocalTime.MIN);
|
||
LocalDateTime now = LocalDateTime.now();
|
||
|
||
// 查询所有进行中的任务
|
||
List<Task> inProgressTasks = taskMapper.selectList(
|
||
new LambdaQueryWrapper<Task>()
|
||
.eq(Task::getStatus, "in_progress")
|
||
.isNotNull(Task::getReceiverId)
|
||
);
|
||
|
||
log.info("当前进行中的任务数量: {}", inProgressTasks.size());
|
||
|
||
int notUpdatedCount = 0;
|
||
int updatedCount = 0;
|
||
int notificationSentCount = 0;
|
||
|
||
for (Task task : inProgressTasks) {
|
||
try {
|
||
// 检查今天是否已经有记录
|
||
TaskProgressUpdateLog existingLog = progressUpdateLogMapper.selectOne(
|
||
new LambdaQueryWrapper<TaskProgressUpdateLog>()
|
||
.eq(TaskProgressUpdateLog::getTaskId, task.getId())
|
||
.eq(TaskProgressUpdateLog::getCheckDate, today)
|
||
);
|
||
|
||
if (existingLog != null) {
|
||
log.debug("任务 {} 今天已检查过,跳过", task.getTaskNo());
|
||
continue;
|
||
}
|
||
|
||
// 检查任务进度是否在今天更新过
|
||
boolean updatedToday = task.getUpdateTime() != null
|
||
&& task.getUpdateTime().isAfter(todayStart);
|
||
|
||
// 创建检查记录
|
||
// 获取接单人姓名
|
||
String receiverName = null;
|
||
if (task.getReceiverId() != null) {
|
||
try {
|
||
var receiver = userService.getUserById(task.getReceiverId());
|
||
if (receiver != null) {
|
||
receiverName = receiver.getRealName() != null ? receiver.getRealName() : receiver.getUsername();
|
||
}
|
||
} catch (Exception e) {
|
||
log.warn("获取接单人姓名失败: receiverId={}", task.getReceiverId());
|
||
}
|
||
}
|
||
|
||
TaskProgressUpdateLog log = new TaskProgressUpdateLog();
|
||
log.setTaskId(task.getId());
|
||
log.setTaskNo(task.getTaskNo());
|
||
log.setTaskTitle(task.getTitle());
|
||
log.setReceiverId(task.getReceiverId());
|
||
log.setReceiverName(receiverName);
|
||
log.setCheckDate(today);
|
||
log.setIsUpdated(updatedToday ? 1 : 0);
|
||
log.setLastUpdateTime(task.getUpdateTime());
|
||
log.setProgressBefore(task.getProgress());
|
||
log.setTaskStatus(task.getStatus());
|
||
log.setCreateTime(now);
|
||
|
||
if (updatedToday) {
|
||
updatedCount++;
|
||
log.setProgressAfter(task.getProgress());
|
||
log.setRemark("今日已更新进度");
|
||
log.setNotificationSent(0); // 已更新,不需要发送通知
|
||
} else {
|
||
notUpdatedCount++;
|
||
log.setRemark("今日未更新进度,已发送提醒通知");
|
||
|
||
// 发送通知给接单人
|
||
if (task.getReceiverId() != null) {
|
||
try {
|
||
notificationService.sendTaskNotification(
|
||
task.getReceiverId(),
|
||
task.getId(),
|
||
String.format("任务【%s】需要更新进度", task.getTitle()),
|
||
String.format("您接收的任务【%s】(编号:%s)今天还未更新进度,请及时更新任务进展情况。",
|
||
task.getTitle(), task.getTaskNo())
|
||
);
|
||
log.setNotificationSent(1);
|
||
log.setNotificationTime(LocalDateTime.now());
|
||
notificationSentCount++;
|
||
this.log.debug("已向用户 {} 发送进度更新提醒", task.getReceiverId());
|
||
} catch (Exception e) {
|
||
this.log.error("发送进度更新通知失败: taskId={}, receiverId={}",
|
||
task.getId(), task.getReceiverId(), e);
|
||
log.setNotificationSent(0);
|
||
log.setRemark("今日未更新进度,通知发送失败: " + e.getMessage());
|
||
}
|
||
}
|
||
}
|
||
|
||
// 保存检查记录
|
||
progressUpdateLogMapper.insert(log);
|
||
|
||
} catch (Exception e) {
|
||
this.log.error("检查任务进度失败: taskId={}, taskNo={}",
|
||
task.getId(), task.getTaskNo(), e);
|
||
}
|
||
}
|
||
|
||
log.info("=== 每日进度更新检查完成 ===");
|
||
log.info("总任务数: {}, 已更新: {}, 未更新: {}, 通知已发送: {}",
|
||
inProgressTasks.size(), updatedCount, notUpdatedCount, notificationSentCount);
|
||
}
|
||
|
||
/**
|
||
* 手动触发进度检查(用于测试或管理员手动触发)
|
||
*/
|
||
public void manualCheckProgressUpdate() {
|
||
log.info("手动触发进度更新检查");
|
||
checkDailyProgressUpdate();
|
||
}
|
||
|
||
/**
|
||
* 获取指定日期的进度更新记录
|
||
*/
|
||
public List<TaskProgressUpdateLog> getProgressUpdateLogs(LocalDate date, Integer isUpdated) {
|
||
LambdaQueryWrapper<TaskProgressUpdateLog> wrapper = new LambdaQueryWrapper<>();
|
||
wrapper.eq(TaskProgressUpdateLog::getCheckDate, date);
|
||
if (isUpdated != null) {
|
||
wrapper.eq(TaskProgressUpdateLog::getIsUpdated, isUpdated);
|
||
}
|
||
wrapper.orderByDesc(TaskProgressUpdateLog::getCreateTime);
|
||
return progressUpdateLogMapper.selectList(wrapper);
|
||
}
|
||
|
||
/**
|
||
* 获取某个用户的进度更新记录
|
||
*/
|
||
public List<TaskProgressUpdateLog> getUserProgressUpdateLogs(Long userId, LocalDate startDate, LocalDate endDate) {
|
||
LambdaQueryWrapper<TaskProgressUpdateLog> wrapper = new LambdaQueryWrapper<>();
|
||
wrapper.eq(TaskProgressUpdateLog::getReceiverId, userId);
|
||
if (startDate != null) {
|
||
wrapper.ge(TaskProgressUpdateLog::getCheckDate, startDate);
|
||
}
|
||
if (endDate != null) {
|
||
wrapper.le(TaskProgressUpdateLog::getCheckDate, endDate);
|
||
}
|
||
wrapper.orderByDesc(TaskProgressUpdateLog::getCheckDate);
|
||
return progressUpdateLogMapper.selectList(wrapper);
|
||
}
|
||
}
|