package com.yunhai.userbase.utils; import java.util.HashMap; import java.util.Map; /** * 课程节点 64 bit 复合 ID 工具类(无实体、纯静态) * rootType 根节点类别【资源,辅导,题库,试卷,专项】 * nodeType 虚拟节点类型【根节点,教材(辅)目录节点,年级节点,教材知识树节点,真实节点】 * stage 学段【2小学 3初中 4高中】 * grade 年级 1-12 */ public final class NodeIdUtil { /* ===================== 位宽 ===================== */ private static final int ROOT_BITS = 4; private static final int TYPE_BITS = 4; // 原 biz private static final int SUBJ_BITS = 20; private static final int STAGE_BITS = 4; private static final int GRADE_BITS = 4; private static final int NODE_BITS = 28; private static final long ROOT_MASK = mask(ROOT_BITS); private static final long TYPE_MASK = mask(TYPE_BITS); private static final long SUBJ_MASK = mask(SUBJ_BITS); private static final long STAGE_MASK = mask(STAGE_BITS); private static final long GRADE_MASK = mask(GRADE_BITS); private static final long NODE_MASK = mask(NODE_BITS); /* ===================== 编码 ===================== */ public static long encode(Integer rootType, String subject, Integer stage, Integer nodeType, Integer grade, Integer nodeId) { int subNum = subjectToInt(subject); long root = (rootType == null ? 0 : rootType) & ROOT_MASK; long type = (nodeType == null ? 0 : nodeType) & TYPE_MASK; long stageVal = (stage == null ? 0 : stage) & STAGE_MASK; long gradeVal = (grade == null ? 0 : grade) & GRADE_MASK; long nodeVal = (nodeId == null ? 0 : nodeId) & NODE_MASK; return root << (TYPE_BITS + SUBJ_BITS + STAGE_BITS + GRADE_BITS + NODE_BITS) | type << (SUBJ_BITS + STAGE_BITS + GRADE_BITS + NODE_BITS) | (long) subNum << (STAGE_BITS + GRADE_BITS + NODE_BITS) | stageVal << (GRADE_BITS + NODE_BITS) | gradeVal << NODE_BITS | nodeVal; } /* ===================== 解码 ===================== */ public static Map decode(long compositeId) { Map map = new HashMap<>(6); int root = (int) ((compositeId >>> (TYPE_BITS + SUBJ_BITS + STAGE_BITS + GRADE_BITS + NODE_BITS)) & ROOT_MASK); int type = (int) ((compositeId >>> (SUBJ_BITS + STAGE_BITS + GRADE_BITS + NODE_BITS)) & TYPE_MASK); int subNum = (int) ((compositeId >>> (STAGE_BITS + GRADE_BITS + NODE_BITS)) & SUBJ_MASK); int stage = (int) ((compositeId >>> (GRADE_BITS + NODE_BITS)) & STAGE_MASK); int grade = (int) ((compositeId >>> (NODE_BITS)) & GRADE_MASK); int nodeId = (int) (compositeId & NODE_MASK); map.put("rootType", root == 0 ? null : root); map.put("nodeType", type == 0 ? null : type); map.put("subject", intToSubject(subNum)); map.put("stage", stage == 0 ? null : stage); map.put("grade", grade == 0 ? null : grade); map.put("nodeId", nodeId == 0 ? null : nodeId); return map; } /* ===================== subject 工具 ===================== */ private static int subjectToInt(String subject) { if (subject == null || !subject.startsWith("SUB")) return 0; return Integer.parseUnsignedInt(subject.substring(3)); } private static String intToSubject(int n) { if (n == 0) return null; return (n <= 6) ? "SUB0" + n : "SUB" + n; } private static long mask(int bits) { return (1L << bits) - 1; } private NodeIdUtil() {} }