package com.zeodao.reminder.model; import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; /** * 禅道任务实体类 - 使用JsonNode实现动态字段解析 * * @author Zeodao * @version 2.0.0 */ @Data public class ZentaoTask { private String id; private String name; private String type; private String status; private String pri; private String assignedTo; private String assignedToRealName; private String assignedDate; private String deadline; private String estStarted; private String realStarted; private String finishedBy; private String finishedDate; private String canceledBy; private String canceledDate; private String closedBy; private String closedDate; private String closedReason; private String lastEditedBy; private String lastEditedDate; private String openedBy; private String openedDate; private String desc; private String project; private String story; private String storyTitle; private String module; private String estimate; private String consumed; private String left; private String progress; private String color; private String deleted; /** * 从JsonNode创建ZentaoTask对象,安全地提取字段 */ public static ZentaoTask fromJsonNode(JsonNode node) { ZentaoTask task = new ZentaoTask(); // 安全地提取字段,如果字段不存在或类型不匹配,使用默认值 task.setId(getStringValue(node, "id")); task.setName(getStringValue(node, "name")); task.setType(getStringValue(node, "type")); task.setStatus(getStringValue(node, "status")); task.setPri(getStringValue(node, "pri")); task.setAssignedTo(getStringValue(node, "assignedTo")); task.setAssignedToRealName(getStringValue(node, "assignedToRealName")); task.setAssignedDate(getStringValue(node, "assignedDate")); task.setDeadline(getStringValue(node, "deadline")); task.setEstStarted(getStringValue(node, "estStarted")); task.setRealStarted(getStringValue(node, "realStarted")); task.setFinishedBy(getStringValue(node, "finishedBy")); task.setFinishedDate(getStringValue(node, "finishedDate")); task.setCanceledBy(getStringValue(node, "canceledBy")); task.setCanceledDate(getStringValue(node, "canceledDate")); task.setClosedBy(getStringValue(node, "closedBy")); task.setClosedDate(getStringValue(node, "closedDate")); task.setClosedReason(getStringValue(node, "closedReason")); task.setLastEditedBy(getStringValue(node, "lastEditedBy")); task.setLastEditedDate(getStringValue(node, "lastEditedDate")); task.setOpenedBy(getStringValue(node, "openedBy")); task.setOpenedDate(getStringValue(node, "openedDate")); task.setDesc(getStringValue(node, "desc")); task.setProject(getStringValue(node, "project")); task.setStory(getStringValue(node, "story")); task.setStoryTitle(getStringValue(node, "storyTitle")); task.setModule(getStringValue(node, "module")); task.setEstimate(getStringValue(node, "estimate")); task.setConsumed(getStringValue(node, "consumed")); task.setLeft(getStringValue(node, "left")); task.setProgress(getStringValue(node, "progress")); task.setColor(getStringValue(node, "color")); task.setDeleted(getStringValue(node, "deleted")); return task; } /** * 安全地从JsonNode中提取字符串值 */ private static String getStringValue(JsonNode node, String fieldName) { if (node == null || !node.has(fieldName)) { return null; } JsonNode fieldNode = node.get(fieldName); if (fieldNode == null || fieldNode.isNull()) { return null; } // 如果是对象类型(如openedBy),尝试提取其中的字符串字段 if (fieldNode.isObject()) { // 对于用户对象,尝试提取account或realname if (fieldNode.has("account")) { return fieldNode.get("account").asText(); } else if (fieldNode.has("realname")) { return fieldNode.get("realname").asText(); } else if (fieldNode.has("id")) { return fieldNode.get("id").asText(); } return null; } // 对于基本类型,直接转换为字符串 return fieldNode.asText(); } /** * 判断任务是否未完成 */ public boolean isIncomplete() { return !"done".equals(status) && !"closed".equals(status) && !"cancel".equals(status); } /** * 判断任务是否已过期 */ public boolean isOverdue() { if (deadline == null || deadline.isEmpty() || "0000-00-00".equals(deadline)) { return false; } // 简单的日期比较,实际项目中应该使用更严格的日期处理 return deadline.compareTo(java.time.LocalDate.now().toString()) < 0; } /** * 获取优先级描述 */ public String getPriorityDesc() { switch (pri) { case "1": return "高"; case "2": return "中"; case "3": return "低"; case "4": return "最低"; default: return "普通"; } } }