from rest_framework.permissions import BasePermission from config.exceptions import AppError class IsSuperAdmin(BasePermission): """仅超级管理员可访问(role_type=super_admin 或 Django is_superuser)。 超管拥有全部 CMS 功能权限且不受机构隔离限制。 """ def has_permission(self, request, view): user = request.user if user and user.is_authenticated and ( getattr(user, 'role_type', '') == 'super_admin' or user.is_superuser ): return True raise AppError('CMS_PERMISSION_DENIED', '仅超级管理员可访问该接口', status_code=403) def is_super(user): return getattr(user, 'role_type', '') == 'super_admin' or getattr(user, 'is_superuser', False) class IsSuperOrHospitalAdmin(BasePermission): """超级管理员(全平台)或医院管理员(仅本院)可访问。 具体的数据范围(本院过滤、角色限制)由各 ViewSet 的 get_queryset / 序列化器实现。 """ def has_permission(self, request, view): user = request.user if user and user.is_authenticated and ( is_super(user) or getattr(user, 'role_type', '') == 'hospital_admin' ): return True raise AppError('CMS_PERMISSION_DENIED', '需要超级管理员或医院管理员权限', status_code=403) def is_content_admin(user): return getattr(user, 'role_type', '') == 'content_admin' def is_hospital_admin(user): return getattr(user, 'role_type', '') == 'hospital_admin' class IsSuperContentOrHospitalAdmin(BasePermission): """超级管理员 / 内容管理员 / 医院管理员可访问(病例库 + AI 生成 + 病例审核)。 数据范围(超管全平台;内容/医院管理员仅本机构 `institution`)由 ViewSet 的 get_queryset 收口;各动作的角色权限(建/改归内容管理员,审核发布归医院管理员) 在 ViewSet 内逐动作判定。 """ def has_permission(self, request, view): user = request.user if user and user.is_authenticated and ( is_super(user) or is_content_admin(user) or is_hospital_admin(user) ): return True raise AppError('CMS_PERMISSION_DENIED', '需要超级管理员 / 内容管理员 / 医院管理员权限', status_code=403) class IsTeacher(BasePermission): """仅带教医生(role_type=doctor)可访问。 数据范围(名下学生)由 ViewSet 的 get_queryset 通过师生关系收口。 """ def has_permission(self, request, view): user = request.user if user and user.is_authenticated and getattr(user, 'role_type', '') == 'doctor': return True raise AppError('CMS_PERMISSION_DENIED', '仅带教医生可访问该接口', status_code=403)