mirror of
https://github.com/WeBankFinTech/fes.js.git
synced 2025-04-06 03:59:53 +08:00
feat: 优化plugin-access和plugin-layout
plugin-access: 1. 添加<Access />组件控制权限 2. 添加v-access指令控制权限 3. 权限的范围改为role和accesId的并集 plugin-layout: 1. 判断是否加载locale插件改为使用api.hasPlugins 2. 提示优化
This commit is contained in:
parent
c91d0b5845
commit
6f6bf341dd
2
packages/fes-plugin-access/README.md
Normal file
2
packages/fes-plugin-access/README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
|
@ -23,6 +23,7 @@ export default (api) => {
|
|||||||
|
|
||||||
const absRuntimeFilePath = join(namespace, 'runtime.js');
|
const absRuntimeFilePath = join(namespace, 'runtime.js');
|
||||||
|
|
||||||
|
const generatedOnce = false;
|
||||||
api.onGenerateFiles(() => {
|
api.onGenerateFiles(() => {
|
||||||
// 文件写出
|
// 文件写出
|
||||||
const { roles = {} } = api.config.access || {};
|
const { roles = {} } = api.config.access || {};
|
||||||
@ -37,12 +38,10 @@ export default (api) => {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
api.writeTmpFile({
|
api.copyTmpFiles({
|
||||||
path: absRuntimeFilePath,
|
namespace,
|
||||||
content: readFileSync(
|
path: join(__dirname, 'runtime'),
|
||||||
join(__dirname, 'runtime/runtime.tpl'),
|
ignore: ['.tpl']
|
||||||
'utf-8'
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { reactive, computed, inject } from "vue";
|
import { reactive, computed, inject } from "vue";
|
||||||
|
import createDirective from "./createDirective";
|
||||||
|
import createComponent from "./createComponent";
|
||||||
|
|
||||||
const accessKey = Symbol("plugin-access");
|
const accessKey = Symbol("plugin-access");
|
||||||
|
|
||||||
@ -20,17 +22,11 @@ const rolePromiseList = [];
|
|||||||
const accessPromiseList = [];
|
const accessPromiseList = [];
|
||||||
|
|
||||||
const getAllowAccessIds = () => {
|
const getAllowAccessIds = () => {
|
||||||
if (
|
|
||||||
Array.isArray(state.currentAccessIds) &&
|
|
||||||
state.currentAccessIds.length > 0
|
|
||||||
) {
|
|
||||||
return state.currentAccessIds;
|
|
||||||
}
|
|
||||||
const roleAccessIds = state.roles[state.currentRoleId];
|
const roleAccessIds = state.roles[state.currentRoleId];
|
||||||
if (Array.isArray(roleAccessIds) && roleAccessIds.length > 0) {
|
if (Array.isArray(roleAccessIds) && roleAccessIds.length > 0) {
|
||||||
return roleAccessIds;
|
return state.currentAccessIds.concat(roleAccessIds);
|
||||||
}
|
}
|
||||||
return [];
|
return state.currentAccessIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
const _syncSetAccessIds = (promise) => {
|
const _syncSetAccessIds = (promise) => {
|
||||||
@ -55,11 +51,18 @@ const setAccess = (accessIds) => {
|
|||||||
return _syncSetAccessIds(accessIds);
|
return _syncSetAccessIds(accessIds);
|
||||||
}
|
}
|
||||||
if (!Array.isArray(accessIds)) {
|
if (!Array.isArray(accessIds)) {
|
||||||
throw new Error("[plugin-access]: pageIds必须是array");
|
throw new Error("[plugin-access]: argument to the setAccess() must be array or promise");
|
||||||
}
|
}
|
||||||
state.currentAccessIds = accessIds;
|
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) => {
|
const _syncSetRoleId = (promise) => {
|
||||||
rolePromiseList.push(promise);
|
rolePromiseList.push(promise);
|
||||||
promise
|
promise
|
||||||
@ -82,12 +85,15 @@ const setRole = async (roleId) => {
|
|||||||
return _syncSetRoleId(roleId);
|
return _syncSetRoleId(roleId);
|
||||||
}
|
}
|
||||||
if (typeof roleId !== "string") {
|
if (typeof roleId !== "string") {
|
||||||
throw new Error("[plugin-access]: roleId必须是string");
|
throw new Error("[plugin-access]: argument to the setRole() must be string or promise");
|
||||||
}
|
}
|
||||||
state.currentRoleId = roleId;
|
state.currentRoleId = roleId;
|
||||||
};
|
};
|
||||||
|
|
||||||
const match = (path, accessIds) => {
|
const match = (path, accessIds) => {
|
||||||
|
if(path === null || path === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!Array.isArray(accessIds) || accessIds.length === 0) {
|
if (!Array.isArray(accessIds) || accessIds.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -131,6 +137,8 @@ export const install = (app) => {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
app.provide(accessKey, useAccess);
|
app.provide(accessKey, useAccess);
|
||||||
|
app.directive("access", createDirective(useAccess));
|
||||||
|
app.component("Access", createComponent(useAccess));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const access = {
|
export const access = {
|
||||||
@ -138,6 +146,7 @@ export const access = {
|
|||||||
hasLoading,
|
hasLoading,
|
||||||
setRole,
|
setRole,
|
||||||
setAccess,
|
setAccess,
|
||||||
|
addAccess
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useAccess = (path) => {
|
export const useAccess = (path) => {
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
export default function createComponent(useAccess) {
|
||||||
|
return (props, { slots }) => {
|
||||||
|
const access = useAccess(props.id);
|
||||||
|
if (!access.value || !slots.default) return null;
|
||||||
|
return slots.default();
|
||||||
|
};
|
||||||
|
}
|
46
packages/fes-plugin-access/src/runtime/createDirective.js
Normal file
46
packages/fes-plugin-access/src/runtime/createDirective.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { watch } from 'vue';
|
||||||
|
|
||||||
|
const cache = new WeakMap();
|
||||||
|
const setDispaly = (el, access) => {
|
||||||
|
if (access.value) {
|
||||||
|
el.style.display = el._display;
|
||||||
|
} else {
|
||||||
|
el.style.display = 'none';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export default function createDirective(useAccess) {
|
||||||
|
return {
|
||||||
|
beforeMount(el) {
|
||||||
|
const ctx = {};
|
||||||
|
ctx.watch = (path) => {
|
||||||
|
el._display = el._display || el.style.display;
|
||||||
|
const access = useAccess(path);
|
||||||
|
setDispaly(el, access);
|
||||||
|
return watch(access, () => {
|
||||||
|
setDispaly(el, access);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
cache.set(el, ctx);
|
||||||
|
},
|
||||||
|
mounted(el, binding) {
|
||||||
|
const ctx = cache.get(el);
|
||||||
|
if (ctx.unwatch) {
|
||||||
|
ctx.unwatch();
|
||||||
|
}
|
||||||
|
ctx.unwatch = ctx.watch(binding.value);
|
||||||
|
},
|
||||||
|
updated(el, binding) {
|
||||||
|
const ctx = cache.get(el);
|
||||||
|
if (ctx.unwatch) {
|
||||||
|
ctx.unwatch();
|
||||||
|
}
|
||||||
|
ctx.unwatch = ctx.watch(binding.value);
|
||||||
|
},
|
||||||
|
beforeUnmount(el) {
|
||||||
|
const ctx = cache.get(el);
|
||||||
|
if (ctx.unwatch) {
|
||||||
|
ctx.unwatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import { access, install } from "./core";
|
import { plugin, ApplyPluginsType } from '@@/core/coreExports';
|
||||||
import { plugin, ApplyPluginsType } from "@@/core/coreExports";
|
import { access, install } from './core';
|
||||||
|
|
||||||
export function onRouterCreated({ router }) {
|
export function onRouterCreated({ router }) {
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
@ -14,11 +14,11 @@ export function onRouterCreated({ router }) {
|
|||||||
next();
|
next();
|
||||||
} else {
|
} else {
|
||||||
const runtimeConfig = plugin.applyPlugins({
|
const runtimeConfig = plugin.applyPlugins({
|
||||||
key: "access",
|
key: 'access',
|
||||||
type: ApplyPluginsType.modify,
|
type: ApplyPluginsType.modify,
|
||||||
initialValue: null,
|
initialValue: {}
|
||||||
});
|
});
|
||||||
if (runtimeConfig.noAccessHandler && typeof runtimeConfig.noAccessHandler === "function") {
|
if (runtimeConfig.noAccessHandler && typeof runtimeConfig.noAccessHandler === 'function') {
|
||||||
runtimeConfig.noAccessHandler(router, to, from);
|
runtimeConfig.noAccessHandler(router, to, from);
|
||||||
}
|
}
|
||||||
next(false);
|
next(false);
|
||||||
@ -27,5 +27,5 @@ export function onRouterCreated({ router }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function onAppCreated({ app }) {
|
export function onAppCreated({ app }) {
|
||||||
install(app)
|
install(app);
|
||||||
}
|
}
|
@ -26,6 +26,10 @@ export default (api) => {
|
|||||||
api.onGenerateFiles(() => {
|
api.onGenerateFiles(() => {
|
||||||
const { name } = api.pkg;
|
const { name } = api.pkg;
|
||||||
|
|
||||||
|
const HAS_LOCALE = api.hasPlugins(['@webank/fes-plugin-locale']);
|
||||||
|
|
||||||
|
const HAS_ACCESS = api.hasPlugins(['@webank/fes-plugin-access']);
|
||||||
|
|
||||||
// .fes配置
|
// .fes配置
|
||||||
const userConfig = {
|
const userConfig = {
|
||||||
title: name,
|
title: name,
|
||||||
@ -38,7 +42,7 @@ export default (api) => {
|
|||||||
readFileSync(join(__dirname, 'runtime/index.tpl'), 'utf-8'),
|
readFileSync(join(__dirname, 'runtime/index.tpl'), 'utf-8'),
|
||||||
{
|
{
|
||||||
REPLACE_USER_CONFIG: JSON.stringify(userConfig),
|
REPLACE_USER_CONFIG: JSON.stringify(userConfig),
|
||||||
HAS_LOCALE: api.pkg.dependencies?.['@webank/fes-plugin-locale']
|
HAS_LOCALE
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { unref, computed } from 'vue';
|
import { unref, computed } from 'vue';
|
||||||
import { useAccess } from '@webank/fes';
|
import { useAccess } from '../../plugin-access/core';
|
||||||
|
|
||||||
if (!useAccess) {
|
if (!useAccess) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'[plugin-layout]: pLugin-layout依赖plugin-access,请先安装plugin-access!'
|
'[plugin-layout]: pLugin-layout depends on plugin-access,please install plugin-access first!'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
<div class="haizekuo">
|
<div class="haizekuo">
|
||||||
<div>国际化: {{t("test")}}</div>
|
<div>国际化: {{t("test")}}</div>
|
||||||
fes & 拉夫德鲁 <br />
|
fes & 拉夫德鲁 <br />
|
||||||
accessOnepicess: {{accessOnepicess}}
|
<access :id="accessId"> accessOnepicess1 <input /> </access>
|
||||||
|
<div v-access="accessId"> accessOnepicess2 <input /> </div>
|
||||||
<input />
|
<input />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -15,27 +16,33 @@
|
|||||||
<script>
|
<script>
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
import {
|
import {
|
||||||
useAccess, useRouter, useI18n, setLocale
|
access, useAccess, useRouter, useI18n, setLocale
|
||||||
} from '@webank/fes';
|
} from '@webank/fes';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
const fes = ref('fes upgrade to vue3');
|
const fes = ref('fes upgrade to vue3');
|
||||||
const accessOnepicess = useAccess('/onepiece');
|
const accessOnepicess = useAccess('/onepiece1');
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const accessId = ref('/onepiece1');
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log(router);
|
console.log(router);
|
||||||
console.log('mounted1!!');
|
console.log('mounted1!!');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setLocale('en-US');
|
setLocale('en-US');
|
||||||
|
access.addAccess('/onepiece1');
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
setTimeout(() => {
|
||||||
|
accessId.value = '11';
|
||||||
|
}, 4000);
|
||||||
// router.push('/onepiece');
|
// router.push('/onepiece');
|
||||||
});
|
});
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log('mounted2!!');
|
console.log('mounted2!!');
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
accessId,
|
||||||
fes,
|
fes,
|
||||||
accessOnepicess,
|
accessOnepicess,
|
||||||
t
|
t
|
||||||
|
Loading…
x
Reference in New Issue
Block a user