Files
djangoadmin-wiki/DjangoAdmin_Flask_AntdVue/zh/volume4/business/role.md
T
2026-09-13 21:53:16 +08:00

6.7 KiB
Raw Blame History

:::tip 角色管理 角色是 RBAC 权限模型的核心,连接用户和菜单(权限)。通过为角色分配菜单权限,再将角色分配给用户,实现灵活的权限管理。角色删除时需清理关联的用户角色和角色菜单数据,并即时失效受影响用户的权限缓存。 :::

模块结构

src/modules/system/role/
├── models.py     # 角色模型
├── schema.py     # 表单验证(WTForms)
├── repository.py # 数据访问层
├── service.py    # 业务逻辑层(继承 BaseService)
└── router.py     # 路由控制器

src/modules/association/role_menu/
├── models.py     # 角色-菜单关联模型
├── repository.py # 关联数据访问
└── service.py    # 关联业务逻辑

角色模型

# src/modules/system/role/models.py
# ============================================================
# 角色模型
# ============================================================
class Role(BaseModel, BaseDB):
    """角色模型类"""
    # ============================================================
    # 表名配置
    # ============================================================
    __tablename__ = DB_PREFIX + "role"
    __table_comment__ = "角色表"

    # ============================================================
    # 字段定义
    # ============================================================
    # 角色名称
    name = Column(String(150), nullable=False, index=True, comment="角色名称")
    # 角色编码
    code = Column(String(30), nullable=False, index=True, comment="角色编码")
    # 角色排序
    sort = Column(Integer, default=0, server_default=text('0'), comment="角色排序")
    # 角色备注
    note = Column(String(255), nullable=True, comment="角色备注")

    # ============================================================
    # 内置方法
    # ============================================================
    def __str__(self):
        """返回角色名称作为字符串表示"""
        return '角色{}:'.format(self.name)

角色-菜单关联

角色与菜单通过 flask_role_menu 关联表实现多对多关系:

# src/modules/system/role_menu/models.py
# ============================================================
# 角色菜单关联模型
# ============================================================
class RoleMenu(BaseModel, BaseDB):
    """角色菜单关联模型类"""
    # ============================================================
    # 表名配置
    # ============================================================
    __tablename__ = DB_PREFIX + "role_menu"
    __table_comment__ = "角色菜单关联表"

    # ============================================================
    # 字段定义
    # ============================================================
    # 角色ID
    role_id = Column(Integer, default=0, server_default=text('0'), index=True, comment="角色ID")
    # 菜单ID
    menu_id = Column(Integer, default=0, server_default=text('0'), index=True, comment="菜单ID")

    # ============================================================
    # 内置方法
    # ============================================================
    def __str__(self):
        """返回角色ID作为字符串表示"""
        return "角色菜单表{}".format(self.role_id)

自定义 Service

角色模块继承 BaseService,覆写删除前钩子处理关联清理和缓存失效:

# src/modules/system/role/service.py
from src.common.base_service import BaseService
from src.modules.system.role.schema import RoleForm
from src.modules.system.role.repository import RoleRepository
from src.modules.association.user_role.repository import UserRoleRepository
from src.modules.system.menu.service import invalidate_user_cache


class RoleService(BaseService):
    """
    角色服务类

    继承 BaseService 获得标准 CRUD 能力,并扩展删除前清除用户权限缓存。
    """
    repository = RoleRepository
    form = RoleForm
    model_name = "角色"

    @classmethod
    def before_delete(cls, ids):
        """
        删除前钩子:清除该角色关联用户的权限缓存

        Args:
            ids: 待删除的角色ID列表
        """
        for rid in ids:
            for uid in UserRoleRepository.get_users_by_role(rid):
                invalidate_user_cache(uid)


# 模块级代理函数
get_role_page = RoleService.get_page
get_role_detail = RoleService.get_detail
add_role = RoleService.add
update_role = RoleService.update
delete_roles = RoleService.remove
get_role_list = RoleService.get_list

删除与缓存清理

角色删除时,before_delete 钩子会先收集受影响用户并清理权限缓存:

# src/modules/system/role/service.py
class RoleService(BaseService):
    @classmethod
    def before_delete(cls, ids):
        """
        删除前钩子:清除该角色关联用户的权限缓存

        在 BaseService.remove() 执行批量软删除之前调用,
        确保权限缓存及时失效。
        """
        for rid in ids:
            for uid in UserRoleRepository.get_users_by_role(rid):
                invalidate_user_cache(uid)

:::warning 删除顺序 before_delete 在 BaseService.remove() 的批量软删除之前执行,此时 UserRole 关联尚未删除,可以正常查询受影响用户。BaseService 的 remove() 方法会自动调用 repository.batch_delete() 完成软删除。 :::

API 接口

接口 方法 权限节点 说明
/api/v1/role/page GET sys:role:page 角色分页列表
/api/v1/role/list GET sys:role:list 角色列表(无分页)
/api/v1/role/detail/{id} GET sys:role:detail 角色详情
/api/v1/role/add POST sys:role:add 新增角色
/api/v1/role/update PUT sys:role:update 编辑角色
/api/v1/role/delete/{id} DELETE sys:role:delete 删除角色
/api/v1/role/batchDelete DELETE sys:role:batchDelete 批量删除
/api/v1/role/auth POST sys:role:auth 分配菜单权限

前端权限分配

角色管理页面通常包含菜单树组件,用于勾选分配权限:

<a-tree
    :tree-data="menuTree"
    :fieldNames="{ children: 'children', title: 'name', key: 'id' }"
    :height="600"
    v-model:checkedKeys="checkedKeys"
    v-model:expandedKeys="expandedKeys"
    checkable
/>

总结

角色管理模块具备以下特点:

1. RBAC 核心:连接用户和权限的桥梁
2. 继承 BaseService:标准 CRUD + 表单校验(WTForms)
3. before_delete 钩子:删除前清理关联用户的权限缓存
4. 灵活组合:一个角色可分配多个菜单,一个用户可拥有多个角色