init: UserBaseService (backend + deploy + scripts)
ci-userbase-service / build-and-push (push) Successful in 40s

This commit is contained in:
chenxing
2026-08-10 14:50:22 +08:00
commit 4ec19486e0
234 changed files with 15604 additions and 0 deletions
@@ -0,0 +1,86 @@
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<String, Object> decode(long compositeId) {
Map<String, Object> 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() {}
}