<template> <div style="padding: 0px 0px 8px 8px"> <el-row :gutter="8" style="width: 100%"> <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12"> <el-card shadow="never" :body-style="{ paddingBottom: '0' }" style="margin-top: 8px"> <el-form :model="state.filterModel" :inline="true" @submit.stop.prevent> <el-form-item label="角色名称" prop="name"> <el-input v-model="state.filterModel.name" placeholder="角色名称" @keyup.enter="onQuery" /> </el-form-item> <el-form-item> <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </el-button> <el-dropdown v-auth="'api:admin:role:add'" style="margin-left: 12px"> <el-button type="primary" >新增<el-icon class="el-icon--right"><ele-ArrowDown /></el-icon ></el-button> <template #dropdown> <el-dropdown-menu> <el-dropdown-item @click="onAdd(1)">新增分组</el-dropdown-item> <el-dropdown-item @click="onAdd(2)">新增角色</el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </el-form-item> </el-form> </el-card> <el-card shadow="never" style="margin-top: 8px"> <el-table ref="roleTableRef" v-loading="state.loading" :data="state.roleTreeData" row-key="id" default-expand-all :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" highlight-current-row style="width: 100%" @current-change="onCurrentChange" > <el-table-column prop="name" label="角色名称" min-width="120" show-overflow-tooltip /> <el-table-column prop="sort" label="排序" width="80" align="center" show-overflow-tooltip /> <el-table-column label="操作" width="100" fixed="right" header-align="center" align="right"> <template #default="{ row }"> <el-button v-if="row.type === 1" v-auth="'api:admin:role:add'" icon="ele-Plus" size="small" text type="primary" @click="onAdd(2, row)" ></el-button> <my-dropdown-more icon-only v-auths="['api:admin:permission:assign', 'api:admin:role:update', 'api:admin:role:delete']"> <template #dropdown> <el-dropdown-menu> <el-dropdown-item v-if="row.type === 2 && auth('api:admin:permission:assign')" @click="onSetRoleMenu(row)" >菜单权限</el-dropdown-item > <el-dropdown-item v-if="row.type === 2" @click="onSetRoleDataScope(row)">数据权限</el-dropdown-item> <el-dropdown-item v-if="auth('api:admin:role:update')" @click="onEdit(row)" >编辑{{ row.type === 1 ? '分组' : '角色' }}</el-dropdown-item > <el-dropdown-item v-if="auth('api:admin:role:delete')" @click="onDelete(row)" >删除{{ row.type === 1 ? '分组' : '角色' }}</el-dropdown-item > </el-dropdown-menu> </template> </my-dropdown-more> </template> </el-table-column> </el-table> </el-card> </el-col> <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12"> <el-card shadow="never" :body-style="{ paddingBottom: '0' }" style="margin-top: 8px"> <el-form :model="state.filterModel" :inline="true" @submit.stop.prevent> <el-form-item label="姓名" prop="name"> <el-input v-model="state.filterModel.name" placeholder="姓名" @keyup.enter="onGetRoleUserList" /> </el-form-item> <el-form-item> <el-button type="primary" icon="ele-Search" @click="onGetRoleUserList"> 查询 </el-button> <el-button v-auth="'api:admin:role:add-role-user'" type="primary" icon="ele-Plus" @click="onAddUser"> 添加员工 </el-button> <el-button v-auth="'api:admin:role:remove-role-user'" type="danger" icon="ele-Delete" @click="onRemoveUser"> 移除员工 </el-button> </el-form-item> </el-form> </el-card> <el-card shadow="never" style="margin-top: 8px"> <el-table ref="userTableRef" v-loading="state.userListLoading" :data="state.userListData" row-key="id" style="width: 100%" @row-click="onUserRowClick" > <el-table-column type="selection" width="55" /> <el-table-column prop="name" label="姓名" show-overflow-tooltip /> <!-- <el-table-column prop="mobile" label="手机号" width="120" show-overflow-tooltip /> <el-table-column prop="email" label="邮箱" min-width="120" show-overflow-tooltip /> --> </el-table> </el-card> </el-col> </el-row> <role-form ref="roleFormRef" :title="state.roleFormTitle" :role-tree-data="state.roleFormTreeData"></role-form> <user-select ref="userSelectRef" title="添加员工" multiple :sure-loading="state.sureLoading" @sure="onSureUser"></user-select> <set-role-menu ref="setRoleMenuRef"></set-role-menu> <set-role-data-scope ref="setRoleDataScopeRef"></set-role-data-scope> </div> </template> <script lang="ts" setup name="admin/role"> import { ref, reactive, onMounted, getCurrentInstance, onUnmounted, nextTick, defineAsyncComponent } from 'vue' import { RoleGetListOutput, UserGetRoleUserListOutput, UserGetPageOutput, RoleAddRoleUserListInput, RoleType } from '/@/api/admin/data-contracts' import { RoleApi } from '/@/api/admin/Role' import { listToTree } from '/@/utils/tree' import { ElTable } from 'element-plus' import { cloneDeep } from 'lodash-es' import eventBus from '/@/utils/mitt' import { auth } from '/@/utils/authFunction' // 引入组件 const RoleForm = defineAsyncComponent(() => import('./components/role-form.vue')) const SetRoleMenu = defineAsyncComponent(() => import('./components/set-role-menu.vue')) const SetRoleDataScope = defineAsyncComponent(() => import('./components/set-role-data-scope.vue')) const UserSelect = defineAsyncComponent(() => import('/@/views/admin/user/components/user-select.vue')) const MyDropdownMore = defineAsyncComponent(() => import('/@/components/my-dropdown-more/index.vue')) const { proxy } = getCurrentInstance() as any const roleTableRef = ref() const roleFormRef = ref() const userTableRef = ref<InstanceType<typeof ElTable>>() const userSelectRef = ref() const setRoleMenuRef = ref() const setRoleDataScopeRef = ref() const state = reactive({ loading: false, userListLoading: false, sureLoading: false, roleFormTitle: '', filterModel: { name: '', }, roleTreeData: [] as any, roleFormTreeData: [] as any, userListData: [] as UserGetRoleUserListOutput[], roleId: undefined as number | undefined, }) onMounted(() => { onQuery() eventBus.on('refreshRole', async () => { onQuery() }) }) onUnmounted(() => { eventBus.off('refreshRole') }) const onQuery = async () => { state.loading = true const res = await new RoleApi().getList() if (res.data && res.data.length > 0) { state.roleTreeData = listToTree(cloneDeep(res.data)) state.roleFormTreeData = listToTree(cloneDeep(res.data).filter((a) => a.parentId === 0)) if (state.roleTreeData[0].children?.length > 0) { nextTick(() => { roleTableRef.value!.setCurrentRow(state.roleTreeData[0].children[0]) }) } } else { state.roleTreeData = [] state.roleFormTreeData = [] } state.loading = false } const onAdd = (type: RoleType, row: RoleGetListOutput | undefined = undefined) => { switch (type) { case 1: state.roleFormTitle = '新增分组' roleFormRef.value.open({ type: 1 }) break case 2: state.roleFormTitle = '新增角色' roleFormRef.value.open({ type: 2, parentId: row?.id }) break } } const onEdit = (row: RoleGetListOutput) => { switch (row.type) { case 1: state.roleFormTitle = '编辑分组' break case 2: state.roleFormTitle = '编辑角色' break } roleFormRef.value.open(row) } const onDelete = (row: RoleGetListOutput) => { proxy.$modal .confirmDelete(`确定要删除角色【${row.name}】?`) .then(async () => { await new RoleApi().delete({ id: row.id }, { loading: true }) onQuery() }) .catch(() => {}) } const onGetRoleUserList = async () => { state.userListLoading = true const res = await new RoleApi().getRoleUserList({ RoleId: state.roleId }) state.userListLoading = false if (res?.success) { if (res.data && res.data.length > 0) { state.userListData = res.data } else { state.userListData = [] } } } const onCurrentChange = (currentRow: RoleGetListOutput, oldCurrentRow: RoleGetListOutput) => { if (!currentRow) { return } if (currentRow?.id !== oldCurrentRow?.id && (oldCurrentRow?.id as number) > 0) { if ((currentRow?.parentId as number) === 0) { roleTableRef.value!.setCurrentRow(oldCurrentRow) } } else { if ((currentRow?.parentId as number) === 0) { roleTableRef.value!.setCurrentRow() } } if ((currentRow?.parentId as number) !== 0 && (oldCurrentRow?.parentId as number) !== 0 && (currentRow?.id as number) > 0) { state.roleId = currentRow.id onGetRoleUserList() } } const onUserRowClick = (row: UserGetRoleUserListOutput) => { // TODO: improvement typing when refactor table // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error userTableRef.value!.toggleRowSelection(row, undefined) } const onAddUser = () => { if (!((state.roleId as number) > 0)) { proxy.$modal.msgWarning('请选择角色') return } userSelectRef.value.open({ roleId: state.roleId }) } const onRemoveUser = () => { if (!((state.roleId as number) > 0)) { proxy.$modal.msgWarning('请选择角色') return } const selectionRows = userTableRef.value!.getSelectionRows() as UserGetPageOutput[] if (!((selectionRows.length as number) > 0)) { proxy.$modal.msgWarning('请选择员工') return } proxy.$modal .confirm(`确定要移除吗?`) .then(async () => { const userIds = selectionRows?.map((a) => a.id) const input = { roleId: state.roleId, userIds } as RoleAddRoleUserListInput await new RoleApi().removeRoleUser(input, { loading: true }) onGetRoleUserList() }) .catch(() => {}) } const onSureUser = async (users: UserGetPageOutput[]) => { if (!(users?.length > 0)) { userSelectRef.value.close() return } state.sureLoading = true const userIds = users?.map((a) => a.id) const input = { roleId: state.roleId, userIds } as RoleAddRoleUserListInput await new RoleApi().addRoleUser(input, { showSuccessMessage: true }) state.sureLoading = false userSelectRef.value.close() onGetRoleUserList() } const onSetRoleMenu = (role: RoleGetListOutput) => { if (!((role?.id as number) > 0)) { proxy.$modal.msgWarning('请选择角色') return } setRoleMenuRef.value.open(role) } const onSetRoleDataScope = (role: RoleGetListOutput) => { if (!((role?.id as number) > 0)) { proxy.$modal.msgWarning('请选择角色') return } setRoleDataScopeRef.value.open(role) } </script> <style scoped lang="scss"></style>