实现在角色权限中加入数据权限鉴权配置办法数据权限
因为项目开发中涉及到比较细化的数据权限划分,需要对部门数据权限就行赋予数据权限(数据要根据各个部门进行权限查看),在框架的基础上进行了下修改,写的比较差,但功能实现了,具体如下:
实现菜单权限和数据权限的单独设置
实现办法,首先创建一个ba_role_data_permissions
表,存储角色对应的部门信息
DROP TABLE IF EXISTS `ba_role_data_permissions`;
CREATE TABLE `ba_role_data_permissions` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`role_id` int(11) UNSIGNED NOT NULL COMMENT '关联的角色ID,外键指向角色表',
`data_permission` enum('all','department','department_and_below','personal','custom') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '数据权限类型',
`custom_department_id` int(11) UNSIGNED NULL DEFAULT NULL COMMENT '可选的自定义部门ID,只有在权限类型为custom时使用',
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录更新时间',
PRIMARY KEY (`id`) USING BTREE,
INDEX `role_id`(`role_id`) USING BTREE,
CONSTRAINT `ba_role_data_permissions_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `ba_admin_group` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 49 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色与数据权限的关系表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
ba_hr_departments
表结构
DROP TABLE IF EXISTS `ba_hr_departments`;
CREATE TABLE `ba_hr_departments` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '部门名称',
`description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '部门描述',
`pid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '上级部门ID',
`sort` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '排序',
`status` enum('1','0') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '单选框:1=启用,0=禁用',
`create_time` bigint(16) UNSIGNED NULL DEFAULT NULL COMMENT '创建时间',
`update_time` bigint(16) UNSIGNED NULL DEFAULT NULL COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '部门管理' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
然后在\app\admin\controller\auth\Group.php
加入代码
public function setRoleDataPermission()
{
$roleId = $this->request->post('role_id');
$dataPermissionType = $this->request->post('data_permission');
$customDepartmentId = $this->request->post('custom_department_id');
// 验证角色ID的有效性
if (!$this->isValidRoleId($roleId)) {
$this->error('无效的角色ID');
}
// 设置数据权限
$dataPermission = [
'role_id' => $roleId,
'data_permission' => $dataPermissionType,
'custom_department_id' => $customDepartmentId,
];
// 检查是否存在记录
$exists = Db::name('role_data_permissions')->where('role_id', $roleId)->find();
if ($exists) {
// 如果存在,更新数据
$result = Db::name('role_data_permissions')->where('role_id', $roleId)->update($dataPermission);
} else {
// 如果不存在,插入新数据
$result = Db::name('role_data_permissions')->insert($dataPermission);
}
// 根据返回值判断操作是否成功
if ($result !== false) {
$this->success('数据权限设置成功');
} else {
$this->error('数据权限设置失败');
}
}
private function isValidRoleId($roleId)
{
//查找角色ID是否存在
$role = AdminGroup::where('id', $roleId)->find();
return $role !== null; //如果角色存在,返回true,否则返回false
}
接下来修改app\common\controller\Backend.php
里面的getDataLimitAdminIds
方法,修改后的代码
protected function getDataLimitAdminIds(): array
{
if (!$this->dataLimit || $this->auth->isSuperAdmin()) {
return [];
}
$adminIds = [];
// 获取角色的数据权限类型和自定义部门 ID
$dataPermissionType = $this->getDataPermissionType($this->auth->getRoleId());
$customDepartmentId = $this->getCustomDepartmentId($this->auth->getRoleId());
switch ($dataPermissionType) {
case 'all':
// 如果指定了 custom_department_id,获取该部门的所有管理员
$adminIds = $customDepartmentId
? $this->getDepartmentAdminIds($customDepartmentId)
: $this->getAllAdminIds();
break;
case 'department':
// 仅限于本部门
$adminIds = $this->getDepartmentAdminIds($this->auth->getDeptId());
break;
case 'department_and_below':
// 本部门及以下
$adminIds = $this->getDepartmentAndBelowAdminIds($this->auth->getDeptId());
break;
case 'personal':
// 仅限于本人
$adminIds[] = $this->auth->id;
break;
case 'custom':
// 自定义部门数据权限
if ($customDepartmentId) {
$adminIds = $this->getCustomDepartmentAdminIds($customDepartmentId);
}
break;
}
// 确保当前用户的 ID 被包含在结果中
// if (!in_array($this->auth->id, $adminIds)) {
// $adminIds[] = $this->auth->id;
// }
return array_unique($adminIds);
}
private function getDataPermissionType($roleId)
{
return Db::table('ba_role_data_permissions')->where('role_id', $roleId)->value('data_permission');
}
private function getCustomDepartmentId($roleId)
{
return Db::table('ba_role_data_permissions')->where('role_id', $roleId)->value('custom_department_id');
}
private function getAllAdminIds(): array
{
return Db::table('ba_admin')->column('id');
}
private function getDepartmentAdminIds($departmentId): array
{
$adminIds = Db::name('admin')
->where('dpt_id', $departmentId)
->column('id');
// if (!in_array($this->auth->id, $adminIds)) {
// $adminIds[] = $this->auth->id;
// }
return array_unique($adminIds);
}
private function getDepartmentAndBelowAdminIds($departmentId): array
{
$departmentIds = $this->getAllChildDepartmentIds($departmentId);
return Db::name('admin')
->whereIn('dpt_id', $departmentIds)
->column('id');
}
private function getCustomDepartmentAdminIds($customDepartmentId): array
{
// 获取当前部门及其所有子部门的管理员 ID
$adminIds = Db::name('admin')
->whereIn('dpt_id', $this->getAllChildDepartmentIds($customDepartmentId))
->column('id');
// 添加当前用户的 ID(如果当前用户不在结果中)
// if (!in_array($this->auth->id, $adminIds)) {
// $adminIds[] = $this->auth->id;
// }
return array_unique($adminIds);
}
private function getAllChildDepartmentIds($departmentId): array
{
// 获取当前部门的子部门ID
$children = Db::name('hr_departments')
->where('pid', $departmentId)
->column('id');
// 创建一个数组,包含当前部门ID和所有子部门ID
$allIds = [$departmentId]; // 添加当前部门ID
foreach ($children as $childId) {
$allIds = array_merge($allIds, $this->getAllChildDepartmentIds($childId));
}
return array_unique($allIds);
}
在app\admin\library\Auth.php
里面新增
//获取当前用户的角色id
public function getRoleId()
{
$roleid=Db::table('ba_admin_group_access')->where('uid',$this->id)->value('group_id');
return $roleid;
}
//获取当前用户的部门id
public function getDeptId()
{
$deptid=Db::table('ba_admin')->where('id',$this->id)->value('dpt_id');
return $deptid;
}
然后对需要开启数据权限的控制器加入对应代码就可以进行数据权限校验了
/**
* 开启数据限制
*/
protected bool|string|int $dataLimit = false;
/**
* 数据限制字段,数据表内必须存在此字段
*/
protected string $dataLimitField = 'admin_id';
/**
* 数据限制开启时自动填充字段值为当前管理员id
*/
protected bool $dataLimitFieldAutoFill = true;
前端配置代码
<template>
<el-dialog class="ba-operate-dialog" v-model="baTable.table.extend!.showInfo" width="50%">
<template #header>
<div class="title" v-drag="['.ba-operate-dialog', '.el-dialog__header']" v-zoom="'.ba-operate-dialog'">数据权限</div>
</template>
<el-form v-if="baTable.table.extend!.infoData" :model="form" ref="formRef">
<el-form-item label="角色ID" prop="role_id">
<el-input v-model="form.role_id" disabled />
</el-form-item>
<el-form-item label="角色名称" prop="role_name">
<el-input v-model="baTable.table.extend!.infoData.name" disabled/>
</el-form-item>
<el-form-item label="数据权限" prop="data_permission">
<el-select v-model="form.data_permission">
<el-option label="全部数据权限" value="all" />
<el-option label="本部门数据权限" value="department" />
<el-option label="本部门及以下数据权限" value="department_and_below" />
<el-option label="本人数据权限" value="personal" />
<el-option label="自定义数据权限" value="custom" />
</el-select>
</el-form-item>
<el-form-item v-if="form.data_permission === 'custom'" label="自定义部门ID" prop="custom_department_id">
<el-input v-model="form.custom_department_id" />
</el-form-item>
</el-form>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="savePermission">确 定</el-button>
</span>
</el-dialog>
</template>
cleanXss
import { inject,ref,watch } from 'vue'
import { timeFormat } from '/@/utils/common'
import type baTableClass from '/@/utils/baTable'
import FormItem from '/@/components/formItem/index.vue'
import{setRoleDataPermission}from '/@/api/backend/auth/group'
const baTable = inject('baTable') as baTableClass
import { ElMessage } from 'element-plus';
const formRef = ref(); // 声明表单引用
const dialogVisible = ref(false);
const form = ref({
role_id: '',
data_permission: '',
custom_department_id: ''
});
const savePermission = () => {
console.log(form.value);
setRoleDataPermission(form.value).then(res => {
console.log(res);
if (res.code === 1) {
ElMessage.success('权限已保存');
baTable.table.extend!.showInfo = false;
// 刷新权限列表逻辑
} else {
ElMessage.error('保存权限失败');
}
}).catch(err => {
ElMessage.error('保存权限失败');
})
};
// 监听父组件传来的 infoData 变化
watch(() => baTable.table.extend!.infoData, (newValue) => {
if (newValue) {
form.value.role_id = newValue.id; // 设置角色ID
// 可以根据需要设置其他字段
}
});
cleanXss
<style scoped lang="scss">
.info-box {
margin-top: 60px;
div {
width: 100%;
text-align: center;
}
.mt-40 {
margin-top: 40px;
}
}
</style>
其他注意事项:
需在admin表内新增一个dpt_id字段存储用户的部门id
请先登录
列表页增加按钮的代码好像没写?
你这里面的cleanXss是什么意思?
才看到回复。楼主辛苦了。。。暂时用不到,先做个记号!
代他回答你:一个安全函数。。。文档有写。。。
学习一下
感谢分享
感谢分享
感谢分享
router.ts:22 SyntaxError: The requested module '/src/api/backend/auth/group.ts?t=1730278509639' does not provide an export named 'setRoleDataPermission' (at info.vue:42:10)
triggerError @ vue-router.mjs:3578
(匿名) @ vue-router.mjs:3291
Promise.catch(异步)
pushWithRedirect @ vue-router.mjs:3285
push @ vue-router.mjs:3217
routePush @ router.ts:22
(匿名) @ index.vue:78
Promise.then(异步)
init @ index.vue:59
(匿名) @ index.vue:46
(匿名) @ runtime-core.esm-bundler.js:1552
callWithErrorHandling @ runtime-core.esm-bundler.js:202
callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:209
hook.__weh.hook.__weh @ runtime-core.esm-bundler.js:1532
flushPostFlushCbs @ runtime-core.esm-bundler.js:386
flushJobs @ runtime-core.esm-bundler.js:426
Promise.then(异步)
queueFlush @ runtime-core.esm-bundler.js:326
queueJob @ runtime-core.esm-bundler.js:320
scheduler @ runtime-core.esm-bundler.js:5988
resetScheduling @ reactivity.esm-bundler.js:262
triggerEffects @ reactivity.esm-bundler.js:306
triggerRefValue @ reactivity.esm-bundler.js:1079
set value @ reactivity.esm-bundler.js:1126
finalizeNavigation @ vue-router.mjs:3460
(匿名) @ vue-router.mjs:3325
Promise.then(异步)
pushWithRedirect @ vue-router.mjs:3292
pushWithRedirect @ vue-router.mjs:3260
push @ vue-router.mjs:3217
install @ vue-router.mjs:3659
use @ runtime-core.esm-bundler.js:2576
start @ main.ts:23
await in start(异步)
(匿名) @ main.ts:36
显示另外 24 个框架
router.ts:39 SyntaxError: The requested module '/src/api/backend/auth/group.ts?t=1730278509639' does not provide an export named 'setRoleDataPermission' (at info.vue:42:10)
提示这个找不到
很不错,感谢贡献!
应该弄成一个模块,直接安装
- 1
前往