万纯 6f6bf341dd feat: 优化plugin-access和plugin-layout
plugin-access:
1. 添加<Access />组件控制权限
2. 添加v-access指令控制权限
3. 权限的范围改为role和accesId的并集

plugin-layout:
1. 判断是否加载locale插件改为使用api.hasPlugins
2. 提示优化
2021-01-14 12:56:31 +08:00

155 lines
3.9 KiB
Smarty
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { reactive, computed, inject } from "vue";
import createDirective from "./createDirective";
import createComponent from "./createComponent";
const accessKey = Symbol("plugin-access");
function isPromise(obj) {
return (
!!obj &&
(typeof obj === "object" || typeof obj === "function") &&
typeof obj.then === "function"
);
}
const state = reactive({
roles: {{{REPLACE_ROLES}}},
currentRoleId: "",
currentAccessIds: [],
});
const rolePromiseList = [];
const accessPromiseList = [];
const getAllowAccessIds = () => {
const roleAccessIds = state.roles[state.currentRoleId];
if (Array.isArray(roleAccessIds) && roleAccessIds.length > 0) {
return state.currentAccessIds.concat(roleAccessIds);
}
return state.currentAccessIds;
};
const _syncSetAccessIds = (promise) => {
accessPromiseList.push(promise);
promise
.then((accessIds) => {
setAccess(accessIds);
})
.catch((e) => {
console.error(e);
})
.then(() => {
const index = accessPromiseList.indexOf(promise);
if (index !== -1) {
accessPromiseList.splice(index, 1);
}
});
};
const setAccess = (accessIds) => {
if (isPromise(accessIds)) {
return _syncSetAccessIds(accessIds);
}
if (!Array.isArray(accessIds)) {
throw new Error("[plugin-access]: argument to the setAccess() must be array or promise");
}
state.currentAccessIds = accessIds;
};
const addAccess = (accessId) => {
if (typeof accessId !== 'string') {
throw new Error("[plugin-access]: argument to the addAccess() must be string");
}
state.currentAccessIds.push(accessId);
};
const _syncSetRoleId = (promise) => {
rolePromiseList.push(promise);
promise
.then((roleId) => {
setRole(roleId);
})
.catch((e) => {
console.error(e);
})
.then(() => {
const index = rolePromiseList.indexOf(promise);
if (index !== -1) {
rolePromiseList.splice(index, 1);
}
});
};
const setRole = async (roleId) => {
if (isPromise(roleId)) {
return _syncSetRoleId(roleId);
}
if (typeof roleId !== "string") {
throw new Error("[plugin-access]: argument to the setRole() must be string or promise");
}
state.currentRoleId = roleId;
};
const match = (path, accessIds) => {
if(path === null || path === undefined) {
return false;
}
if (!Array.isArray(accessIds) || accessIds.length === 0) {
return false;
}
path = path.split("?")[0];
// "/"path为
if (path === "") {
path = "/";
}
const len = accessIds.length;
for (let i = 0; i < len; i++) {
if (path === accessIds[i]) {
return true;
}
// *
const reg = new RegExp(`^${accessIds[i].replace("*", ".+")}$`);
if (reg.test(path)) {
return true;
}
}
return false;
};
const hasLoading = () => {
return rolePromiseList.length || accessPromiseList.length;
};
const hasAccess = async (path) => {
if (!hasLoading()) {
return match(path, getAllowAccessIds());
}
await Promise.all(rolePromiseList.concat(accessPromiseList));
return match(path, getAllowAccessIds());
};
export const install = (app) => {
const allowPageIds = computed(getAllowAccessIds);
const useAccess = (path) => {
const result = computed(() => {
return match(path, allowPageIds.value);
});
return result;
};
app.provide(accessKey, useAccess);
app.directive("access", createDirective(useAccess));
app.component("Access", createComponent(useAccess));
};
export const access = {
hasAccess,
hasLoading,
setRole,
setAccess,
addAccess
};
export const useAccess = (path) => {
return inject(accessKey)(path);
};