|
|
@@ -1,42 +1,172 @@
|
|
|
-var list =[]
|
|
|
+import { myRequest } from './api.js';
|
|
|
+
|
|
|
+// 权限列表的内存缓存。
|
|
|
+// 首次成功读取后缓存在内存里,后续不再依赖每次渲染都同步读取存储,
|
|
|
+// 既避免了“数据还没写入存储就被读取”的偶发时序问题,也省去重复 JSON.parse。
|
|
|
+var permissionList = null;
|
|
|
+// 正在进行的拉取请求,避免并发重复调用接口
|
|
|
+var fetchingPromise = null;
|
|
|
+
|
|
|
+// 从本地存储同步读取并刷新缓存。
|
|
|
+// 读到有效数据时返回解析后的数组;否则返回 null(缓存保持不变)。
|
|
|
+function loadListFromStorage() {
|
|
|
+ try {
|
|
|
+ var raw = uni.getStorageSync('jurisdiction');
|
|
|
+ if (raw) {
|
|
|
+ var parsed = JSON.parse(raw);
|
|
|
+ if (Array.isArray(parsed)) {
|
|
|
+ permissionList = parsed;
|
|
|
+ return permissionList;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('[QueryPermission] 解析 jurisdiction 失败:', e);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+}
|
|
|
+
|
|
|
+// 从服务端拉取权限列表并写入存储 + 缓存。
|
|
|
+// 幂等:已缓存且非强制刷新时直接返回;并发调用共享同一个请求。
|
|
|
+// 用于“未经过首页”等无法依赖本地存储已写入的特殊场景。
|
|
|
+function fetchPermissionList(options = {}) {
|
|
|
+ const { force = false } = options;
|
|
|
+ if (!force && permissionList && permissionList.length) {
|
|
|
+ return Promise.resolve(permissionList);
|
|
|
+ }
|
|
|
+ if (fetchingPromise) {
|
|
|
+ return fetchingPromise;
|
|
|
+ }
|
|
|
+ fetchingPromise = (async () => {
|
|
|
+ try {
|
|
|
+ const res = await myRequest({
|
|
|
+ url: '/api/api_gateway?method=user.login.user_login_info',
|
|
|
+ data: { is_app: 1 },
|
|
|
+ });
|
|
|
+ const menuList = [];
|
|
|
+ (res || []).forEach((item) => {
|
|
|
+ if (item && item.children) {
|
|
|
+ menuList.push(...item.children);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const children = [];
|
|
|
+ menuList.forEach((item) => {
|
|
|
+ if (item && item.children) {
|
|
|
+ children.push(...item.children);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ permissionList = children;
|
|
|
+ // 同步落盘,保证其他读取 storage 的地方也能拿到
|
|
|
+ uni.setStorageSync('jurisdiction', JSON.stringify(children));
|
|
|
+ return children;
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('[QueryPermission] 拉取权限列表失败:', e);
|
|
|
+ return permissionList || [];
|
|
|
+ } finally {
|
|
|
+ fetchingPromise = null;
|
|
|
+ }
|
|
|
+ })();
|
|
|
+ return fetchingPromise;
|
|
|
+}
|
|
|
+
|
|
|
+// 重置权限数据:清空内存缓存,并默认清除本地存储中的权限列表。
|
|
|
+// 用于退出登录、一键登录(切换账号)等场景,防止上一个用户的权限残留。
|
|
|
+function resetPermissionList(options = {}) {
|
|
|
+ const { keepStorage = false } = options;
|
|
|
+ permissionList = null;
|
|
|
+ fetchingPromise = null;
|
|
|
+ if (!keepStorage) {
|
|
|
+ try {
|
|
|
+ uni.removeStorageSync('jurisdiction');
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('[QueryPermission] 清除 jurisdiction 存储失败:', e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
function QueryPermission(id) {
|
|
|
- if(uni.getStorageSync("jurisdiction")){
|
|
|
- list = JSON.parse(uni.getStorageSync("jurisdiction"))
|
|
|
- }
|
|
|
- for (var i = 0; i < list.length; i++) {
|
|
|
- if (list[i].children) {
|
|
|
- var data = list[i].children
|
|
|
- for (var j = 0; j < data.length; j++) {
|
|
|
- var item = data[j]
|
|
|
- if (item.pur_id == id) {
|
|
|
- return true
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return false
|
|
|
+ // 优先使用内存缓存;缓存为空时尝试同步读取一次存储
|
|
|
+ // (覆盖“模块初始化时存储还没写入、但调用时已写入”的情况)
|
|
|
+ var list = permissionList || loadListFromStorage() || [];
|
|
|
+ for (var i = 0; i < list.length; i++) {
|
|
|
+ if (list[i] && list[i].children) {
|
|
|
+ var data = list[i].children;
|
|
|
+ for (var j = 0; j < data.length; j++) {
|
|
|
+ var item = data[j];
|
|
|
+ if (item && item.pur_id == id) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
}
|
|
|
-function getUserPermission(){
|
|
|
- let list = []
|
|
|
- if(uni.getStorageSync("jurisdiction")){
|
|
|
- list = JSON.parse(uni.getStorageSync("jurisdiction"))
|
|
|
- }
|
|
|
- return list
|
|
|
+function getUserPermission() {
|
|
|
+ if (!permissionList) {
|
|
|
+ loadListFromStorage();
|
|
|
+ }
|
|
|
+ return permissionList || [];
|
|
|
}
|
|
|
-function getPermissionById(node = getUserPermission(),id) {
|
|
|
- for (const child of node) {
|
|
|
- if(id == child.pur_id){
|
|
|
- return child.children || []
|
|
|
- }
|
|
|
- if(child.children){
|
|
|
- let result = getPermissionById(child.children,id)
|
|
|
- if(result){
|
|
|
- return result
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return null
|
|
|
+function getPermissionById(node = getUserPermission(), id) {
|
|
|
+ for (const child of node) {
|
|
|
+ if (id == child.pur_id) {
|
|
|
+ return child.children || [];
|
|
|
+ }
|
|
|
+ if (child.children) {
|
|
|
+ let result = getPermissionById(child.children, id);
|
|
|
+ if (result) {
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
}
|
|
|
-export {
|
|
|
- QueryPermission,getPermissionById,getUserPermission
|
|
|
+
|
|
|
+/**
|
|
|
+ * 异步预加载权限列表,解决“数据未写入存储就执行 QueryPermission”的时序问题。
|
|
|
+ * 在依赖权限的详情页 onLoad 中 `await ensurePermissionLoaded()`,
|
|
|
+ * 可保证页面渲染前权限数据已就绪:
|
|
|
+ * - 缓存或本地存储里已有 -> 立即返回;
|
|
|
+ * - 本地没有(未经过首页等特殊入口)-> 默认直接请求接口拉取;
|
|
|
+ * - 也可设置 fromServer:false 仅轮询等待本地存储写入完成。
|
|
|
+ * @param {Object} options
|
|
|
+ * @param {number} options.timeout 最长等待时间(ms),默认 8000(仅轮询模式生效)
|
|
|
+ * @param {number} options.interval 轮询间隔(ms),默认 100(仅轮询模式生效)
|
|
|
+ * @param {boolean} options.fromServer 本地无数据时是否请求接口拉取,默认 true
|
|
|
+ * @returns {Promise<Array>}
|
|
|
+ */
|
|
|
+function ensurePermissionLoaded(options = {}) {
|
|
|
+ const { timeout = 8000, interval = 100, fromServer = true } = options;
|
|
|
+ // 已就绪:缓存或存储里有数据,直接返回
|
|
|
+ if (permissionList && permissionList.length) {
|
|
|
+ return Promise.resolve(permissionList);
|
|
|
+ }
|
|
|
+ if (loadListFromStorage()) {
|
|
|
+ return Promise.resolve(permissionList);
|
|
|
+ }
|
|
|
+ // 未经过首页等特殊情况:本地没有权限数据,默认直接请求接口拉取
|
|
|
+ if (fromServer) {
|
|
|
+ return fetchPermissionList();
|
|
|
+ }
|
|
|
+ // fromServer=false:仅轮询等待本地存储写入完成
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ const start = Date.now();
|
|
|
+ const timer = setInterval(() => {
|
|
|
+ if (loadListFromStorage()) {
|
|
|
+ clearInterval(timer);
|
|
|
+ resolve(permissionList);
|
|
|
+ } else if (Date.now() - start >= timeout) {
|
|
|
+ clearInterval(timer);
|
|
|
+ console.warn('[QueryPermission] 预加载超时,权限数据可能未就绪');
|
|
|
+ resolve([]);
|
|
|
+ }
|
|
|
+ }, interval);
|
|
|
+ });
|
|
|
}
|
|
|
+export {
|
|
|
+ QueryPermission,
|
|
|
+ getPermissionById,
|
|
|
+ getUserPermission,
|
|
|
+ ensurePermissionLoaded,
|
|
|
+ fetchPermissionList,
|
|
|
+ resetPermissionList,
|
|
|
+};
|