diff --git a/backend/src/main/java/com/designhub/service/TaskItemService.java b/backend/src/main/java/com/designhub/service/TaskItemService.java index d7f5dbb..69f9f53 100644 --- a/backend/src/main/java/com/designhub/service/TaskItemService.java +++ b/backend/src/main/java/com/designhub/service/TaskItemService.java @@ -811,13 +811,14 @@ public class TaskItemService { taskItemMapper.updateById(item); } - // 发送钉钉群机器人通知(与第一轮格式一致) + // 发送钉钉群机器人通知(与第一轮格式完全一致) + // 注意:钉钉Markdown换行需要两个空格+换行符 try { String title = "新任务发布"; StringBuilder content = new StringBuilder(); // 基本信息 - content.append("**任务名称**:").append(mainTask.getTitle()).append("(第").append(groupNo).append("组) \n"); + content.append("**任务名称**:").append(mainTask.getTitle()).append(" \n"); content.append("**任务编号**:").append(mainTask.getTaskNo()).append(" \n"); // 任务详情 @@ -831,68 +832,60 @@ public class TaskItemService { content.append("**SPU**:").append(mainTask.getSpuInfo()).append(" \n"); } if (mainTask.getTaskSubType() != null && !mainTask.getTaskSubType().isEmpty()) { - String taskSubTypeName = convertTaskSubTypeToName(mainTask.getTaskSubType()); - content.append("**任务类型**:").append(taskSubTypeName).append(" \n"); + content.append("**任务类型**:").append(mainTask.getTaskSubType()).append(" \n"); } content.append(" \n"); - // 任务明细(与第一轮格式一致) - content.append("**任务明细**: \n"); - for (TaskItem item : groupItems) { - // 通过任务类型ID获取接单部门名称 - String deptName = "未指定"; - if (item.getTaskTypeId() != null) { - try { - com.designhub.entity.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()); - com.designhub.entity.Department dept = departmentMapper.selectById(firstDeptId); - if (dept != null) { - deptName = dept.getDeptName(); + // 任务明细(与第一轮格式完全一致) + if (!groupItems.isEmpty()) { + content.append("**任务明细**: \n"); + for (TaskItem item : groupItems) { + // 通过任务类型ID获取接单部门名称 + String deptName = "未指定"; + if (item.getTaskTypeId() != null) { + try { + com.designhub.entity.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()); + com.designhub.entity.Department dept = departmentMapper.selectById(firstDeptId); + if (dept != null) { + deptName = dept.getDeptName(); + } } + } catch (Exception e) { + log.warn("获取部门名称失败: {}", e.getMessage()); } - } catch (Exception e) { - log.warn("获取部门名称失败: {}", e.getMessage()); } - } - - // 格式化工时显示 - String hoursDisplay = "未知"; - if (item.getEstimatedHours() != null) { - java.math.BigDecimal hours = item.getEstimatedHours(); - if (hours.compareTo(java.math.BigDecimal.ONE) >= 0) { - hoursDisplay = hours.intValue() + "小时"; - } else { - int minutes = hours.multiply(java.math.BigDecimal.valueOf(60)).intValue(); - hoursDisplay = minutes + "分钟"; - } - } - - content.append(" \n"); - content.append("▸ **").append(deptName).append("** | ") - .append(item.getTotalScore() != null ? item.getTotalScore() : 0).append("分 | ") - .append(hoursDisplay).append(" \n"); - - // 解析并显示任务类型明细 - if (item.getTypeDetails() != null && !item.getTypeDetails().isEmpty()) { - try { - @SuppressWarnings("unchecked") - java.util.List> typeDetails = - objectMapper.readValue(item.getTypeDetails(), java.util.List.class); - for (java.util.Map 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"); + + // 格式化工时显示(与第一轮一致) + 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") + java.util.List> typeDetails = + objectMapper.readValue(item.getTypeDetails(), java.util.List.class); + for (java.util.Map 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()); } - } catch (Exception e) { - log.warn("解析任务类型明细失败: {}", e.getMessage()); } } } @@ -910,10 +903,15 @@ public class TaskItemService { content.append(" \n"); content.append("点击下方按钮查看详情"); - dingTalkService.sendRobotMessage(title, content.toString()); - log.info("第 {} 组 {} 个子任务已发布到任务大厅,已发送钉钉群通知", groupNo, groupItems.size()); + log.info("准备调用钉钉机器人发送消息,title={}", title); + boolean success = dingTalkService.sendRobotMessage(title, content.toString()); + if (success) { + log.info("第{}组子任务钉钉群通知发送成功", groupNo); + } else { + log.warn("第{}组子任务钉钉群通知发送失败(返回false)", groupNo); + } } catch (Exception e) { - log.error("发送钉钉群通知失败:taskId={}, groupNo={}", taskId, groupNo, e); + log.error("发送钉钉群通知异常:taskId={}, groupNo={}, error={}", taskId, groupNo, e.getMessage(), e); // 通知发送失败不影响主流程 } } @@ -1263,4 +1261,25 @@ public class TaskItemService { log.debug("未找到配置的部门,返回 null"); return null; } + + /** + * 格式化工时显示(与TaskApprovalService一致) + */ + private String formatEstimatedHours(java.math.BigDecimal hours) { + if (hours == null) { + return "未设置"; + } + int totalHours = hours.intValue(); + int days = totalHours / 24; + int remainingHours = totalHours % 24; + + StringBuilder sb = new StringBuilder(); + if (days > 0) { + sb.append(days).append("天"); + } + if (remainingHours > 0 || days == 0) { + sb.append(remainingHours).append("小时"); + } + return sb.toString(); + } }