增加角色批量授权用户
(cherry picked commit from <gitee.com//lxy0722/django-vue3-admin/commit/702eb7d7aeb2a9c30416a8ebb503a4b8e3367492>
This commit is contained in:
@@ -10,16 +10,17 @@ from rest_framework import serializers
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
|
||||
from dvadmin.system.models import Role, Menu, MenuButton, Dept
|
||||
from dvadmin.system.models import Role, Menu, MenuButton, Dept, Users
|
||||
from dvadmin.system.views.dept import DeptSerializer
|
||||
from dvadmin.system.views.menu import MenuSerializer
|
||||
from dvadmin.system.views.menu_button import MenuButtonSerializer
|
||||
from dvadmin.utils.crud_mixin import FastCrudMixin
|
||||
from dvadmin.utils.field_permission import FieldPermissionMixin
|
||||
from dvadmin.utils.json_response import SuccessResponse, DetailResponse
|
||||
from dvadmin.utils.json_response import SuccessResponse, DetailResponse, ErrorResponse
|
||||
from dvadmin.utils.serializers import CustomModelSerializer
|
||||
from dvadmin.utils.validator import CustomUniqueValidator
|
||||
from dvadmin.utils.viewset import CustomModelViewSet
|
||||
from dvadmin.utils.permission import CustomPermission
|
||||
|
||||
|
||||
class RoleSerializer(CustomModelSerializer):
|
||||
@@ -107,7 +108,6 @@ class MenuButtonPermissionSerializer(CustomModelSerializer):
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
|
||||
class RoleViewSet(CustomModelViewSet, FastCrudMixin,FieldPermissionMixin):
|
||||
"""
|
||||
角色管理接口
|
||||
@@ -142,3 +142,62 @@ class RoleViewSet(CustomModelViewSet, FastCrudMixin,FieldPermissionMixin):
|
||||
role.users_set.add(*movedKeys)
|
||||
serializer = RoleSerializer(role)
|
||||
return DetailResponse(data=serializer.data, msg="更新成功")
|
||||
|
||||
@action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated, CustomPermission])
|
||||
def get_role_users(self, request):
|
||||
"""
|
||||
获取角色已授权、未授权的用户
|
||||
已授权的用户:1
|
||||
未授权的用户:0
|
||||
"""
|
||||
role_id = request.query_params.get('role_id', None)
|
||||
|
||||
if not role_id:
|
||||
return ErrorResponse(msg="请选择角色")
|
||||
|
||||
if request.query_params.get('authorized', 0) == "1":
|
||||
queryset = Users.objects.filter(role__id=role_id).exclude(is_superuser=True)
|
||||
else:
|
||||
queryset = Users.objects.exclude(role__id=role_id).exclude(is_superuser=True)
|
||||
|
||||
if name := request.query_params.get('name', None):
|
||||
queryset = queryset.filter(name__icontains=name)
|
||||
|
||||
if dept := request.query_params.get('dept', None):
|
||||
queryset = queryset.filter(dept=dept)
|
||||
|
||||
page = self.paginate_queryset(queryset.values('id', 'name', 'dept__name'))
|
||||
if page is not None:
|
||||
return self.get_paginated_response(page)
|
||||
|
||||
return SuccessResponse(data=page)
|
||||
|
||||
@action(methods=['DELETE'], detail=True, permission_classes=[IsAuthenticated, CustomPermission])
|
||||
def remove_role_user(self, request, pk):
|
||||
"""
|
||||
角色-删除用户
|
||||
"""
|
||||
user_id = request.data.get('user_id', None)
|
||||
|
||||
if not user_id:
|
||||
return ErrorResponse(msg="请选择用户")
|
||||
|
||||
role = self.get_object()
|
||||
role.users_set.remove(*user_id)
|
||||
|
||||
return SuccessResponse(msg="删除成功")
|
||||
|
||||
@action(methods=['POST'], detail=True, permission_classes=[IsAuthenticated, CustomPermission])
|
||||
def add_role_users(self, request, pk):
|
||||
"""
|
||||
角色-添加用户
|
||||
"""
|
||||
users_id = request.data.get('users_id', None)
|
||||
|
||||
if not users_id:
|
||||
return ErrorResponse(msg="请选择用户")
|
||||
|
||||
role = self.get_object()
|
||||
role.users_set.add(*users_id)
|
||||
|
||||
return DetailResponse(msg="添加成功")
|
||||
|
||||
30
web/src/views/system/role/components/addUsers/api.ts
Normal file
30
web/src/views/system/role/components/addUsers/api.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { request } from '/@/utils/service';
|
||||
import { UserPageQuery} from '@fast-crud/fast-crud';
|
||||
|
||||
/**
|
||||
* 当前角色查询未授权的用户
|
||||
* @param role_id 角色id
|
||||
* @param query 查询条件 需要有角色id
|
||||
* @returns
|
||||
*/
|
||||
export function getRoleUsersUnauthorized(query: UserPageQuery) {
|
||||
query["authorized"] = 0; // 未授权的用户
|
||||
return request({
|
||||
url: '/api/system/role/get_role_users/',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 当前用户角色添加用户
|
||||
* @param role_id 角色id
|
||||
* @param users_id 用户id数组
|
||||
* @returns
|
||||
*/
|
||||
export function addRoleUsers(role_id: number, users_id: Array<Number>) {
|
||||
return request({
|
||||
url: `/api/system/role/${role_id}/add_role_users/`,
|
||||
method: 'post',
|
||||
data: {users_id: users_id},
|
||||
});
|
||||
}
|
||||
184
web/src/views/system/role/components/addUsers/crud.tsx
Normal file
184
web/src/views/system/role/components/addUsers/crud.tsx
Normal file
@@ -0,0 +1,184 @@
|
||||
import {getRoleUsersUnauthorized} from './api';
|
||||
import {
|
||||
compute,
|
||||
dict,
|
||||
UserPageQuery,
|
||||
AddReq,
|
||||
DelReq,
|
||||
EditReq,
|
||||
CrudOptions,
|
||||
CreateCrudOptionsProps,
|
||||
CreateCrudOptionsRet
|
||||
} from '@fast-crud/fast-crud';
|
||||
|
||||
import { ref , nextTick} from 'vue';
|
||||
import XEUtils from 'xe-utils';
|
||||
|
||||
export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const pageRequest = async (query: UserPageQuery) => {
|
||||
return await getRoleUsersUnauthorized(query);
|
||||
};
|
||||
const editRequest = async ({ form, row }: EditReq) => {
|
||||
return undefined;
|
||||
};
|
||||
const delRequest = async ({ row }: DelReq) => {
|
||||
return undefined;
|
||||
};
|
||||
const addRequest = async ({ form }: AddReq) => {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
// 记录选中的行
|
||||
const selectedRows = ref<any>([]);
|
||||
|
||||
const onSelectionChange = (changed: any) => {
|
||||
const tableData = crudExpose.getTableData();
|
||||
const unChanged = tableData.filter((row: any) => !changed.includes(row));
|
||||
// 添加已选择的行
|
||||
XEUtils.arrayEach(changed, (item: any) => {
|
||||
const ids = XEUtils.pluck(selectedRows.value, 'id');
|
||||
if (!ids.includes(item.id)) {
|
||||
selectedRows.value = XEUtils.union(selectedRows.value, [item]);
|
||||
}
|
||||
});
|
||||
// 剔除未选择的行
|
||||
XEUtils.arrayEach(unChanged, (unItem: any) => {
|
||||
selectedRows.value = XEUtils.remove(selectedRows.value, (item: any) => item.id !== unItem.id);
|
||||
});
|
||||
};
|
||||
const toggleRowSelection = () => {
|
||||
// 多选后,回显默认勾选
|
||||
const tableRef = crudExpose.getBaseTableRef();
|
||||
const tableData = crudExpose.getTableData();
|
||||
const selected = XEUtils.filter(tableData, (item: any) => {
|
||||
const ids = XEUtils.pluck(selectedRows.value, 'id');
|
||||
return ids.includes(item.id);
|
||||
});
|
||||
|
||||
nextTick(() => {
|
||||
XEUtils.arrayEach(selected, (item) => {
|
||||
tableRef.toggleRowSelection(item, true);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
selectedRows,
|
||||
crudOptions: {
|
||||
request: {
|
||||
pageRequest,
|
||||
addRequest,
|
||||
editRequest,
|
||||
delRequest,
|
||||
},
|
||||
actionbar: {
|
||||
show: false,
|
||||
buttons: {
|
||||
add: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
rowHandle: {
|
||||
show: false,
|
||||
//固定右侧
|
||||
fixed: 'left',
|
||||
width: 150,
|
||||
buttons: {
|
||||
view: {
|
||||
show: false,
|
||||
},
|
||||
edit: {
|
||||
show: false,
|
||||
},
|
||||
remove: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
table: {
|
||||
rowKey: "id",
|
||||
onSelectionChange,
|
||||
onRefreshed: () => toggleRowSelection(),
|
||||
},
|
||||
columns: {
|
||||
$checked: {
|
||||
title: "选择",
|
||||
form: { show: false},
|
||||
column: {
|
||||
show: true,
|
||||
type: "selection",
|
||||
align: "center",
|
||||
width: "55px",
|
||||
columnSetDisabled: true, //禁止在列设置中选择
|
||||
}
|
||||
},
|
||||
_index: {
|
||||
title: '序号',
|
||||
form: { show: false },
|
||||
column: {
|
||||
//type: 'index',
|
||||
align: 'center',
|
||||
width: '70px',
|
||||
columnSetDisabled: true, //禁止在列设置中选择
|
||||
formatter: (context) => {
|
||||
//计算序号,你可以自定义计算规则,此处为翻页累加
|
||||
let index = context.index ?? 1;
|
||||
let pagination = crudExpose!.crudBinding.value.pagination;
|
||||
// @ts-ignore
|
||||
return ((pagination.currentPage ?? 1) - 1) * pagination.pageSize + index + 1;
|
||||
},
|
||||
},
|
||||
},
|
||||
name: {
|
||||
title: '用户名',
|
||||
search: {
|
||||
show: true,
|
||||
component: {
|
||||
props: {
|
||||
clearable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
type: 'text',
|
||||
form: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
dept: {
|
||||
title: '部门',
|
||||
show: true,
|
||||
type: 'dict-tree',
|
||||
column: {
|
||||
name: 'text',
|
||||
formatter({value,row,index}){
|
||||
return row.dept__name
|
||||
}
|
||||
},
|
||||
search: {
|
||||
show: true,
|
||||
disabled: true,
|
||||
col:{span: 6},
|
||||
component: {
|
||||
multiple: false,
|
||||
props: {
|
||||
checkStrictly: true,
|
||||
clearable: true,
|
||||
filterable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
dict: dict({
|
||||
isTree: true,
|
||||
url: '/api/system/dept/all_dept/',
|
||||
value: 'id',
|
||||
label: 'name'
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
91
web/src/views/system/role/components/addUsers/index.vue
Normal file
91
web/src/views/system/role/components/addUsers/index.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialog" title="添加授权用户" direction="rtl" destroy-on-close :before-close="handleDialogClose">
|
||||
<div style="height: 500px;" >
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||
<template #pagination-right>
|
||||
<el-popover placement="top" :width="200" trigger="click">
|
||||
<template #reference>
|
||||
<el-button text :type="selectedRowsCount > 0 ? 'primary' : ''">已选中{{ selectedRowsCount }}条数据</el-button>
|
||||
</template>
|
||||
<el-table :data="selectedRows" size="small" :max-height="500">
|
||||
<!-- <el-table-column width="100" property="id" label="id" /> -->
|
||||
<el-table-column width="100" property="name" label="用户名" />
|
||||
<el-table-column fixed="right" label="操作" min-width="50">
|
||||
<template #default="scope">
|
||||
<el-button text type="info" :icon="Close" @click="removeSelectedRows(scope.row)" circle />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-popover>
|
||||
</template>
|
||||
|
||||
</fs-crud>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div>
|
||||
<el-button type="primary" @click="handleDialogConfirm"> 确定</el-button>
|
||||
<el-button @click="handleDialogClose"> 取消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useFs } from '@fast-crud/fast-crud';
|
||||
import { createCrudOptions } from './crud';
|
||||
import { successNotification } from '/@/utils/message';
|
||||
import { addRoleUsers } from './api';
|
||||
import { Close } from '@element-plus/icons-vue';
|
||||
import XEUtils from 'xe-utils';
|
||||
|
||||
const props = defineProps({
|
||||
refreshCallback: {
|
||||
type: Function,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
//对话框是否显示
|
||||
const dialog = ref(false);
|
||||
|
||||
// 父组件刷新回调函数
|
||||
const parentRefreshCallbackFunc = props.refreshCallback;
|
||||
|
||||
//抽屉关闭确认
|
||||
const handleDialogClose = () => {
|
||||
dialog.value = false;
|
||||
selectedRows.value = [];
|
||||
};
|
||||
|
||||
const handleDialogConfirm = async () => {
|
||||
if (selectedRows.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
await addRoleUsers(crudRef.value.getSearchFormData().role_id, XEUtils.pluck(selectedRows.value, 'id')).then(res => {
|
||||
successNotification(res.msg);
|
||||
})
|
||||
parentRefreshCallbackFunc && parentRefreshCallbackFunc(); // 刷新父组件
|
||||
handleDialogClose();
|
||||
};
|
||||
|
||||
const { crudBinding, crudRef, crudExpose, selectedRows } = useFs({ createCrudOptions, context: {} });
|
||||
const { setSearchFormData, doRefresh } = crudExpose;
|
||||
|
||||
// 选中行的条数
|
||||
const selectedRowsCount = computed(() => {
|
||||
return selectedRows.value.length;
|
||||
});
|
||||
|
||||
const removeSelectedRows = (row: any) => {
|
||||
const tableRef = crudExpose.getBaseTableRef();
|
||||
const tableData = crudExpose.getTableData();
|
||||
if (XEUtils.pluck(tableData, 'id').includes(row.id)) {
|
||||
tableRef.toggleRowSelection(row, false);
|
||||
} else {
|
||||
selectedRows.value = XEUtils.remove(selectedRows.value, (item: any) => item.id !== row.id);
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({ dialog, setSearchFormData, doRefresh, parentRefreshCallbackFunc});
|
||||
</script>
|
||||
44
web/src/views/system/role/components/searchUsers/api.ts
Normal file
44
web/src/views/system/role/components/searchUsers/api.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { request } from '/@/utils/service';
|
||||
import { UserPageQuery} from '@fast-crud/fast-crud';
|
||||
|
||||
/**
|
||||
* 当前角色查询授权的用户
|
||||
* @param query 查询条件 需要有角色id
|
||||
* @returns
|
||||
*/
|
||||
export function getRoleUsersAuthorized(query: UserPageQuery) {
|
||||
query["authorized"] = 1; // 授权的用户
|
||||
return request({
|
||||
url: '/api/system/role/get_role_users/',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 当前角色删除授权的用户
|
||||
* @param role_id 角色id
|
||||
* @param user_id 用户id数组
|
||||
* @returns
|
||||
*/
|
||||
export function removeRoleUser(role_id: number, user_id: Array<number>) {
|
||||
return request({
|
||||
url: `/api/system/role/${role_id}/remove_role_user/`,
|
||||
method: 'delete',
|
||||
data: {user_id: user_id},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 当前用户角色添加用户
|
||||
* @param role_id 角色id
|
||||
* @param data 用户id数组
|
||||
* @returns
|
||||
*/
|
||||
export function addRoleUsers(role_id: number, data: Array<Number>) {
|
||||
return request({
|
||||
url: `/api/system/role/${role_id}/add_role_users/`,
|
||||
method: 'post',
|
||||
data: {users_id: data},
|
||||
});
|
||||
}
|
||||
193
web/src/views/system/role/components/searchUsers/crud.tsx
Normal file
193
web/src/views/system/role/components/searchUsers/crud.tsx
Normal file
@@ -0,0 +1,193 @@
|
||||
import {getRoleUsersAuthorized, removeRoleUser} from './api';
|
||||
import {
|
||||
compute,
|
||||
dict,
|
||||
UserPageQuery,
|
||||
AddReq,
|
||||
DelReq,
|
||||
EditReq,
|
||||
CrudOptions,
|
||||
CreateCrudOptionsProps,
|
||||
CreateCrudOptionsRet
|
||||
} from '@fast-crud/fast-crud';
|
||||
|
||||
import {auth} from "/@/utils/authFunction";
|
||||
import { ref , nextTick} from 'vue';
|
||||
import XEUtils from 'xe-utils';
|
||||
|
||||
export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const pageRequest = async (query: UserPageQuery) => {
|
||||
return await getRoleUsersAuthorized(query);
|
||||
};
|
||||
const editRequest = async ({ form, row }: EditReq) => {
|
||||
return undefined;
|
||||
};
|
||||
const delRequest = async ({ row }: DelReq) => {
|
||||
return await removeRoleUser(crudExpose.crudRef.value.getSearchFormData().role_id, [row.id]);
|
||||
};
|
||||
const addRequest = async ({ form }: AddReq) => {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
// 记录选中的行
|
||||
const selectedRows = ref<any>([]);
|
||||
|
||||
const onSelectionChange = (changed: any) => {
|
||||
const tableData = crudExpose.getTableData();
|
||||
const unChanged = tableData.filter((row: any) => !changed.includes(row));
|
||||
// 添加已选择的行
|
||||
XEUtils.arrayEach(changed, (item: any) => {
|
||||
const ids = XEUtils.pluck(selectedRows.value, 'id');
|
||||
if (!ids.includes(item.id)) {
|
||||
selectedRows.value = XEUtils.union(selectedRows.value, [item]);
|
||||
}
|
||||
});
|
||||
// 剔除未选择的行
|
||||
XEUtils.arrayEach(unChanged, (unItem: any) => {
|
||||
selectedRows.value = XEUtils.remove(selectedRows.value, (item: any) => item.id !== unItem.id);
|
||||
});
|
||||
};
|
||||
const toggleRowSelection = () => {
|
||||
// 多选后,回显默认勾选
|
||||
const tableRef = crudExpose.getBaseTableRef();
|
||||
const tableData = crudExpose.getTableData();
|
||||
const selected = XEUtils.filter(tableData, (item: any) => {
|
||||
const ids = XEUtils.pluck(selectedRows.value, 'id');
|
||||
return ids.includes(item.id);
|
||||
});
|
||||
|
||||
nextTick(() => {
|
||||
XEUtils.arrayEach(selected, (item) => {
|
||||
tableRef.toggleRowSelection(item, true);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
selectedRows,
|
||||
crudOptions: {
|
||||
request: {
|
||||
pageRequest,
|
||||
addRequest,
|
||||
editRequest,
|
||||
delRequest,
|
||||
},
|
||||
actionbar: {
|
||||
buttons: {
|
||||
add: {
|
||||
show: auth('role:AuthorizedAdd'),
|
||||
click: (ctx: any) => {
|
||||
context!.subUserRef.value.dialog = true;
|
||||
nextTick(() => {
|
||||
context!.subUserRef.value.setSearchFormData({ form: { role_id: crudExpose.crudRef.value.getSearchFormData().role_id } });
|
||||
context!.subUserRef.value.doRefresh();
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
},
|
||||
rowHandle: {
|
||||
//固定右侧
|
||||
fixed: 'left',
|
||||
width: 120,
|
||||
show: auth('role:AuthorizedDel'),
|
||||
buttons: {
|
||||
view: {
|
||||
show: false,
|
||||
},
|
||||
edit: {
|
||||
show: false,
|
||||
},
|
||||
remove: {
|
||||
iconRight: 'Delete',
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
table: {
|
||||
rowKey: "id",
|
||||
onSelectionChange,
|
||||
onRefreshed: () => toggleRowSelection(),
|
||||
},
|
||||
columns: {
|
||||
$checked: {
|
||||
title: "选择",
|
||||
form: { show: false},
|
||||
column: {
|
||||
show: auth('role:AuthorizedDel'),
|
||||
type: "selection",
|
||||
align: "center",
|
||||
width: "55px",
|
||||
columnSetDisabled: true, //禁止在列设置中选择
|
||||
}
|
||||
},
|
||||
_index: {
|
||||
title: '序号',
|
||||
form: { show: false },
|
||||
column: {
|
||||
//type: 'index',
|
||||
align: 'center',
|
||||
width: '70px',
|
||||
columnSetDisabled: true, //禁止在列设置中选择
|
||||
formatter: (context) => {
|
||||
//计算序号,你可以自定义计算规则,此处为翻页累加
|
||||
let index = context.index ?? 1;
|
||||
let pagination = crudExpose!.crudBinding.value.pagination;
|
||||
// @ts-ignore
|
||||
return ((pagination.currentPage ?? 1) - 1) * pagination.pageSize + index + 1;
|
||||
},
|
||||
},
|
||||
},
|
||||
name: {
|
||||
title: '用户名',
|
||||
search: {
|
||||
show: true,
|
||||
component: {
|
||||
props: {
|
||||
clearable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
type: 'text',
|
||||
form: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
dept: {
|
||||
title: '部门',
|
||||
show: true,
|
||||
type: 'dict-tree',
|
||||
column: {
|
||||
name: 'text',
|
||||
formatter({value,row,index}){
|
||||
return row.dept__name
|
||||
}
|
||||
},
|
||||
search: {
|
||||
show: true,
|
||||
disabled: true,
|
||||
col:{span: 6},
|
||||
component: {
|
||||
multiple: false,
|
||||
props: {
|
||||
checkStrictly: true,
|
||||
clearable: true,
|
||||
filterable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
dict: dict({
|
||||
isTree: true,
|
||||
url: '/api/system/dept/all_dept/',
|
||||
value: 'id',
|
||||
label: 'name'
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
98
web/src/views/system/role/components/searchUsers/index.vue
Normal file
98
web/src/views/system/role/components/searchUsers/index.vue
Normal file
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<el-drawer size="70%" v-model="RoleUserDrawer.drawerVisible" direction="rtl" destroy-on-close :before-close="handleClose">
|
||||
<template #header>
|
||||
<div>
|
||||
当前授权角色:
|
||||
<el-tag>{{ RoleUserDrawer.role_name }}</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||
<template #pagination-right>
|
||||
<el-popover placement="top" :width="200" trigger="click">
|
||||
<template #reference>
|
||||
<el-button text :type="selectedRowsCount > 0 ? 'primary' : ''">已选中{{ selectedRowsCount }}条数据</el-button>
|
||||
</template>
|
||||
<el-table :data="selectedRows" size="small" :max-height="500" >
|
||||
<!-- <el-table-column width="100" property="id" label="id" /> -->
|
||||
<el-table-column width="100" property="name" label="用户名" />
|
||||
<el-table-column fixed="right" label="操作" min-width="60">
|
||||
<template #default="scope">
|
||||
<el-button text type="info" :icon="Close" @click="removeSelectedRows(scope.row)" circle />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-popover>
|
||||
</template>
|
||||
<template #pagination-left>
|
||||
<el-tooltip content="批量删除所选择的用户权限">
|
||||
<el-button v-show="selectedRowsCount > 0 && auth('role:AuthorizedDel')" type="danger" @click="multipleDel" :icon="Delete">批量删除</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</fs-crud>
|
||||
<subUser ref="subUserRef" :refreshCallback="refreshData"> </subUser>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {auth} from "/@/utils/authFunction";
|
||||
import { ref, onMounted, defineAsyncComponent, computed } from 'vue';
|
||||
import { useFs } from '@fast-crud/fast-crud';
|
||||
import { createCrudOptions } from './crud';
|
||||
import { Close, Delete } from '@element-plus/icons-vue';
|
||||
import XEUtils from 'xe-utils';
|
||||
import {removeRoleUser} from "./api"
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { errorMessage, successNotification } from '/@/utils/message';
|
||||
|
||||
import { RoleUserStores } from '../../stores/RoleUserStores';
|
||||
const RoleUserDrawer = RoleUserStores(); // 授权用户抽屉参数
|
||||
|
||||
const subUser = defineAsyncComponent(() => import('../addUsers/index.vue'));
|
||||
const subUserRef = ref();
|
||||
|
||||
const refreshData = () => {
|
||||
crudExpose.doRefresh();
|
||||
};
|
||||
|
||||
//抽屉是否显示
|
||||
const drawer = ref(false);
|
||||
|
||||
//抽屉关闭确认
|
||||
const handleClose = (done: () => void) => {
|
||||
selectedRows.value = [];
|
||||
done();
|
||||
};
|
||||
|
||||
// 选中行的条数
|
||||
const selectedRowsCount = computed(() => {
|
||||
return selectedRows.value.length;
|
||||
});
|
||||
|
||||
const removeSelectedRows = (row: any) => {
|
||||
const tableRef = crudExpose.getBaseTableRef();
|
||||
const tableData = crudExpose.getTableData();
|
||||
if (XEUtils.pluck(tableData, 'id').includes(row.id)) {
|
||||
tableRef.toggleRowSelection(row, false);
|
||||
} else {
|
||||
selectedRows.value = XEUtils.remove(selectedRows.value, (item: any) => item.id !== row.id);
|
||||
}
|
||||
};
|
||||
|
||||
const multipleDel = async () => {
|
||||
if (selectedRows.value.length < 1) {
|
||||
errorMessage("请先勾选用户");
|
||||
return
|
||||
}
|
||||
await ElMessageBox.confirm(`确定要删除这 “${selectedRows.value.length}” 位用户的权限吗`, "确认");
|
||||
const req = await removeRoleUser(crudRef.value.getSearchFormData().role_id, XEUtils.pluck(selectedRows.value, 'id'));
|
||||
selectedRows.value = [];
|
||||
successNotification(req.msg)
|
||||
crudExpose.doRefresh()
|
||||
}
|
||||
|
||||
const { crudBinding, crudRef, crudExpose, selectedRows } = useFs({ createCrudOptions, context: {subUserRef} });
|
||||
const { setSearchFormData, doRefresh } = crudExpose;
|
||||
|
||||
defineExpose({ drawer, setSearchFormData, doRefresh });
|
||||
|
||||
</script>
|
||||
@@ -3,6 +3,7 @@ import * as api from './api';
|
||||
import { dictionary } from '/@/utils/dictionary';
|
||||
import { successMessage } from '../../../utils/message';
|
||||
import { auth } from '/@/utils/authFunction';
|
||||
import { nextTick, computed } from 'vue';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -46,7 +47,12 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
|
||||
rowHandle: {
|
||||
//固定右侧
|
||||
fixed: 'right',
|
||||
width: 320,
|
||||
width: computed(() => {
|
||||
if (auth('role:AuthorizedAdd') || auth('role:AuthorizedSearch')){
|
||||
return 420;
|
||||
}
|
||||
return 320;
|
||||
}),
|
||||
buttons: {
|
||||
view: {
|
||||
show: true,
|
||||
@@ -57,6 +63,19 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
|
||||
remove: {
|
||||
show: auth('role:Delete'),
|
||||
},
|
||||
assignment: {
|
||||
type: 'primary',
|
||||
text: '授权用户',
|
||||
show: auth('role:AuthorizedAdd') || auth('role:AuthorizedSearch'),
|
||||
click: (ctx: any) => {
|
||||
const { row } = ctx;
|
||||
context!.RoleUserDrawer.handleDrawerOpen(row);
|
||||
nextTick(() => {
|
||||
context!.RoleUserRef.value.setSearchFormData({ form: { role_id: row.id } });
|
||||
context!.RoleUserRef.value.doRefresh();
|
||||
});
|
||||
},
|
||||
},
|
||||
permission: {
|
||||
type: 'primary',
|
||||
text: '权限配置',
|
||||
|
||||
@@ -2,17 +2,22 @@
|
||||
<fs-page>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||
<PermissionDrawerCom />
|
||||
<RoleUser ref="RoleUserRef" />
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="role">
|
||||
import { defineAsyncComponent, onMounted } from 'vue';
|
||||
import { defineAsyncComponent, onMounted, ref} from 'vue';
|
||||
import { useFs } from '@fast-crud/fast-crud';
|
||||
import { createCrudOptions } from './crud';
|
||||
import { RoleDrawerStores } from './stores/RoleDrawerStores';
|
||||
import { RoleMenuBtnStores } from './stores/RoleMenuBtnStores';
|
||||
import { RoleMenuFieldStores } from './stores/RoleMenuFieldStores';
|
||||
import { RoleUsersStores } from './stores/RoleUsersStores';
|
||||
import { RoleUserStores } from './stores/RoleUserStores';
|
||||
|
||||
const RoleUser = defineAsyncComponent(() => import('./components/searchUsers/index.vue'));
|
||||
const RoleUserRef = ref();
|
||||
|
||||
const PermissionDrawerCom = defineAsyncComponent(() => import('./components/RoleDrawer.vue'));
|
||||
|
||||
@@ -20,9 +25,11 @@ const RoleDrawer = RoleDrawerStores(); // 角色-抽屉
|
||||
const RoleMenuBtn = RoleMenuBtnStores(); // 角色-菜单
|
||||
const RoleMenuField = RoleMenuFieldStores();// 角色-菜单-字段
|
||||
const RoleUsers = RoleUsersStores();// 角色-用户
|
||||
const RoleUserDrawer = RoleUserStores(); // 授权用户抽屉参数
|
||||
|
||||
const { crudBinding, crudRef, crudExpose } = useFs({
|
||||
createCrudOptions,
|
||||
context: { RoleDrawer, RoleMenuBtn, RoleMenuField },
|
||||
context: { RoleDrawer, RoleMenuBtn, RoleMenuField, RoleUserDrawer, RoleUserRef },
|
||||
});
|
||||
|
||||
// 页面打开后获取列表数据
|
||||
|
||||
29
web/src/views/system/role/stores/RoleUserStores.ts
Normal file
29
web/src/views/system/role/stores/RoleUserStores.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
/**
|
||||
* 权限抽屉:角色-用户
|
||||
*/
|
||||
|
||||
export const RoleUserStores = defineStore('RoleUserStores', {
|
||||
state: (): any => ({
|
||||
drawerVisible: false,
|
||||
role_id: undefined,
|
||||
role_name: undefined,
|
||||
}),
|
||||
actions: {
|
||||
/**
|
||||
* 打开权限修改抽屉
|
||||
*/
|
||||
handleDrawerOpen(row: any) {
|
||||
this.drawerVisible = true;
|
||||
this.role_name = row.name;
|
||||
this.role_id = row.id;
|
||||
},
|
||||
/**
|
||||
* 关闭权限修改抽屉
|
||||
*/
|
||||
handleDrawerClose() {
|
||||
this.drawerVisible = false;
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user