search_tools_web/src/views/role-list.vue

512 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="data-center-wrap">
<el-card shadow="never" style="height: 100%">
<el-row :gutter="20" style="height: 100%">
<el-col :xl="4" :lg="4" style="border-right: 1px solid #dcdfe6">
<div style="margin-bottom: 24px; font-weight: 700">角色管理</div>
<el-divider></el-divider>
<el-button @click="addVisible = true;Object.assign(form, new Role());" type="primary" link
v-action:role:create>新建角色
</el-button>
<div style="margin-top: 16px">
<div
class="role-item"
:class="{ 'role-item-active': item.id === activeRoleId }"
v-for="(item, index) in roleList"
:key="index"
@click="handleRoleChange(item)"
>
<div>
<div>{{ item.name }}</div>
</div>
<el-dropdown trigger="hover">
<el-icon>
<setting/>
</el-icon>
<template #dropdown>
<el-dropdown-menu>
<span v-action:role:update>
<el-dropdown-item @click="handleEdit" v-action:role:update>编辑</el-dropdown-item>
</span>
<span v-action:role:delete>
<el-dropdown-item @click="handleDelete(roleList.find(r => r?.id === activeRoleId))">
<span class="del-btn">删除</span>
</el-dropdown-item>
</span>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</el-col>
<el-col :xl="20" :lg="20">
<el-col :span="24">
<el-col :span="24" style="padding-left: 0px;">
{{ roleList.find(r => r?.id === activeRoleId)?.name }}
<el-button text :icon="Edit" @click="handleEdit" v-action:role:update>
编辑
</el-button>
<el-button text :icon="Delete" class="red"
@click="handleDelete(roleList.find(r => r?.id === activeRoleId))" v-action:role:delete>
删除
</el-button>
</el-col>
<el-col style="font-size: 8px;color: #777777;padding-left: 0px;" :span="24">
{{ roleList.find(r => r?.id === activeRoleId)?.description }}
</el-col>
</el-col>
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleChangeRoleUserClient">
<el-tab-pane label="角色成员" name="first">
<div style="margin-bottom: 24px">
<el-button type="primary" @click="isOrgSelectShow = true" v-action:role:update>调整成员</el-button>
</div>
<el-table :data="tableData" border class="table" ref="multipleTable"
header-cell-class-name="table-header">
<el-table-column prop="id" label="ID" width="55" align="center"></el-table-column>
<el-table-column prop="username" label="用户名"></el-table-column>
<el-table-column prop="gender" label="性别">
<template #default="{ row }">
<span>{{ row.gender === 'MALE' ? '男' : '女' }}</span>
</template>
</el-table-column>
<el-table-column label="头像" align="center">
<template #default="scope">
<el-image
class="table-td-thumb"
:src="scope.row.avatar"
:z-index="10"
:preview-src-list="[scope?.row?.avatar]"
preview-teleported
>
</el-image>
</template>
</el-table-column>
<el-table-column label="拥有的角色">
<template #default="scope">
<sppan v-for="(role, index) in scope.row?.roles">
<template v-if="index > 0">, </template>
{{ role.name }}
</sppan>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
layout="total, prev, pager, next"
:current-page="userQuery.pageIndex"
:page-size="userQuery.pageSize"
:total="pageTotal"
@current-change="handlePageChange"
></el-pagination>
</div>
</el-tab-pane>
<el-tab-pane label="权限设置" name="second">
<div style="margin-bottom: 24px">
<el-button type="primary" @click="savePermission" v-action:role:update>保存</el-button>
</div>
<div v-for="(menu, index) in rolePermission" :key="index">
<el-row>
<el-col :span="18" :style="{fontWeight:'bold'}">{{ menu.name }}</el-col>
<el-col :span="6" :style="{textAlign:'right'}">
<el-switch
size="small"
v-model="menu.enabled"
@change="onChangeSwitch($event,menu)"/>
</el-col>
</el-row>
<el-divider type="horizontal" :style="{margin: '5px'}"/>
<el-row :gutter="16" v-for="(checkbox, tab) in menu.children" :key="tab">
<el-col :xl="4" :lg="4">
{{ checkbox.name }}
</el-col>
<el-col :xl="20" :lg="20">
<el-checkbox
:disabled="!menu.enabled"
v-model="checkbox.checkedAll"
:indeterminate="checkbox.indeterminate"
@change="onChangeCheckAll($event,checkbox)"
>全选
</el-checkbox>
<el-checkbox-group :disabled="!menu.enabled" v-model="checkbox.selected"
@change="onChangeCheck($event,checkbox)">
<el-checkbox v-for="btn in checkbox?.actionsOptions" :key="btn.id" :label="btn.id">
{{ btn.name }}
</el-checkbox>
</el-checkbox-group>
</el-col>
</el-row>
</div>
</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
</el-card>
<!-- 组织架构选择弹出框 -->
<OrgSelect
append-to-body
v-if="isOrgSelectShow"
:visible="isOrgSelectShow"
:activeRoleId="activeRoleId"
@on-cancel="handleOrgSelectCancel"
@on-submit="handleOrgSelectSubmit"
/>
<!-- 新增弹出框 -->
<el-dialog title="新增" v-model="addVisible" width="30%">
<el-form label-width="70px">
<el-form-item label="用户名">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="描述">
<el-input v-model="form.description" type="textarea"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="addVisible = false">取 消</el-button>
<el-button type="primary" @click="saveAdd">确 定</el-button>
</span>
</template>
</el-dialog>
<!-- 编辑弹出框 -->
<el-dialog title="编辑" v-model="editVisible" width="30%">
<el-form label-width="70px">
<el-form label-width="70px">
<el-form-item label="用户名">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="描述">
<el-input v-model="form.description" type="textarea"></el-input>
</el-form-item>
</el-form>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="editVisible = false">取 消</el-button>
<el-button type="primary" @click="saveEdit">确 定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import {reactive, ref} from "vue";
import {
changeResources,
changeUsers,
createRole,
deleteRole,
getRoleList,
getRoleUserList,
updateRole
} from "../api/role";
import {ElMessage, ElMessageBox, TabsPaneContext} from "element-plus";
import {getResourceTree as reqResourceTree} from "../api/resource";
import {Delete, Edit} from '@element-plus/icons-vue';
import OrgSelect, {OrgSelectedData} from "../components/OrgSelect.vue";
const isOrgSelectShow = ref(false)
interface Resource {
id: number;
name: string;
type: string;
permission: string;
url: string;
children?: Resource[]
}
interface RoleInterface {
id: number;
name?: string;
description?: string;
resourceIds?: number[];
}
class Role implements RoleInterface {
id = 0;
name = '';
description = '';
resourceIds = [];
}
interface Permission {
id: number;
name: string;
enabled: boolean,
children: {
id: number;
name: string;
checkedAll: boolean;
indeterminate: boolean;
selected: number[];
actionsOptions: {
id: number;
name: string;
}[]
}[];
}
interface UserTableItem {
id: number;
userName: string;
gender: string;
state: string;
roles: { id: number, name: string }
}
interface RoleSelectable extends RoleInterface {
value: number;
label?: string;
}
const roleList = ref<RoleInterface[]>([]);
const activeRoleId = ref<number>(1);
const reqRoleList = async () => {
try {
const { data, } = await getRoleList();
roleList.value = data;
getResourceTree(); // 获取权限列表
} catch (error) {
ElMessage.error(error as Error);
}
};
reqRoleList();
const handleRoleChange = (role: RoleInterface) => {
activeRoleId.value = role.id;
getUserData(role.id);
handlePermission();
}
//用户表格数据
const userQuery = reactive({
username: '',
state: '',
pageIndex: 1,
pageSize: 10
});
const tableData = ref<UserTableItem[]>([]);
const pageTotal = ref(0);
const getUserData = (roleId: number) => {
getRoleUserList(roleId, {
page: userQuery.pageIndex,
size: userQuery.pageSize,
username: userQuery.username || undefined,
state: userQuery.state || undefined,
}).then(res => {
tableData.value = res.data.list;
pageTotal.value = res.data.total;
});
}
getUserData(activeRoleId.value);
// 分页导航
const handlePageChange = (val: number) => {
userQuery.pageIndex = val;
getUserData(activeRoleId.value);
};
//标签页
const activeName = ref('first');
const rolePermission = ref<Permission[]>([]);
const getResourceTree = () => {
//初始化权限资源树
reqResourceTree().then(res => {
rolePermission.value = res.data.map((menu: Resource) => {
return {
id: menu.id,
name: menu.name,
enabled: true,
children: menu.children?.map((checkbox: Resource) => {
return {
id: checkbox.id,
name: checkbox.name,
checkedAll: false,
indeterminate: false,
selected: [],
actionsOptions: checkbox.children?.map((p: Resource) => {
return {
id: p.id,
name: p.name
};
}) || []
};
}) || []
};
});
// 赋值
handlePermission();
});
}
function handlePermission() {
let role: any = roleList.value.find(r => r.id == activeRoleId.value);
const resourceIds: number[] = role.resourceIds || [];
rolePermission.value.forEach(p => {
onChangeSwitch(resourceIds.includes(p.id), p);
p.children.forEach(pp => {
const selected: any[] = pp.actionsOptions.filter(action => resourceIds.includes(action.id)).map(action => action.id);
onChangeCheckAll(selected.length === pp.actionsOptions.length, pp);
pp.selected = selected;
onChangeCheck(selected, pp);
});
});
}
const onChangeSwitch = (enabled: boolean, permission: any) => {
permission.enabled = enabled;
}
const onChangeCheckAll = (checked: boolean, permission: any) => {
Object.assign(permission, {
selected: checked ? permission.actionsOptions.map((obj: any) => obj.id) : [],
indeterminate: false,
checkedAll: checked
});
}
const onChangeCheck = (selected: number[], permission: any) => {
permission.indeterminate = !!permission.selected.length && (permission.selected.length < permission.actionsOptions.length);
permission.checkedAll = permission.selected.length === permission.actionsOptions.length;
}
const handleChangeRoleUserClient = (tab: TabsPaneContext, event: Event) => {
}
const handleEdit = () => {
let role: any = roleList.value?.find(r => r?.id === activeRoleId.value);
form.name = role.name;
form.description = role.description;
editVisible.value = true;
};
const addVisible = ref<boolean>(false);
const editVisible = ref<boolean>(false);
let form = reactive(new Role());
const saveAdd = () => {
createRole(form).then(res => {
reqRoleList();
ElMessage.success(`新增成功`);
addVisible.value = false;
});
};
const saveEdit = () => {
updateRole(activeRoleId.value, form).then(res => {
reqRoleList();
ElMessage.success(`修改成功`);
editVisible.value = false;
});
};
const savePermission = () => {
let resourceIds: number[] = [];
rolePermission.value.forEach(p => {
if (p.enabled) {
resourceIds.push(p.id);
}
p.children.forEach(pp => {
if (pp.selected?.length) {
resourceIds.push(pp.id);
}
pp.selected.forEach(sel => resourceIds.push(sel));
})
});
changeResources(activeRoleId.value, resourceIds).then(res => {
reqRoleList();
ElMessage.success(`修改角色权限成功`);
editVisible.value = false;
});
}
// 删除操作
const handleDelete = (role: any) => {
// 二次确认删除
ElMessageBox.confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
deleteRole(role.id).then(res => {
reqRoleList();
ElMessage.success('删除成功');
});
}).catch(() => {
});
};
const handleOrgSelectCancel = () => {
isOrgSelectShow.value = false;
}
const handleOrgSelectSubmit = (p: OrgSelectedData) => {
isOrgSelectShow.value = false;
console.log(p);
debugger
let userIds: number[] = p.selected?.map((u: { id: number; }) => u.id);
changeUsers(activeRoleId.value, userIds).then(res => {
getUserData(activeRoleId.value);
ElMessage.success(`修改角色成员成功`);
editVisible.value = false;
});
}
</script>
<style scoped lang="scss">
.data-center-wrap {
position: relative;
.role-item {
font-size: 14px;
height: 32px;
line-height: 32px;
cursor: pointer;
white-space: nowrap;
display: flex;
align-items: center;
padding: 0 4px;
&:hover {
background-color: #f5f7fa;
}
&-active {
background-color: #ecf5ff;
}
.el-icon {
margin-left: 4px;
}
}
.el-pagination {
display: flex;
justify-content: flex-end;
margin: 20px 0;
padding-bottom: 20px;
}
}
.red {
color: #F56C6C;
}
.table-td-thumb {
display: block;
margin: auto;
width: 40px;
height: 40px;
}
</style>