diff --git a/backend/src/main/java/com/designhub/service/DingTalkService.java b/backend/src/main/java/com/designhub/service/DingTalkService.java index 171cb1c..5202535 100644 --- a/backend/src/main/java/com/designhub/service/DingTalkService.java +++ b/backend/src/main/java/com/designhub/service/DingTalkService.java @@ -259,6 +259,16 @@ public class DingTalkService { * 发送机器人消息 */ public boolean sendRobotMessage(String title, String content) { + return sendRobotMessage(title, content, null); + } + + /** + * 发送机器人消息,支持@指定人(通过手机号) + * @param title 消息标题 + * @param content 消息内容 + * @param atMobiles 要@的手机号列表,null或空表示不@任何人 + */ + public boolean sendRobotMessage(String title, String content, List atMobiles) { DingTalkConfig config = getConfig(); if (config == null || config.getRobotWebhook() == null) { log.warn("钉钉机器人未配置"); @@ -281,6 +291,15 @@ public class DingTalkService { markdown.put("title", title); markdown.put("text", "### " + title + "\n\n" + content); message.put("markdown", markdown); + + // 添加@人功能 + if (atMobiles != null && !atMobiles.isEmpty()) { + Map at = new HashMap<>(); + at.put("atMobiles", atMobiles); + at.put("isAtAll", false); + message.put("at", at); + log.info("群消息将@手机号: {}", atMobiles); + } HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); diff --git a/backend/src/main/java/com/designhub/service/TaskApprovalService.java b/backend/src/main/java/com/designhub/service/TaskApprovalService.java index 7d9956b..df58fd7 100644 --- a/backend/src/main/java/com/designhub/service/TaskApprovalService.java +++ b/backend/src/main/java/com/designhub/service/TaskApprovalService.java @@ -184,6 +184,34 @@ public class TaskApprovalService { "task_reject", taskId ); + + // 如果任务有指定的处理人,发送群通知告知驳回 + if (task.getReceiverId() != null) { + try { + com.designhub.entity.User receiver = userMapper.selectById(task.getReceiverId()); + if (receiver != null) { + String title = "任务已驳回"; + StringBuilder content = new StringBuilder(); + content.append("-------------------------------- \n"); + content.append(" 【 任 务 已 驳 回 】 \n"); + content.append("-------------------------------- \n\n"); + + content.append("任务名称:").append(task.getTitle()).append(" \n"); + content.append("任务编号:").append(task.getTaskNo()).append(" \n"); + content.append("原处理人:").append(receiver.getRealName()).append(" \n"); + content.append("驳回原因:").append(reason).append(" \n"); + + content.append(" \n"); + content.append("--------------------------------"); + + java.util.List atMobiles = receiver.getPhone() != null ? + java.util.Arrays.asList(receiver.getPhone()) : null; + dingTalkService.sendRobotMessage(title, content.toString(), atMobiles); + } + } catch (Exception e) { + log.error("发送任务驳回群通知失败", e); + } + } log.info("需求部门负责人驳回任务,任务ID:{},审核人:{}", taskId, approverId); } @@ -268,9 +296,47 @@ public class TaskApprovalService { } logApproval(taskId, approverId, 2, "approve", logComment); - // 如果指定了接收人,发送通知 + // 发送钉钉群通知 if (assignedReceiverId != null) { - log.info("任务【{}】已指定给设计师", task.getTitle()); + // 指定了设计师,发送群通知并@该设计师 + log.info("任务【{}】已指定给设计师,准备发送钉钉群通知", task.getTitle()); + try { + com.designhub.entity.User receiver = userMapper.selectById(assignedReceiverId); + String receiverName = receiver != null ? receiver.getRealName() : "未知"; + String receiverPhone = receiver != null ? receiver.getPhone() : null; + + String title = "任务已指派"; + StringBuilder content = new StringBuilder(); + content.append("-------------------------------- \n"); + content.append(" 【 任 务 已 指 派 】 \n"); + content.append("-------------------------------- \n\n"); + + content.append("任务名称:").append(task.getTitle()).append(" \n"); + content.append("任务编号:").append(task.getTaskNo()).append(" \n"); + content.append("任务积分:").append(task.getScore()).append(" 分 \n"); + content.append("指派给:").append(receiverName).append(" \n"); + + if (task.getEstimatedHours() != null) { + content.append("预估工时:").append(task.getEstimatedHours().intValue()).append(" 小时 \n"); + } + + if (task.getPublisherName() != null && !task.getPublisherName().isEmpty()) { + content.append("发起人:").append(task.getPublisherName()).append(" \n"); + } + + content.append(" \n"); + content.append("-------------------------------- \n"); + content.append("请尽快处理!qd.yydd.ai \n"); + content.append("--------------------------------"); + + // 发送群通知并@指定的设计师 + java.util.List atMobiles = receiverPhone != null ? + java.util.Arrays.asList(receiverPhone) : null; + dingTalkService.sendRobotMessage(title, content.toString(), atMobiles); + log.info("任务指派群通知已发送,@手机号: {}", receiverPhone); + } catch (Exception e) { + log.error("发送任务指派群通知失败", e); + } } else { log.info("任务【{}】已发布到任务大厅,准备发送钉钉群通知", task.getTitle()); // 任务发布到大厅,发送钉钉群机器人通知 @@ -409,6 +475,34 @@ public class TaskApprovalService { "task_reject", taskId ); + + // 如果任务有指定的处理人,发送群通知告知驳回 + if (task.getReceiverId() != null) { + try { + com.designhub.entity.User receiver = userMapper.selectById(task.getReceiverId()); + if (receiver != null) { + String title = "任务已驳回"; + StringBuilder content = new StringBuilder(); + content.append("-------------------------------- \n"); + content.append(" 【 任 务 已 驳 回 】 \n"); + content.append("-------------------------------- \n\n"); + + content.append("任务名称:").append(task.getTitle()).append(" \n"); + content.append("任务编号:").append(task.getTaskNo()).append(" \n"); + content.append("原处理人:").append(receiver.getRealName()).append(" \n"); + content.append("驳回原因:").append(reason).append(" \n"); + + content.append(" \n"); + content.append("--------------------------------"); + + java.util.List atMobiles = receiver.getPhone() != null ? + java.util.Arrays.asList(receiver.getPhone()) : null; + dingTalkService.sendRobotMessage(title, content.toString(), atMobiles); + } + } catch (Exception e) { + log.error("发送任务驳回群通知失败", e); + } + } log.info("接单部门负责人驳回任务,任务ID:{},审核人:{}", taskId, approverId); } diff --git a/backend/src/main/java/com/designhub/service/TaskItemService.java b/backend/src/main/java/com/designhub/service/TaskItemService.java index 32410e6..b544f21 100644 --- a/backend/src/main/java/com/designhub/service/TaskItemService.java +++ b/backend/src/main/java/com/designhub/service/TaskItemService.java @@ -502,6 +502,40 @@ public class TaskItemService { notification.setPriority(2); notification.setPushDingtalk(1); // 推送到钉钉 notificationService.sendNotification(notification); + + // 发送钉钉群通知并@指定的设计师 + try { + int totalScore = groupItems.stream().mapToInt(item -> item.getTotalScore() != null ? item.getTotalScore() : 0).sum(); + String title = "子任务组已指派"; + StringBuilder content = new StringBuilder(); + content.append("-------------------------------- \n"); + content.append(" 【 子 任 务 组 已 指 派 】 \n"); + content.append("-------------------------------- \n\n"); + + content.append("主任务:").append(mainTask.getTitle()).append(" \n"); + content.append("任务编号:").append(mainTask.getTaskNo()).append(" \n"); + content.append("任务组:第 ").append(groupNo).append(" 组 \n"); + content.append("子任务数量:").append(groupItems.size()).append(" 个 \n"); + content.append("总积分:").append(totalScore).append(" 分 \n"); + content.append("指派给:").append(receiver.getRealName()).append(" \n"); + + if (mainTask.getPublisherName() != null && !mainTask.getPublisherName().isEmpty()) { + content.append("发起人:").append(mainTask.getPublisherName()).append(" \n"); + } + + content.append(" \n"); + content.append("-------------------------------- \n"); + content.append("请尽快处理!qd.yydd.ai \n"); + content.append("--------------------------------"); + + // @指定的设计师 + java.util.List atMobiles = receiver.getPhone() != null ? + java.util.Arrays.asList(receiver.getPhone()) : null; + dingTalkService.sendRobotMessage(title, content.toString(), atMobiles); + log.info("子任务组指派群通知已发送,@手机号: {}", receiver.getPhone()); + } catch (Exception e) { + log.error("发送子任务组指派群通知失败", e); + } log.info("第 {} 组 {} 个子任务已指派给设计师 {}", groupNo, groupItems.size(), receiver.getRealName()); } else { @@ -653,6 +687,55 @@ public class TaskItemService { notification.setPushDingtalk(1); // 推送到钉钉 notificationService.sendNotification(notification); } + + // 6. 查找该任务组中有处理人的子任务,发送群通知@处理人 + try { + List groupItems = taskItemMapper.selectList( + new LambdaQueryWrapper() + .eq(TaskItem::getTaskId, taskId) + .eq(TaskItem::getGroupNo, groupNo) + ); + + // 收集所有处理人的手机号 + java.util.Set atMobiles = new java.util.HashSet<>(); + java.util.Set receiverNames = new java.util.HashSet<>(); + for (TaskItem item : groupItems) { + if (item.getReceiverId() != null) { + com.designhub.entity.User receiver = userMapper.selectById(item.getReceiverId()); + if (receiver != null) { + if (receiver.getPhone() != null) { + atMobiles.add(receiver.getPhone()); + } + if (receiver.getRealName() != null) { + receiverNames.add(receiver.getRealName()); + } + } + } + } + + // 如果有处理人,发送群通知 + if (!receiverNames.isEmpty()) { + String title = "子任务组已驳回"; + StringBuilder content = new StringBuilder(); + content.append("-------------------------------- \n"); + content.append(" 【 子 任 务 组 已 驳 回 】 \n"); + content.append("-------------------------------- \n\n"); + + content.append("主任务:").append(mainTask.getTitle()).append(" \n"); + content.append("任务编号:").append(mainTask.getTaskNo()).append(" \n"); + content.append("任务组:第 ").append(groupNo).append(" 组 \n"); + content.append("原处理人:").append(String.join("、", receiverNames)).append(" \n"); + content.append("驳回原因:").append(reason).append(" \n"); + + content.append(" \n"); + content.append("--------------------------------"); + + dingTalkService.sendRobotMessage(title, content.toString(), + atMobiles.isEmpty() ? null : new java.util.ArrayList<>(atMobiles)); + } + } catch (Exception e) { + log.error("发送子任务组驳回群通知失败", e); + } } /**