| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- 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) {
- // 优先使用内存缓存;缓存为空时尝试同步读取一次存储
- // (覆盖“模块初始化时存储还没写入、但调用时已写入”的情况)
- 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() {
- 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;
- }
- /**
- * 异步预加载权限列表,解决“数据未写入存储就执行 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,
- };
|