51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
/**
|
|
* 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,
|
|
};
|
|
}
|