package handlers import ( "context" "net/http" "time" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "yh_web/server/config" "yh_web/server/models" "github.com/gin-gonic/gin" ) // roleIDFromContext 从 context 安全取 role_id(JWT 等可能解码为 float64) func roleIDFromContext(c *gin.Context) (int, bool) { roleIDVal, ok := c.Get("role_id") if !ok { return 0, false } switch v := roleIDVal.(type) { case int: return v, true case float64: return int(v), true default: return 0, false } } // getPermissionsByRoleID 从 role_permissions 读取某角色的权限;9527 默认拥有全部 func getPermissionsByRoleID(ctx context.Context, roleID int) []string { if roleID == models.RoleIDSuperAdmin { return allPermissionKeys() } coll := config.GetDB(config.DBName).Collection("role_permissions") var doc models.RolePermissionsDoc err := coll.FindOne(ctx, bson.M{"role_id": roleID}).Decode(&doc) if err != nil { if err == mongo.ErrNoDocuments { return nil } return nil } return doc.Permissions } func allPermissionKeys() []string { keys := make([]string, 0, len(models.AllPermissions)) for _, p := range models.AllPermissions { keys = append(keys, p.Key) } return keys } // RequirePermission 要求当前用户拥有指定权限(在 AuthRequired 之后使用) func RequirePermission(permission string) gin.HandlerFunc { return func(c *gin.Context) { roleID, ok := roleIDFromContext(c) if !ok { c.JSON(http.StatusForbidden, gin.H{"error": "无权限"}) c.Abort() return } if roleID == models.RoleIDSuperAdmin { c.Next() return } ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() perms := getPermissionsByRoleID(ctx, roleID) for _, p := range perms { if p == permission { c.Next() return } } c.JSON(http.StatusForbidden, gin.H{"error": "无此操作权限"}) c.Abort() } } // GetMyPermissions 返回当前用户权限列表(供前端菜单、按钮显隐) func GetMyPermissions(c *gin.Context) { roleID, ok := roleIDFromContext(c) if !ok { c.JSON(http.StatusOK, gin.H{"permissions": []string{}}) return } ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() perms := getPermissionsByRoleID(ctx, roleID) c.JSON(http.StatusOK, gin.H{"permissions": perms}) }