2021-11-16 21:24:25 +08:00

158 lines
4.0 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, unref, computed, inject } from "vue";
import createDirective from "./createDirective";
import createComponent from "./createComponent";
import {isPlainObject} from "{{{ lodashPath }}}";
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(isPlainObject(accessIds)){
if(accessIds.accessIds){
setAccess(accessIds.accessIds);
}
if(accessIds.roleId){
setRole(accessIds.roleId);
}
return
}
if (!Array.isArray(accessIds)) {
throw new Error("[plugin-access]: argument to the setAccess() must be array or promise or object");
}
state.currentAccessIds = accessIds;
};
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 isDataReady = () => {
return rolePromiseList.length || accessPromiseList.length;
};
const hasAccess = async (path) => {
if (!isDataReady()) {
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(unref(path), allowPageIds.value);
});
return result;
};
app.provide(accessKey, useAccess);
app.directive("access", createDirective(useAccess));
app.component("Access", createComponent(useAccess));
};
export const access = {
hasAccess,
isDataReady,
setRole,
setAccess,
getAccess: getAllowAccessIds,
};
export const useAccess = (path) => {
return inject(accessKey)(path);
};