package service import ( "github.com/freefire/jiang13-bbs/model" ) // 权限码:后台功能点。路由通过 RequirePerm 声明, // 板块管理员的板块范围由 Actor.BoardIDs 在业务层二次校验。 const ( PermUsers = "users" // 用户与权限管理(超管/站长) PermAnnouncements = "announcements" // 公告管理(管理员及以上) PermSettings = "settings" // 站点外观设置(超管/站长) PermModeration = "moderation" // 内容审核(任意管理角色,板块范围受限) ) // Actor 当前请求操作者的实时权限快照(每次后台请求从 DB 现取, // 不依赖 JWT 内的 role claim,角色/授权变更立即生效) type Actor struct { ID uint Username string Role model.Role BoardIDs []uint // 板块管理员被授权的板块;其他角色为空 } // IsStaff 是否管理团队成员 func (a *Actor) IsStaff() bool { return a != nil && model.IsStaff(a.Role) } // HasPerm 是否拥有某后台功能点 func (a *Actor) HasPerm(p string) bool { if a == nil { return false } switch p { case PermUsers, PermSettings: return a.Role == model.RoleSuperAdmin || a.Role == model.RoleOwner case PermAnnouncements: return model.RoleLevel(a.Role) >= model.RoleLevel(model.RoleAdmin) case PermModeration: return a.IsStaff() } return false } // CanModerateBoard 是否可管理指定板块的内容: // 管理员及以上不限板块;板块管理员仅限被授权板块 func (a *Actor) CanModerateBoard(boardID uint) bool { if a == nil { return false } if model.RoleLevel(a.Role) >= model.RoleLevel(model.RoleAdmin) { return true } if a.Role != model.RoleBoardAdmin { return false } for _, id := range a.BoardIDs { if id == boardID { return true } } return false } // CanAssignRole 操作者能否把他人设置为目标角色(站长不可被授予,仅站长可授予超管) func (a *Actor) CanAssignRole(target model.Role) bool { if a == nil { return false } if target == model.RoleOwner { return false // 站长身份不通过授权产生 } if target == model.RoleSuperAdmin { return a.Role == model.RoleOwner } return a.HasPerm(PermUsers) } // LoadActor 读取用户实时角色与板块授权 func (s *AuthService) LoadActor(id uint) (*Actor, error) { var u model.User if err := s.db.Select("id", "username", "role").First(&u, id).Error; err != nil { return nil, err } actor := &Actor{ID: u.ID, Username: u.Username, Role: u.Role, BoardIDs: []uint{}} if u.Role == model.RoleBoardAdmin { var ids []uint if err := s.db.Model(&model.UserBoard{}). Where("user_id = ?", id). Order("board_id ASC"). Pluck("board_id", &ids).Error; err != nil { return nil, err } actor.BoardIDs = ids } return actor, nil } // GetUserBoardIDs 读取用户被授权的板块 ID(供 /me 等场景) func (s *AuthService) GetUserBoardIDs(id uint) ([]uint, error) { var ids []uint err := s.db.Model(&model.UserBoard{}). Where("user_id = ?", id).Order("board_id ASC").Pluck("board_id", &ids).Error return ids, err } // GetUserIDByUsername 按用户名查 ID(登录失败审计用),用户不存在返回 0 func (s *AuthService) GetUserIDByUsername(username string) uint { var u model.User if err := s.db.Select("id").Where("username = ?", username).First(&u).Error; err != nil { return 0 } return u.ID }