mirror of
https://github.com/WeBankFinTech/fes.js.git
synced 2025-04-06 03:59:53 +08:00
feat: plugin-access 70%
This commit is contained in:
parent
8fc1141056
commit
4fcdd6c641
@ -4,7 +4,7 @@ import { join } from 'path';
|
||||
// utils must build before core
|
||||
// runtime must build before renderer-react
|
||||
|
||||
const headPkgs = ['fes-runtime', 'fes-core', 'fes', 'fes-plugin-built-in', 'fes-plugin-request', 'fes-plugin-access'];
|
||||
const headPkgs = ['fes-runtime', 'fes-core', 'fes', 'fes-plugin-built-in', 'fes-plugin-request', 'fes-plugin-access', 'fes-plugin-initstate'];
|
||||
const tailPkgs = [];
|
||||
// const otherPkgs = readdirSync(join(__dirname, 'packages')).filter(
|
||||
// (pkg) =>
|
||||
@ -18,4 +18,4 @@ export default {
|
||||
cjs: { type: 'babel', lazy: false },
|
||||
disableTypeCheck: true,
|
||||
pkgs: [...headPkgs, ...otherPkgs, ...tailPkgs],
|
||||
};
|
||||
};
|
@ -109,12 +109,12 @@ export default (api) => {
|
||||
});
|
||||
});
|
||||
|
||||
// api.addExports(() => [
|
||||
// {
|
||||
// exportAll: true,
|
||||
// source: absoluteFilePath
|
||||
// }
|
||||
// ]);
|
||||
api.addExports(() => [
|
||||
{
|
||||
specifiers: ['access', 'useAccess'],
|
||||
source: absoluteFilePath
|
||||
}
|
||||
]);
|
||||
|
||||
api.addRuntimePlugin(() => `@@/${absRuntimeFilePath}`);
|
||||
};
|
||||
|
@ -1,18 +0,0 @@
|
||||
import { hasAccess } from './core';
|
||||
|
||||
export function onRouterCreated({ router }) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
let path;
|
||||
if (to.matched.length === 1) {
|
||||
path = to.matched[0].path;
|
||||
} else {
|
||||
path = to.path;
|
||||
}
|
||||
const canRoute = await hasAccess(path);
|
||||
if (canRoute) {
|
||||
next();
|
||||
} else {
|
||||
next(false);
|
||||
}
|
||||
});
|
||||
}
|
@ -1,48 +1,137 @@
|
||||
const roles = {{{REPLACE_ROLES}}};
|
||||
import { reactive, computed } from "vue";
|
||||
|
||||
let allowPageIds = [];
|
||||
function isPromise(obj) {
|
||||
return (
|
||||
!!obj &&
|
||||
(typeof obj === "object" || typeof obj === "function") &&
|
||||
typeof obj.then === "function"
|
||||
);
|
||||
}
|
||||
|
||||
const get = () => Promise.all(allowPageIds).then(data => data.reduce((merge, cur) => merge.concat(cur), []));
|
||||
const state = reactive({
|
||||
roles: {{{REPLACE_ROLES}}},
|
||||
currentRoleId: "",
|
||||
currentAccessIds: ["/"],
|
||||
});
|
||||
|
||||
export const setPageIds = (pageIds) => {
|
||||
if (Array.isArray(pageIds)) {
|
||||
allowPageIds = pageIds.map(id => Promise.resolve(id));
|
||||
} else {
|
||||
allowPageIds = [Promise.resolve(pageIds)];
|
||||
const rolePromiseList = [];
|
||||
const accessPromiseList = [];
|
||||
|
||||
const getAllowAccessIds = () => {
|
||||
if (
|
||||
Array.isArray(state.currentAccessIds) &&
|
||||
state.currentAccessIds.length > 0
|
||||
) {
|
||||
return state.currentAccessIds;
|
||||
}
|
||||
const roleAccessIds = state.roles[state.currentRoleId];
|
||||
if (Array.isArray(roleAccessIds) && roleAccessIds.length > 0) {
|
||||
return roleAccessIds;
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
export const setRoleId = async (roleId) => {
|
||||
console.log('setRole');
|
||||
const _roleId = await Promise.resolve(roleId);
|
||||
if (typeof _roleId !== 'string') {
|
||||
throw new Error(
|
||||
'[plugin-access]: roleId必须是string或者Promise的结果必须是string',
|
||||
);
|
||||
}
|
||||
setPageIds(roles[_roleId]);
|
||||
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);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const hasAccess = async (path) => {
|
||||
const allowPage = await get();
|
||||
if (!Array.isArray(allowPage) || allowPage.length === 0) {
|
||||
const setAccess = (accessIds) => {
|
||||
if (isPromise(accessIds)) {
|
||||
return _syncSetAccessIds(accessIds);
|
||||
}
|
||||
if (!Array.isArray(accessIds)) {
|
||||
throw new Error("[plugin-access]: pageIds必须是array");
|
||||
}
|
||||
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]: roleId必须是string");
|
||||
}
|
||||
state.currentRoleId = roleId;
|
||||
};
|
||||
|
||||
const match = (path, accessIds) => {
|
||||
if (!Array.isArray(accessIds) || accessIds.length === 0) {
|
||||
return false;
|
||||
}
|
||||
path = path.split('?')[0];
|
||||
path = path.split("?")[0];
|
||||
// 进入"/"路由时,此时path为“”
|
||||
if (path === '') {
|
||||
path = '/';
|
||||
if (path === "") {
|
||||
path = "/";
|
||||
}
|
||||
const len = allowPage.length;
|
||||
const len = accessIds.length;
|
||||
for (let i = 0; i < len; i++) {
|
||||
if (path === allowPage[i]) {
|
||||
if (path === accessIds[i]) {
|
||||
return true;
|
||||
}
|
||||
// 支持*匹配
|
||||
const reg = new RegExp(`^${allowPage[i].replace('*', '.+')}$`);
|
||||
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())
|
||||
};
|
||||
|
||||
const allowPageIds = computed(getAllowAccessIds);
|
||||
|
||||
export const access = {
|
||||
hasAccess,
|
||||
hasLoading,
|
||||
setRole,
|
||||
setAccess
|
||||
}
|
||||
|
||||
export const useAccess = (path) => {
|
||||
const result = computed(() => {
|
||||
return match(path, allowPageIds.value);
|
||||
});
|
||||
return result;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { hasAccess } from './core';
|
||||
import { access } from './core';
|
||||
|
||||
export function onRouterCreated({ router }) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
@ -8,11 +8,11 @@ export function onRouterCreated({ router }) {
|
||||
} else {
|
||||
path = to.path;
|
||||
}
|
||||
const canRoute = await hasAccess(path);
|
||||
const canRoute = await access.hasAccess(path);
|
||||
if (canRoute) {
|
||||
next();
|
||||
} else {
|
||||
next(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -21,4 +21,11 @@ export default function (api) {
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
api.addExports(() => [
|
||||
{
|
||||
specifiers: ['router'],
|
||||
source: absoluteFilePath
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
@ -31,3 +31,5 @@ export const createRouter = () => {
|
||||
|
||||
return router;
|
||||
};
|
||||
|
||||
export { router }
|
3
packages/fes-plugin-initstate/.fatherrc.js
Normal file
3
packages/fes-plugin-initstate/.fatherrc.js
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
disableTypeCheck: false,
|
||||
};
|
19
packages/fes-plugin-initstate/package.json
Normal file
19
packages/fes-plugin-initstate/package.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "@webank/fes-plugin-initstate",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"module": "dist/index.esm.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@webank/fes": "^2.0.0"
|
||||
}
|
||||
}
|
21
packages/fes-plugin-initstate/src/index.js
Normal file
21
packages/fes-plugin-initstate/src/index.js
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
const namespace = 'plugin-initstate';
|
||||
|
||||
export default (api) => {
|
||||
api.addRuntimePluginKey(() => 'initstate');
|
||||
|
||||
const absRuntimeFilePath = join(namespace, 'runtime.js');
|
||||
|
||||
api.onGenerateFiles(() => {
|
||||
api.writeTmpFile({
|
||||
path: absRuntimeFilePath,
|
||||
content: readFileSync(join(__dirname, 'template/runtime.tpl'), 'utf-8')
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
api.addRuntimePlugin(() => `@@/${absRuntimeFilePath}`);
|
||||
};
|
28
packages/fes-plugin-initstate/src/template/runtime.tpl
Normal file
28
packages/fes-plugin-initstate/src/template/runtime.tpl
Normal file
@ -0,0 +1,28 @@
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export function rootContainer(childComponent, args){
|
||||
console.log(childComponent, args)
|
||||
const App = {
|
||||
setup() {
|
||||
const state = reactive({
|
||||
loading: true
|
||||
})
|
||||
onMounted(()=>{
|
||||
setTimeout(() => {
|
||||
state.loading = false
|
||||
}, 3000);
|
||||
})
|
||||
return () => {
|
||||
if(state.loading){
|
||||
return (
|
||||
<>
|
||||
<div>loading</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
return <childComponent />
|
||||
}
|
||||
}
|
||||
}
|
||||
return App
|
||||
}
|
@ -34,7 +34,6 @@
|
||||
"dependencies": {
|
||||
"vue": "^3.0.2",
|
||||
"@webank/fes": "^2.0.0",
|
||||
"@webank/fes-plugin-request": "^1.0.0",
|
||||
"@webank/fes-plugin-access": "^1.0.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +0,0 @@
|
||||
// 配置fes-plugin-request
|
||||
export const request = {};
|
@ -1,17 +1,32 @@
|
||||
<template>
|
||||
<div>
|
||||
fes & 拉夫德鲁
|
||||
fes & 拉夫德鲁 <br />
|
||||
accessOnepicess: {{accessOnepicess}}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from 'vue';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { useAccess, access, router } from '@webank/fes';
|
||||
|
||||
const { setAccess } = access;
|
||||
export default {
|
||||
setup() {
|
||||
const fes = ref('fes upgrade to vue3');
|
||||
const accessOnepicess = useAccess('/onepiece');
|
||||
onMounted(() => {
|
||||
console.log('mounted!');
|
||||
console.log(router);
|
||||
setAccess(new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
resolve(['/', '/onepiece']);
|
||||
}, 3000);
|
||||
}));
|
||||
// router.push('/onepiece');
|
||||
});
|
||||
return {
|
||||
fes
|
||||
fes,
|
||||
accessOnepicess
|
||||
};
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user