123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- <template>
- <div class="p-base full">
- <div class="flex direction-column p-t-base p-b-base p-l-large fill-blank">
- <div class="flex items-center">
- <span class="m-r-base">角色</span>
- <base-select v-model="role" :options="ROLE_OPTION"></base-select>
- <el-button class="m-l-base" type="primary" :loading="loading" @click="onSubmit">保存</el-button>
- </div>
- <div class="flex-1 p-base m-t-large fill-lighter full-scroll-y-auto privilege-tree">
- <el-tree ref="treeRef" show-checkbox node-key="index" :data="menuTree || []" @check-change="onCheckChange">
- </el-tree>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts" name="RoleSetting">
- /** 角色权限管理 */
- import { computed, nextTick, ref, watch } from 'vue'
- import { ElButton, ElTree, ElMessage } from 'element-plus'
- import { ROLE_OPTION } from '@/constants/dicts'
- import useFetch from '@/hooks/useFetch'
- import useMainLayoutStore from '@/store/layout'
- import BaseSelect from '@/components/element/BaseSelect.vue'
- import type { ExtractApiResponse } from '@/api/api'
- type MenuItem = MainLayoutStore.MenuItem
- type MenuItemWithId = MenuItem & { id: number }
- const props = defineProps<{ role: ROLE }>()
- const mainLayoutStore = useMainLayoutStore()
- const role = ref<ROLE>(props.role)
- const treeRef = ref<InstanceType<typeof ElTree>>()
- const checkedMenus = ref<MenuItemWithId[]>([])
- const { fetch: getPrivilege, result: privilege } = useFetch('getRolePrivilege')
- const { fetch: setPrivilege, loading } = useFetch('setRolePrivilege')
- watch(
- role,
- () => {
- role.value && getPrivilege({ role: role.value })
- },
- { immediate: true }
- )
- watch(privilege, () => {
- nextTick(() => {
- treeRef?.value?.setCheckedKeys(privilege?.value?.filter((d) => d.hasPrivilege)?.map((d) => d.code))
- })
- })
- function filterPrivilege(
- item: MenuItem,
- privilege: ExtractApiResponse<'getRolePrivilege'>
- ): MenuItemWithId | undefined {
- const privilegeItem = privilege.find((d) => item.index === d.code)
- if (privilegeItem) {
- return {
- ...item,
- id: privilegeItem.id,
- children: item.children?.map((child) => filterPrivilege(child, privilege)).filter((d) => !!d) as MenuItemWithId[],
- }
- }
- }
- const menuTree = computed(() => {
- return mainLayoutStore.menuList?.reduce((menus, menu) => {
- return menus.concat(filterPrivilege(menu, privilege.value || []) || [])
- }, [] as MenuItem[])
- })
- const onCheckChange = () => {
- checkedMenus.value = (treeRef?.value?.getCheckedNodes() as MenuItemWithId[]) || []
- }
- /** 保存 */
- const onSubmit = async () => {
- try {
- const checkedNodes = treeRef?.value?.getCheckedNodes() || []
- const checkedHalfNodes = treeRef?.value?.getHalfCheckedNodes() || []
- const privilegeIds = checkedNodes.concat(checkedHalfNodes).map((d) => d.id)
- await setPrivilege({ role: role.value, privilegeIds })
- ElMessage.success('保存成功')
- } catch (error) {
- console.error(error)
- }
- }
- </script>
- <style scoped lang="scss">
- .privilege-tree {
- width: 660px;
- min-height: 320px;
- }
- </style>
|