<script setup lang="ts">
|
import type { TreeActionType } from '@jnpf/ui';
|
|
import { computed, nextTick, onMounted, reactive, ref, toRefs, unref } from 'vue';
|
|
import { BasicLeftTree } from '@jnpf/ui';
|
|
import { getOrgAndPosSelector } from '#/api/permission/organize';
|
import { getRoleList } from '#/api/permission/role';
|
import { $t } from '#/locales';
|
|
import CommonAuth from './components/CommonAuth.vue';
|
import MenuAuth from './components/MenuAuth.vue';
|
|
defineOptions({ name: 'PermissionAuth' });
|
|
interface State {
|
activeKey: string;
|
roleActiveKey: string;
|
menuType: string;
|
orgTreeData: any[];
|
orgLoading: boolean;
|
roleTreeData: any[];
|
roleLoading: boolean;
|
orgQuery: any;
|
objectId: string;
|
objectType: string;
|
key: number;
|
}
|
interface clearSearchValue {
|
clearSearchValue: Function;
|
}
|
|
const state = reactive<State>({
|
activeKey: 'organize',
|
roleActiveKey: 'user',
|
menuType: 'Menu',
|
orgTreeData: [],
|
orgLoading: false,
|
roleTreeData: [],
|
roleLoading: false,
|
orgQuery: {
|
id: '0',
|
type: 'organize',
|
},
|
objectId: '',
|
objectType: '',
|
key: 0,
|
});
|
const { activeKey, roleActiveKey, menuType } = toRefs(state);
|
const permissionTypeList: any[] = [
|
{ id: 'Menu', fullName: '菜单权限' },
|
{ id: 'Flow', fullName: '流程权限' },
|
{ id: 'Print', fullName: '打印文件' },
|
];
|
const orgTreeRef = ref<Nullable<TreeActionType>>(null);
|
const roleTreeRef = ref<Nullable<clearSearchValue & TreeActionType>>(null);
|
const menuAuthRef = ref<any>(null);
|
const commonAuthRef = ref<any>(null);
|
|
const getOrgTreeBindValue = computed(() => {
|
const key = Date.now();
|
const data: any = {
|
key,
|
showSearch: false,
|
defaultExpandAll: false,
|
loadData: onLoadData,
|
loading: state.orgLoading,
|
onSelect: handleSelect,
|
treeData: state.orgTreeData,
|
};
|
return data;
|
});
|
const getRoleTreeBindValue = computed(() => {
|
const data: any = {
|
showToolbar: false,
|
defaultExpandAll: false,
|
loading: state.roleLoading,
|
onSelect: handleSelect,
|
treeData: state.roleTreeData,
|
};
|
return data;
|
});
|
const getBindValues = computed(() => ({ id: state.objectId, objectType: state.objectType, type: state.menuType, key: state.key }));
|
const getRealRef = computed(() => (state.menuType == 'Menu' ? unref(menuAuthRef) : unref(commonAuthRef)));
|
|
function getOrgTreeData() {
|
state.orgLoading = true;
|
getOrgAndPosSelector(state.orgQuery)
|
.then((res) => {
|
state.orgTreeData = res.data.list;
|
if (state.orgTreeData.length > 0 && state.orgQuery.id == '0') {
|
nextTick(() => {
|
const keys = [state.orgTreeData[0].id];
|
getOrgTree().setSelectedKeys(keys);
|
handleSelect(keys[0], state.orgTreeData[0]);
|
});
|
}
|
state.orgLoading = false;
|
})
|
.catch(() => {
|
state.orgLoading = false;
|
});
|
}
|
function getOrgTree() {
|
const tree = unref(orgTreeRef);
|
if (!tree) {
|
throw new Error('tree is null!');
|
}
|
return tree;
|
}
|
function onLoadData(node) {
|
state.orgQuery.id = node.id;
|
state.orgQuery.type = node.type;
|
return new Promise((resolve: (value?: unknown) => void) => {
|
getOrgAndPosSelector(state.orgQuery).then((res) => {
|
const list = res.data.list;
|
getOrgTree().updateNodeByKey(node.eventKey, { isLeaf: list.length === 0, children: list });
|
resolve();
|
});
|
});
|
}
|
function handleSelect(key, item?) {
|
if (key.length === 0 || state.objectId === key) return;
|
state.objectId = key;
|
if (state.activeKey == 'organize') state.objectType = item.type;
|
state.key = Date.now();
|
}
|
function getRoleTreeData() {
|
state.roleLoading = true;
|
getRoleList({ type: state.roleActiveKey || 'user' })
|
.then((res) => {
|
state.roleTreeData = res.data.list;
|
if (state.roleTreeData.length) {
|
nextTick(() => {
|
const keys = [state.roleTreeData[0].id];
|
getRoleTree().setSelectedKeys(keys);
|
handleSelect(keys[0]);
|
});
|
}
|
state.roleLoading = false;
|
})
|
.catch(() => {
|
state.roleLoading = false;
|
});
|
}
|
function getRoleTree() {
|
const tree = unref(roleTreeRef);
|
if (!tree) {
|
throw new Error('tree is null!');
|
}
|
return tree;
|
}
|
function onTypeChange(key) {
|
if (key == 'role') {
|
getRoleTreeData();
|
state.objectType = key;
|
} else {
|
state.orgQuery = {
|
id: '0',
|
type: 'organize',
|
};
|
getOrgTreeData();
|
}
|
}
|
function onRoleTypeChange() {
|
getRoleTree()?.clearSearchValue();
|
getRoleTreeData();
|
}
|
function onMenuTypeChange() {
|
state.key = Date.now();
|
}
|
function handlePrev() {
|
unref(getRealRef)?.handlePrev();
|
}
|
function handleNext() {
|
unref(getRealRef)?.handleNext();
|
}
|
function handleCheckAll(boo) {
|
unref(getRealRef)?.handleCheckAll(boo);
|
}
|
function handleExpandAll(boo) {
|
unref(getRealRef)?.handleExpandAll(boo);
|
}
|
function handleSubmit() {
|
unref(getRealRef)?.handleSubmit();
|
}
|
|
onMounted(() => {
|
getOrgTreeData();
|
});
|
</script>
|
<template>
|
<div class="relative flex h-full flex-col">
|
<a-alert show-icon type="warning" class="mb-[10px]">
|
<template #message>
|
组织、权限模块的详细说明介绍,请查阅使用帮助,<a class="link-text" target="_blank" href="https://usermanuals.jnpfsoft.com/#/docs/11007">点击查看</a>
|
</template>
|
</a-alert>
|
<div class="jnpf-content-wrapper">
|
<div class="jnpf-content-wrapper-left !w-[260px]">
|
<a-tabs v-model:active-key="activeKey" class="jnpf-content-wrapper-tabs tabs-contain average-tabs" @change="onTypeChange">
|
<a-tab-pane key="organize" tab="组织权限" class="flex">
|
<BasicLeftTree ref="orgTreeRef" class="w-full" v-bind="getOrgTreeBindValue" />
|
</a-tab-pane>
|
<a-tab-pane key="role" tab="角色权限" class="role-content-wrapper-left">
|
<BasicLeftTree ref="roleTreeRef" v-bind="getRoleTreeBindValue">
|
<template #headerTitle>
|
<a-tabs v-model:active-key="roleActiveKey" class="jnpf-content-wrapper-tabs" :tab-bar-gutter="9" @change="onRoleTypeChange">
|
<a-tab-pane key="user" tab="用户角色" />
|
<a-tab-pane key="organize" tab="组织角色" />
|
<a-tab-pane key="position" tab="岗位角色" />
|
</a-tabs>
|
</template>
|
</BasicLeftTree>
|
</a-tab-pane>
|
</a-tabs>
|
</div>
|
<div class="jnpf-content-wrapper-center">
|
<div class="jnpf-content-wrapper-content auth-content bg-white">
|
<a-tabs v-model:active-key="menuType" class="jnpf-content-wrapper-tabs w-full" @change="onMenuTypeChange">
|
<a-tab-pane :key="item.id" :tab="item.fullName" v-for="item in permissionTypeList" />
|
<template #rightExtra>
|
<div class="tool-container">
|
<a-button type="text" :disabled="unref(getRealRef)?.loading" @click="handleExpandAll(true)">展开全部</a-button>
|
<a-button type="text" :disabled="unref(getRealRef)?.loading" @click="handleExpandAll(false)">折叠全部</a-button>
|
<a-button type="text" :disabled="unref(getRealRef)?.loading" @click="handleCheckAll(true)">全部勾选</a-button>
|
<a-button type="text" :disabled="unref(getRealRef)?.loading" @click="handleCheckAll(false)">取消全选</a-button>
|
<a-divider type="vertical" class="!h-7" />
|
<a-space :size="10">
|
<template v-if="menuType == 'Menu'">
|
<a-button @click="handlePrev" :disabled="unref(getRealRef)?.activeStep <= 0 || unref(getRealRef)?.loading">
|
{{ $t('common.prev') }}
|
</a-button>
|
<a-button @click="handleNext" :disabled="unref(getRealRef)?.activeStep >= unref(getRealRef)?.maxStep || unref(getRealRef)?.loading">
|
{{ $t('common.next') }}
|
</a-button>
|
</template>
|
<a-button
|
type="primary"
|
@click="handleSubmit()"
|
:disabled="unref(getRealRef)?.activeStep < unref(getRealRef)?.maxStep || unref(getRealRef)?.loading"
|
:loading="unref(getRealRef)?.btnLoading">
|
{{ $t('common.saveText') }}
|
</a-button>
|
</a-space>
|
</div>
|
</template>
|
</a-tabs>
|
<div class="main-container">
|
<MenuAuth v-bind="getBindValues" ref="menuAuthRef" v-if="menuType === 'Menu'" />
|
<CommonAuth v-bind="getBindValues" ref="commonAuthRef" v-else />
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
<style lang="scss" scoped>
|
.tool-container {
|
.ant-btn-text {
|
padding: 4px 8px;
|
}
|
}
|
|
.auth-content {
|
display: flex;
|
flex-direction: column;
|
|
.main-container {
|
flex: 1;
|
height: 100%;
|
overflow: hidden;
|
|
.auth-main-container {
|
display: flex;
|
flex-direction: column;
|
height: 100%;
|
}
|
}
|
}
|
</style>
|