修复流水线任务审核通过后只通知一个设计师的问题
- 新增sendTaskAssignedNotification方法 - 流水线任务审核通过后,遍历第一个部门的所有子任务 - 给每个子任务的设计师都发送钉钉通知 - 每个设计师收到的通知只包含自己负责的任务明细
This commit is contained in:
parent
cb2c468513
commit
9b5407060a
@ -265,144 +265,34 @@ public class TaskApprovalService {
|
||||
logApproval(taskId, approverId, 2, "approve", logComment);
|
||||
|
||||
// 发送钉钉通知
|
||||
if (finalReceiverId != null) {
|
||||
// 指定了设计师,发送个人通知和群通知
|
||||
log.info("任务【{}】已指定给设计师,准备发送钉钉通知", task.getTitle());
|
||||
try {
|
||||
com.designhub.entity.User receiver = userMapper.selectById(finalReceiverId);
|
||||
String receiverName = receiver != null ? receiver.getRealName() : "未知";
|
||||
String receiverPhone = receiver != null ? receiver.getPhone() : null;
|
||||
|
||||
// 1. 构建统一格式的通知内容(与"新任务发布"模版保持一致)
|
||||
StringBuilder content = new StringBuilder();
|
||||
|
||||
// 基本信息
|
||||
content.append("**任务名称**:").append(task.getTitle()).append(" \n");
|
||||
content.append("**任务编号**:").append(task.getTaskNo()).append(" \n");
|
||||
|
||||
// 任务详情
|
||||
if (task.getBrandName() != null && !task.getBrandName().isEmpty()) {
|
||||
content.append("**品牌**:").append(task.getBrandName()).append(" \n");
|
||||
// 对于流水线任务,需要给第一个部门的所有子任务设计师发送通知
|
||||
java.util.Set<Long> notifiedReceiverIds = new java.util.HashSet<>();
|
||||
|
||||
if (task.getIsPipeline() != null && task.getIsPipeline() == 1) {
|
||||
// 流水线任务:查询第一个部门的所有子任务,给每个设计师发送通知
|
||||
List<TaskItem> firstDeptItems = taskItemMapper.selectList(
|
||||
new LambdaQueryWrapper<TaskItem>()
|
||||
.eq(TaskItem::getTaskId, task.getId())
|
||||
.eq(TaskItem::getStatus, "in_progress")
|
||||
.isNotNull(TaskItem::getReceiverId)
|
||||
);
|
||||
|
||||
for (TaskItem item : firstDeptItems) {
|
||||
if (item.getReceiverId() != null && !notifiedReceiverIds.contains(item.getReceiverId())) {
|
||||
notifiedReceiverIds.add(item.getReceiverId());
|
||||
sendTaskAssignedNotification(task, item.getReceiverId(), isPreAssigned);
|
||||
}
|
||||
if (task.getPlatformName() != null && !task.getPlatformName().isEmpty()) {
|
||||
content.append("**平台**:").append(task.getPlatformName()).append(" \n");
|
||||
}
|
||||
if (task.getSpuInfo() != null && !task.getSpuInfo().isEmpty()) {
|
||||
content.append("**SPU**:").append(task.getSpuInfo()).append(" \n");
|
||||
}
|
||||
if (task.getTaskSubType() != null && !task.getTaskSubType().isEmpty()) {
|
||||
content.append("**任务类型**:").append(task.getTaskSubType()).append(" \n");
|
||||
}
|
||||
|
||||
content.append(" \n");
|
||||
|
||||
// 查询子任务获取任务类型明细
|
||||
List<TaskItem> taskItems = taskItemMapper.selectList(
|
||||
new LambdaQueryWrapper<TaskItem>()
|
||||
.eq(TaskItem::getTaskId, task.getId())
|
||||
.orderByAsc(TaskItem::getGroupNo)
|
||||
);
|
||||
|
||||
if (!taskItems.isEmpty()) {
|
||||
content.append("**任务明细**: \n");
|
||||
for (TaskItem item : taskItems) {
|
||||
// 通过任务类型ID获取接单部门名称
|
||||
String deptName = "未指定";
|
||||
if (item.getTaskTypeId() != null) {
|
||||
try {
|
||||
DemandType demandType = configService.getDemandTypeById(item.getTaskTypeId());
|
||||
if (demandType != null && demandType.getAllowedDeptIds() != null && !demandType.getAllowedDeptIds().isEmpty()) {
|
||||
String[] deptIds = demandType.getAllowedDeptIds().split(",");
|
||||
Long firstDeptId = Long.parseLong(deptIds[0].trim());
|
||||
Department dept = departmentMapper.selectById(firstDeptId);
|
||||
if (dept != null) {
|
||||
deptName = dept.getDeptName();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("获取部门名称失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化工时显示
|
||||
String hoursDisplay = formatEstimatedHours(item.getEstimatedHours());
|
||||
|
||||
content.append(" \n");
|
||||
content.append("▸ **").append(deptName).append("** | ")
|
||||
.append(item.getTotalScore()).append("分 | ")
|
||||
.append(hoursDisplay).append(" \n");
|
||||
|
||||
// 解析并显示任务类型明细
|
||||
if (item.getTypeDetails() != null && !item.getTypeDetails().isEmpty()) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<java.util.Map<String, Object>> typeDetails =
|
||||
objectMapper.readValue(item.getTypeDetails(), List.class);
|
||||
for (java.util.Map<String, Object> detail : typeDetails) {
|
||||
String typeName = String.valueOf(detail.get("typeName"));
|
||||
Object qtyObj = detail.get("quantity");
|
||||
Object scoreObj = detail.get("totalScore");
|
||||
int qty = qtyObj instanceof Number ? ((Number) qtyObj).intValue() : 1;
|
||||
String score = scoreObj != null ? String.valueOf(scoreObj) : "0";
|
||||
content.append(" └ ").append(typeName)
|
||||
.append(" ×").append(qty)
|
||||
.append(" = ").append(score).append("分 \n");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("解析任务类型明细失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 没有子任务时显示总积分和工时
|
||||
content.append("**任务积分**:").append(task.getScore()).append(" 分 \n");
|
||||
if (task.getEstimatedHours() != null) {
|
||||
content.append("**预估工时**:").append(formatEstimatedHours(task.getEstimatedHours())).append(" \n");
|
||||
}
|
||||
}
|
||||
|
||||
content.append(" \n");
|
||||
|
||||
// 发起人信息
|
||||
if (task.getPublisherName() != null && !task.getPublisherName().isEmpty()) {
|
||||
content.append("**发起人**:").append(task.getPublisherName()).append(" \n");
|
||||
}
|
||||
if (task.getPublisherDeptName() != null && !task.getPublisherDeptName().isEmpty()) {
|
||||
content.append("**发起部门**:").append(task.getPublisherDeptName()).append(" \n");
|
||||
}
|
||||
|
||||
// 指派信息
|
||||
content.append("**指派给**:").append(receiverName).append(" \n");
|
||||
|
||||
content.append(" \n");
|
||||
content.append("点击下方按钮查看详情");
|
||||
|
||||
// 2. 发送个人钉钉通知给设计师
|
||||
Notification notification = new Notification();
|
||||
notification.setReceiverId(finalReceiverId);
|
||||
notification.setTitle("任务已指派");
|
||||
notification.setContent(content.toString());
|
||||
notification.setNotificationType("TASK_ASSIGNED");
|
||||
notification.setRelatedType("task");
|
||||
notification.setRelatedId(task.getId());
|
||||
notification.setPushDingtalk(1); // 推送到钉钉
|
||||
notificationService.sendNotification(notification);
|
||||
log.info("任务指派个人通知已发送给设计师: userId={}", finalReceiverId);
|
||||
|
||||
// 3. 只有非预先指定的任务才发送群通知(预先指定的任务只发送个人通知)
|
||||
if (!isPreAssigned) {
|
||||
// 发送群通知并@指定的设计师,使用相同的内容模版
|
||||
java.util.List<String> atMobiles = receiverPhone != null ?
|
||||
java.util.Arrays.asList(receiverPhone) : null;
|
||||
dingTalkService.sendRobotMessage("任务已指派", content.toString(), atMobiles);
|
||||
log.info("任务指派群通知已发送,@手机号: {}", receiverPhone);
|
||||
} else {
|
||||
log.info("任务【{}】为预先指定任务,只发送个人通知,不发送群通知", task.getTitle());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("发送任务指派通知失败", e);
|
||||
}
|
||||
} else {
|
||||
log.info("流水线任务【{}】已通知 {} 个设计师", task.getTitle(), notifiedReceiverIds.size());
|
||||
} else if (finalReceiverId != null) {
|
||||
// 普通任务:只通知一个设计师
|
||||
sendTaskAssignedNotification(task, finalReceiverId, isPreAssigned);
|
||||
notifiedReceiverIds.add(finalReceiverId);
|
||||
log.info("普通任务【{}】已通知设计师: {}", task.getTitle(), finalReceiverId);
|
||||
}
|
||||
|
||||
// 如果没有指定设计师(发布到大厅),发送群通知
|
||||
if (notifiedReceiverIds.isEmpty()) {
|
||||
log.info("任务【{}】已发布到任务大厅,准备发送钉钉群通知", task.getTitle());
|
||||
// 任务发布到大厅,发送钉钉群机器人通知
|
||||
// 注意:钉钉Markdown换行需要两个空格+换行符
|
||||
@ -906,4 +796,151 @@ public class TaskApprovalService {
|
||||
// WorkHoursCalculator 返回 "--" 表示无效,这里保持 "未设置" 的语义
|
||||
return "--".equals(formatted) ? "未设置" : formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送任务指派通知给设计师
|
||||
* @param task 任务
|
||||
* @param receiverId 接收人ID
|
||||
* @param isPreAssigned 是否预先指定
|
||||
*/
|
||||
private void sendTaskAssignedNotification(Task task, Long receiverId, boolean isPreAssigned) {
|
||||
try {
|
||||
com.designhub.entity.User receiver = userMapper.selectById(receiverId);
|
||||
if (receiver == null) {
|
||||
log.warn("接收人不存在: {}", receiverId);
|
||||
return;
|
||||
}
|
||||
String receiverName = receiver.getRealName();
|
||||
String receiverPhone = receiver.getPhone();
|
||||
|
||||
// 构建通知内容
|
||||
StringBuilder content = new StringBuilder();
|
||||
|
||||
// 基本信息
|
||||
content.append("**任务名称**:").append(task.getTitle()).append(" \n");
|
||||
content.append("**任务编号**:").append(task.getTaskNo()).append(" \n");
|
||||
|
||||
// 任务详情
|
||||
if (task.getBrandName() != null && !task.getBrandName().isEmpty()) {
|
||||
content.append("**品牌**:").append(task.getBrandName()).append(" \n");
|
||||
}
|
||||
if (task.getPlatformName() != null && !task.getPlatformName().isEmpty()) {
|
||||
content.append("**平台**:").append(task.getPlatformName()).append(" \n");
|
||||
}
|
||||
if (task.getSpuInfo() != null && !task.getSpuInfo().isEmpty()) {
|
||||
content.append("**SPU**:").append(task.getSpuInfo()).append(" \n");
|
||||
}
|
||||
if (task.getTaskSubType() != null && !task.getTaskSubType().isEmpty()) {
|
||||
content.append("**任务类型**:").append(task.getTaskSubType()).append(" \n");
|
||||
}
|
||||
|
||||
content.append(" \n");
|
||||
|
||||
// 查询该设计师负责的子任务
|
||||
List<TaskItem> receiverItems = taskItemMapper.selectList(
|
||||
new LambdaQueryWrapper<TaskItem>()
|
||||
.eq(TaskItem::getTaskId, task.getId())
|
||||
.eq(TaskItem::getReceiverId, receiverId)
|
||||
.orderByAsc(TaskItem::getGroupNo)
|
||||
);
|
||||
|
||||
if (!receiverItems.isEmpty()) {
|
||||
content.append("**您负责的任务明细**: \n");
|
||||
for (TaskItem item : receiverItems) {
|
||||
// 通过任务类型ID获取接单部门名称
|
||||
String deptName = "未指定";
|
||||
if (item.getTaskTypeId() != null) {
|
||||
try {
|
||||
DemandType demandType = configService.getDemandTypeById(item.getTaskTypeId());
|
||||
if (demandType != null && demandType.getAllowedDeptIds() != null && !demandType.getAllowedDeptIds().isEmpty()) {
|
||||
String[] deptIds = demandType.getAllowedDeptIds().split(",");
|
||||
Long firstDeptId = Long.parseLong(deptIds[0].trim());
|
||||
Department dept = departmentMapper.selectById(firstDeptId);
|
||||
if (dept != null) {
|
||||
deptName = dept.getDeptName();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("获取部门名称失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化工时显示
|
||||
String hoursDisplay = formatEstimatedHours(item.getEstimatedHours());
|
||||
|
||||
content.append(" \n");
|
||||
content.append("▸ **").append(deptName).append("** | ")
|
||||
.append(item.getTotalScore()).append("分 | ")
|
||||
.append(hoursDisplay).append(" \n");
|
||||
|
||||
// 解析并显示任务类型明细
|
||||
if (item.getTypeDetails() != null && !item.getTypeDetails().isEmpty()) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<java.util.Map<String, Object>> typeDetails =
|
||||
objectMapper.readValue(item.getTypeDetails(), List.class);
|
||||
for (java.util.Map<String, Object> detail : typeDetails) {
|
||||
String typeName = String.valueOf(detail.get("typeName"));
|
||||
Object qtyObj = detail.get("quantity");
|
||||
Object scoreObj = detail.get("totalScore");
|
||||
int qty = qtyObj instanceof Number ? ((Number) qtyObj).intValue() : 1;
|
||||
String score = scoreObj != null ? String.valueOf(scoreObj) : "0";
|
||||
content.append(" └ ").append(typeName)
|
||||
.append(" ×").append(qty)
|
||||
.append(" = ").append(score).append("分 \n");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("解析任务类型明细失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 没有子任务时显示总积分和工时
|
||||
content.append("**任务积分**:").append(task.getScore()).append(" 分 \n");
|
||||
if (task.getEstimatedHours() != null) {
|
||||
content.append("**预估工时**:").append(formatEstimatedHours(task.getEstimatedHours())).append(" \n");
|
||||
}
|
||||
}
|
||||
|
||||
content.append(" \n");
|
||||
|
||||
// 发起人信息
|
||||
if (task.getPublisherName() != null && !task.getPublisherName().isEmpty()) {
|
||||
content.append("**发起人**:").append(task.getPublisherName()).append(" \n");
|
||||
}
|
||||
if (task.getPublisherDeptName() != null && !task.getPublisherDeptName().isEmpty()) {
|
||||
content.append("**发起部门**:").append(task.getPublisherDeptName()).append(" \n");
|
||||
}
|
||||
|
||||
// 指派信息
|
||||
content.append("**指派给**:").append(receiverName).append(" \n");
|
||||
|
||||
content.append(" \n");
|
||||
content.append("点击下方按钮查看详情");
|
||||
|
||||
// 发送个人钉钉通知给设计师
|
||||
Notification notification = new Notification();
|
||||
notification.setReceiverId(receiverId);
|
||||
notification.setTitle("任务已指派");
|
||||
notification.setContent(content.toString());
|
||||
notification.setNotificationType("TASK_ASSIGNED");
|
||||
notification.setRelatedType("task");
|
||||
notification.setRelatedId(task.getId());
|
||||
notification.setPushDingtalk(1); // 推送到钉钉
|
||||
notificationService.sendNotification(notification);
|
||||
log.info("任务指派个人通知已发送给设计师: userId={}, name={}", receiverId, receiverName);
|
||||
|
||||
// 只有非预先指定的任务才发送群通知(预先指定的任务只发送个人通知)
|
||||
if (!isPreAssigned) {
|
||||
java.util.List<String> atMobiles = receiverPhone != null ?
|
||||
java.util.Arrays.asList(receiverPhone) : null;
|
||||
dingTalkService.sendRobotMessage("任务已指派", content.toString(), atMobiles);
|
||||
log.info("任务指派群通知已发送,@手机号: {}", receiverPhone);
|
||||
} else {
|
||||
log.info("任务【{}】为预先指定任务,只发送个人通知,不发送群通知", task.getTitle());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("发送任务指派通知失败: receiverId={}", receiverId, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user