/** * NodeId 解码工具 */ const ROOT_BITS = 4, TYPE_BITS = 4, SUBJ_BITS = 20, STAGE_BITS = 4, GRADE_BITS = 4, NODE_BITS = 28; const ROOT_MASK = mask(ROOT_BITS), TYPE_MASK = mask(TYPE_BITS), SUBJ_MASK = mask(SUBJ_BITS), STAGE_MASK = mask(STAGE_BITS), GRADE_MASK = mask(GRADE_BITS), NODE_MASK = mask(NODE_BITS); function mask(bits: number) { return (1n << BigInt(bits)) - 1n; } function intToSubject(n: number) { if (n === 0) return null; return n <= 6 ? `SUB0${n}` : `SUB${n}`; } /** * 解码入口:long → 普通对象 * @param {string|number} compositeId 后端传来的 long 字符串或数字 * @returns {Object} */ export function decodeNodeId(compositeId: number | string) { const id = BigInt(compositeId); const root = Number((id >> BigInt(TYPE_BITS + SUBJ_BITS + STAGE_BITS + GRADE_BITS + NODE_BITS)) & ROOT_MASK); const type = Number((id >> BigInt(SUBJ_BITS + STAGE_BITS + GRADE_BITS + NODE_BITS)) & TYPE_MASK); const subNum = Number((id >> BigInt(STAGE_BITS + GRADE_BITS + NODE_BITS)) & SUBJ_MASK); const stage = Number((id >> BigInt(GRADE_BITS + NODE_BITS)) & STAGE_MASK); const grade = Number((id >> BigInt(NODE_BITS)) & GRADE_MASK); const nodeId = Number(id & NODE_MASK); return { rootType: root === 0 ? null : root, nodeType: type === 0 ? null : type, subject: intToSubject(subNum), stage: stage === 0 ? null : stage, grade: grade === 0 ? null : grade, nodeId: nodeId === 0 ? null : nodeId, }; }