路由上传一个ui_control参数(uint32类型)控制页面UI显隐

前言:传一个uint32类型的值,通过 按位或操作符(|)来设置ui_control的值,通过按位与操作符(&)来检测是否显示或隐藏

简单介绍一下两个概念:

按位与操作符和按位或操作符都是二进制位运算符。

  1. 按位与操作符(&):对于每一个二进制位,只有当两个操作数的对应位都为1时,结果的对应位才为1,否则为0。例如,5(二进制101) & 3(二进制011)的结果是1(二进制001)。

  2. 按位或操作符(|):对于每一个二进制位,只要两个操作数的对应位有一个为1时,结果的对应位就为1,否则为0。例如,5(二进制101) | 3(二进制011)的结果是7(二进制111)。

这两种操作符在计算机编程中常用于位操作,如设置位标志、清除位标志、切换位标志等。

一、demo1:路由传一个ui_control,用高16位设置允许修改,修改位用第17位检测

javascript 复制代码
var ui_control = 0;
ui_control = (ui_control | (1 << 17));
console.log(ui_control) // 131072

这时候ui_control参数传131072,在页面中做检测看是否允许修改

javascript 复制代码
var uiControl = Number(new URLSearchParams(location.search).get('uiControl'))
if ((control & (1 << 17)) !== 0) {
    console.log("1 表示允许修改");
} else {
    console.log("0 表示不允许修改");
}

二、demo2:路由传一个ui_control,同时控制修改和导出权限,修改位用第17位检测,导出位用第16位检测

既允许修改也允许导出

javascript 复制代码
var ui_control = 0;
ui_control = (ui_control | (1 << 17));
ui_control = (ui_control | (1 << 16));

console.log(ui_control) // 196608

这时候ui_control参数传196608,通过与运算检测第16位导出是否为1,第17位修改是否为1,就能知道是否有对应权限了

咱们封装一个方法出来

javascript 复制代码
// keys 传一个检测权限的key,比如下面Edit编辑,Export导出
const getUiControlBinaryContent = (keys) => {
	var uicontrol = Number(new URLSearchParams(location.search).get('uiControl'))
	let uint32 = new Uint32Array(1);
	uint32[0] = uicontrol;
	const action = new Map<string, any>([
		['Edit', checkUnitBuffer(uint32[0], 17)], // 第17位
		['Export', checkUnitBuffer(uint32[0], 16)], // 第16位
	]);
	return keys ? action.get(keys) : 0;
};

// 与或位控制
const checkUnitBuffer = (control: number, idx: number) => {
	if (!idx) return 0; 
	if ((control & (1 << idx)) !== 0) {
		return 1; // 表示有该操作权限
	} else {
		return 0; // 表示没有该操作权限
	}
};

这样的话在这些操作的地方就直接能调用getUiControlBinaryContent方法传对应key值就可以知道是否有权限了

上面的demo1和demo2是高16位的检测,接下来我们简单说一下低16位的检测

三、举个例子:低0,1,2,3,4位控制,高16,17位控制总结

1、设置ui_control:我这里用简单的html元素来展示,你们按照自己的库来做就行,最终的UI_Control就是路由上要传的参数

javascript 复制代码
/**
 * unit32 生成 ui_control
 *  ● 是否修改:ui_control & (1 << 17)
    ● 是否导出:ui_control & (1 << 16)
    ● 是否显示思维导图:ui_control & (1 << 4)
    ● 是否显示原文:ui_control & (1 << 3)
    ● 是否显示章节概率:ui_control & (1 << 2)
    ● 是否显示全文总结:ui_control & (1 << 1)
    ● 是否显示视频:ui_control & 1
 */
function onCreateUiControl() {
    var ui_control = 0;
    const Edit = document.getElementById("Edit");
    const Export1 = document.getElementById("Export");
    const VideoPre = document.getElementById("VideoPre");
    const MindMap = document.getElementById("MindMap");
    const AllText = document.getElementById("AllText");
    const ChapterOverviewt = document.getElementById("ChapterOverviewt");
    const FullTextSummary = document.getElementById("FullTextSummary");

    if (Edit.checked) ui_control = (ui_control | (1 << 17));
    if (Export1.checked) ui_control = (ui_control | (1 << 16));
    if (VideoPre.checked) ui_control = (ui_control | 1);
    if (MindMap.checked) ui_control = (ui_control | (1 << 4));
    if (AllText.checked) ui_control = (ui_control | (1 << 3));
    if (ChapterOverviewt.checked) ui_control = (ui_control | (1 << 2));
    if (FullTextSummary.checked) ui_control = (ui_control | (1 << 1));

    document.getElementById("ui_control").value = ui_control;

    // TODO 这个最终的ui_control就是你设置的上面某些功能的权限了
    console.log("ui_control", ui_control);
}

2、检测ui_control权限:调用getUiControlBinaryContent(key)传对应keys值做检测

javascript 复制代码
/**
 * UI控制使用16位位运算 https://tool.oschina.net/hexconvert
 * 每一位可以看作一个开关,1表示开,0表示关。
 * 右移操作符>>和按位与操作符&来获取每一位的值。如果某一位的值为1,那么对应的开关就是开,如果某一位的值为0,那么对应的开关就是关。
 * 	● 是否修改:ui_control & (1 << 17)
	● 是否导出:ui_control & (1 << 16)
	● 是否显示思维导图:ui_control & (1 << 4)
	● 是否显示原文:ui_control & (1 << 3)
	● 是否显示章节概率:ui_control & (1 << 2)
	● 是否显示全文总结:ui_control & (1 << 1)
	● 是否显示视频:ui_control & 1
 */
const getUiControlBinaryContent = (keys) => {
	var uicontrol = Number(new URLSearchParams(location.search).get('uiControl'))
	let uint32 = new Uint32Array(1);
	uint32[0] = uicontrol;
	const action = new Map<string, any>([
		['Edit', checkUnitBuffer(uint32[0], 17)],
		['Export', checkUnitBuffer(uint32[0], 16)],
		['VideoPre', checkUnitVideo(uint32[0], 1)],
		['MindMap', checkUnitBuffer(uint32[0], 4)],
		['AllText', checkUnitBuffer(uint32[0], 3)],
		['ChapterOverviewt', checkUnitBuffer(uint32[0], 2)],
		['FullTextSummary', checkUnitBuffer(uint32[0], 1)]
	]);
	return keys ? action.get(keys) : 0;
};

// 与或位控制
const checkUnitBuffer = (control: number, idx: number) => {
	if (!idx) return 0; 
	if ((control & (1 << idx)) !== 0) {
		return 1;
	} else {
		return 0;
	}
};

总结:路由上设置ui_control,通过第几位用按位或来设置具体值,用按位与来解析是否有权限