From 9d76411ef9a1f8b9dd150871d380045eb0b3edd3 Mon Sep 17 00:00:00 2001 From: zijiren233 Date: Tue, 31 Oct 2023 13:18:44 +0800 Subject: [PATCH] Refector: search user and room --- internal/db/db.go | 54 ++++++++++++++++-- internal/db/room.go | 10 +--- internal/db/user.go | 31 ++++++---- server/handlers/admin.go | 118 +++++++++++++++------------------------ server/handlers/init.go | 10 +--- server/handlers/room.go | 16 +++--- server/handlers/root.go | 17 ------ server/handlers/user.go | 51 ++++++++--------- 8 files changed, 149 insertions(+), 158 deletions(-) diff --git a/internal/db/db.go b/internal/db/db.go index 44ac0a3..e342c70 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -140,13 +140,13 @@ func WhereLike(column string, value string) func(db *gorm.DB) *gorm.DB { } } -func WhereRoomNameLikeOrCreatorIn(name string, ids []string) func(db *gorm.DB) *gorm.DB { +func WhereRoomNameLikeOrCreatorInOrIDLike(name string, ids []string, id string) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { switch dbType { case conf.DatabaseTypePostgres: - return db.Where("name ILIKE ? OR creator_id IN ?", utils.LIKE(name), ids) + return db.Where("name ILIKE ? OR creator_id IN ? OR id ILIKE ?", utils.LIKE(name), ids, id) default: - return db.Where("name LIKE ? OR creator_id IN ?", utils.LIKE(name), ids) + return db.Where("name LIKE ? OR creator_id IN ? OR id LIKE ?", utils.LIKE(name), ids, id) } } } @@ -162,7 +162,7 @@ func WhereRoomNameLike(name string) func(db *gorm.DB) *gorm.DB { } } -func WhereUserNameLike(name string) func(db *gorm.DB) *gorm.DB { +func WhereUsernameLike(name string) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { switch dbType { case conf.DatabaseTypePostgres: @@ -190,3 +190,49 @@ func WhereStatus(status model.RoomStatus) func(db *gorm.DB) *gorm.DB { return db.Where("status = ?", status) } } + +func WhereRole(role model.Role) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + return db.Where("role = ?", role) + } +} + +func WhereUsernameLikeOrIDIn(name string, ids []string) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + switch dbType { + case conf.DatabaseTypePostgres: + return db.Where("username ILIKE ? OR id IN ?", utils.LIKE(name), ids) + default: + return db.Where("username LIKE ? OR id IN ?", utils.LIKE(name), ids) + } + } +} + +func WhereIDIn(ids []string) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + return db.Where("id IN ?", ids) + } +} + +func WhereRoomSettingWithoutHidden() func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + return db.Where("settings_hidden = ?", false) + } +} + +func WhereRoomSettingHidden() func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + return db.Where("settings_hidden = ?", true) + } +} + +func WhereIDLike(id string) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + switch dbType { + case conf.DatabaseTypePostgres: + return db.Where("id ILIKE ?", utils.LIKE(id)) + default: + return db.Where("id LIKE ?", utils.LIKE(id)) + } + } +} diff --git a/internal/db/room.go b/internal/db/room.go index 3f97570..4cce077 100644 --- a/internal/db/room.go +++ b/internal/db/room.go @@ -172,15 +172,9 @@ func GetAllRooms(scopes ...func(*gorm.DB) *gorm.DB) []*model.Room { return rooms } -func GetAllRoomsWithoutHidden(scopes ...func(*gorm.DB) *gorm.DB) []*model.Room { - rooms := []*model.Room{} - db.Where("settings_hidden = ?", false).Scopes(scopes...).Find(&rooms) - return rooms -} - -func GetAllRoomsWithoutHiddenCount(scopes ...func(*gorm.DB) *gorm.DB) int64 { +func GetAllRoomsCount(scopes ...func(*gorm.DB) *gorm.DB) int64 { var count int64 - db.Model(&model.Room{}).Where("settings_hidden = ?", false).Scopes(scopes...).Count(&count) + db.Model(&model.Room{}).Scopes(scopes...).Count(&count) return count } diff --git a/internal/db/user.go b/internal/db/user.go index e011f11..1a2e3be 100644 --- a/internal/db/user.go +++ b/internal/db/user.go @@ -6,6 +6,7 @@ import ( "github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/provider" + "github.com/synctv-org/synctv/utils" "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -106,6 +107,12 @@ func GerUsersIDByUsernameLike(username string, scopes ...func(*gorm.DB) *gorm.DB return ids } +func GerUsersIDByIDLike(id string, scopes ...func(*gorm.DB) *gorm.DB) []string { + var ids []string + db.Model(&model.User{}).Where(`id LIKE ?`, utils.LIKE(id)).Scopes(scopes...).Pluck("id", &ids) + return ids +} + func GetUserByIDOrUsernameLike(idOrUsername string, scopes ...func(*gorm.DB) *gorm.DB) ([]*model.User, error) { var users []*model.User err := db.Where("id = ? OR username LIKE ?", idOrUsername, fmt.Sprintf("%%%s%%", idOrUsername)).Scopes(scopes...).Find(&users).Error @@ -271,18 +278,6 @@ func SetRoleByID(userID string, role model.Role) error { return err } -func GetAllUserWithRoleUser(role model.Role, scopes ...func(*gorm.DB) *gorm.DB) []*model.User { - users := []*model.User{} - db.Where("role = ?", role).Scopes(scopes...).Find(&users) - return users -} - -func GetAllUserCountWithRole(role model.Role, scopes ...func(*gorm.DB) *gorm.DB) int64 { - var count int64 - db.Model(&model.User{}).Where("role = ?", role).Scopes(scopes...).Count(&count) - return count -} - func SetUsernameByID(userID string, username string) error { err := db.Model(&model.User{}).Where("id = ?", userID).Update("username", username).Error if errors.Is(err, gorm.ErrRecordNotFound) { @@ -290,3 +285,15 @@ func SetUsernameByID(userID string, username string) error { } return err } + +func GetAllUserCount(scopes ...func(*gorm.DB) *gorm.DB) int64 { + var count int64 + db.Model(&model.User{}).Scopes(scopes...).Count(&count) + return count +} + +func GetAllUsers(scopes ...func(*gorm.DB) *gorm.DB) []*model.User { + var users []*model.User + db.Scopes(scopes...).Find(&users) + return users +} diff --git a/server/handlers/admin.go b/server/handlers/admin.go index 5e42677..ba71774 100644 --- a/server/handlers/admin.go +++ b/server/handlers/admin.go @@ -56,12 +56,6 @@ func AdminSettings(ctx *gin.Context) { func Users(ctx *gin.Context) { // user := ctx.MustGet("user").(*op.User) - order := ctx.Query("order") - if order == "" { - ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("order is required")) - return - } - page, pageSize, err := GetPageAndPageSize(ctx) if err != nil { ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) @@ -72,11 +66,21 @@ func Users(ctx *gin.Context) { scopes := []func(db *gorm.DB) *gorm.DB{} - if keyword := ctx.Query("keyword"); keyword != "" { - scopes = append(scopes, db.WhereUserNameLike(keyword)) + switch ctx.DefaultQuery("role", "user") { + case "admin": + scopes = append(scopes, db.WhereRole(dbModel.RoleAdmin)) + case "user": + scopes = append(scopes, db.WhereRole(dbModel.RoleUser)) + case "pending": + scopes = append(scopes, db.WhereRole(dbModel.RolePending)) + case "banned": + scopes = append(scopes, db.WhereRole(dbModel.RoleBanned)) + default: + ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("not support role")) + return } - switch order { + switch ctx.DefaultQuery("order", "createdAt") { case "createdAt": if desc { scopes = append(scopes, db.OrderByCreatedAtDesc) @@ -100,14 +104,26 @@ func Users(ctx *gin.Context) { return } + if keyword := ctx.Query("keyword"); keyword != "" { + // search mode, all, name, id + switch ctx.DefaultQuery("search", "all") { + case "all": + scopes = append(scopes, db.WhereUsernameLikeOrIDIn(keyword, db.GerUsersIDByIDLike(keyword))) + case "name": + scopes = append(scopes, db.WhereUsernameLike(keyword)) + case "id": + scopes = append(scopes, db.WhereIDIn(db.GerUsersIDByIDLike(keyword))) + } + } + ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{ - "total": db.GetAllUserCountWithRole(dbModel.RoleUser, scopes...), - "list": genUserListResp(dbModel.RoleUser, append(scopes, db.Paginate(page, pageSize))...), + "total": db.GetAllUserCount(scopes...), + "list": genUserListResp(append(scopes, db.Paginate(page, pageSize))...), })) } -func genUserListResp(role dbModel.Role, scopes ...func(db *gorm.DB) *gorm.DB) []*model.UserInfoResp { - us := db.GetAllUserWithRoleUser(role, scopes...) +func genUserListResp(scopes ...func(db *gorm.DB) *gorm.DB) []*model.UserInfoResp { + us := db.GetAllUsers(scopes...) resp := make([]*model.UserInfoResp, len(us)) for i, v := range us { resp[i] = &model.UserInfoResp{ @@ -120,58 +136,6 @@ func genUserListResp(role dbModel.Role, scopes ...func(db *gorm.DB) *gorm.DB) [] return resp } -func PendingUsers(ctx *gin.Context) { - // user := ctx.MustGet("user").(*op.User) - order := ctx.Query("order") - if order == "" { - ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("order is required")) - return - } - - page, pageSize, err := GetPageAndPageSize(ctx) - if err != nil { - ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) - return - } - - var desc = ctx.DefaultQuery("sort", "desc") == "desc" - - scopes := []func(db *gorm.DB) *gorm.DB{} - - if keyword := ctx.Query("keyword"); keyword != "" { - scopes = append(scopes, db.WhereUserNameLike(keyword)) - } - - switch order { - case "createdAt": - if desc { - scopes = append(scopes, db.OrderByCreatedAtDesc) - } else { - scopes = append(scopes, db.OrderByCreatedAtAsc) - } - case "name": - if desc { - scopes = append(scopes, db.OrderByDesc("username")) - } else { - scopes = append(scopes, db.OrderByAsc("username")) - } - case "id": - if desc { - scopes = append(scopes, db.OrderByIDDesc) - } else { - scopes = append(scopes, db.OrderByIDAsc) - } - default: - ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("not support order")) - return - } - - ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{ - "total": db.GetAllUserCountWithRole(dbModel.RolePending, scopes...), - "list": genUserListResp(dbModel.RolePending, append(scopes, db.Paginate(page, pageSize))...), - })) -} - func ApprovePendingUser(ctx *gin.Context) { req := model.UserIDReq{} if err := model.Decode(ctx, &req); err != nil { @@ -240,7 +204,7 @@ func BanUser(ctx *gin.Context) { ctx.Status(http.StatusNoContent) } -func PendingRooms(ctx *gin.Context) { +func Rooms(ctx *gin.Context) { // user := ctx.MustGet("user").(*op.User) order := ctx.Query("order") if order == "" { @@ -256,12 +220,18 @@ func PendingRooms(ctx *gin.Context) { var desc = ctx.DefaultQuery("sort", "desc") == "desc" - scopes := []func(db *gorm.DB) *gorm.DB{ - db.WhereStatus(dbModel.RoomStatusPending), - } + scopes := []func(db *gorm.DB) *gorm.DB{} - if keyword := ctx.Query("keyword"); keyword != "" { - scopes = append(scopes, db.WhereRoomNameLike(keyword)) + switch ctx.DefaultQuery("status", "active") { + case "active": + scopes = append(scopes, db.WhereStatus(dbModel.RoomStatusActive)) + case "pending": + scopes = append(scopes, db.WhereStatus(dbModel.RoomStatusPending)) + case "banned": + scopes = append(scopes, db.WhereStatus(dbModel.RoomStatusBanned)) + default: + ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("not support status")) + return } switch order { @@ -292,16 +262,18 @@ func PendingRooms(ctx *gin.Context) { // search mode, all, name, creator switch ctx.DefaultQuery("search", "all") { case "all": - scopes = append(scopes, db.WhereRoomNameLikeOrCreatorIn(keyword, db.GerUsersIDByUsernameLike(keyword))) + scopes = append(scopes, db.WhereRoomNameLikeOrCreatorInOrIDLike(keyword, db.GerUsersIDByUsernameLike(keyword), keyword)) case "name": scopes = append(scopes, db.WhereRoomNameLike(keyword)) case "creator": scopes = append(scopes, db.WhereCreatorIDIn(db.GerUsersIDByUsernameLike(keyword))) + case "id": + scopes = append(scopes, db.WhereIDLike(keyword)) } } ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{ - "total": db.GetAllRoomsWithoutHiddenCount(scopes...), + "total": db.GetAllRoomsCount(scopes...), "list": genRoomListResp(append(scopes, db.Paginate(page, pageSize))...), })) } diff --git a/server/handlers/init.go b/server/handlers/init.go index f188cff..686c371 100644 --- a/server/handlers/init.go +++ b/server/handlers/init.go @@ -51,9 +51,7 @@ func Init(e *gin.Engine) { admin.GET("/users", Users) - admin.GET("/pending/users", PendingUsers) - - admin.GET("/pending/rooms", PendingRooms) + admin.GET("/rooms", Rooms) admin.POST("/approve/user", ApprovePendingUser) @@ -65,11 +63,9 @@ func Init(e *gin.Engine) { } { - root.GET("/admins", Admins) - - root.POST("/addAdmin", AddAdmin) + root.POST("/admin/add", AddAdmin) - root.POST("/deleteAdmin", DeleteAdmin) + root.POST("/admin/delete", DeleteAdmin) } } diff --git a/server/handlers/room.go b/server/handlers/room.go index c234e84..7b15f7d 100644 --- a/server/handlers/room.go +++ b/server/handlers/room.go @@ -79,11 +79,6 @@ func RoomHotList(ctx *gin.Context) { } func RoomList(ctx *gin.Context) { - order := ctx.Query("order") - if order == "" { - ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("order is required")) - return - } page, pageSize, err := GetPageAndPageSize(ctx) if err != nil { ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) @@ -93,10 +88,11 @@ func RoomList(ctx *gin.Context) { var desc = ctx.DefaultQuery("sort", "desc") == "desc" scopes := []func(db *gorm.DB) *gorm.DB{ + db.WhereRoomSettingWithoutHidden(), db.WhereStatus(dbModel.RoomStatusActive), } - switch order { + switch ctx.DefaultQuery("order", "createdAt") { case "createdAt": if desc { scopes = append(scopes, db.OrderByCreatedAtDesc) @@ -124,22 +120,24 @@ func RoomList(ctx *gin.Context) { // search mode, all, name, creator switch ctx.DefaultQuery("search", "all") { case "all": - scopes = append(scopes, db.WhereRoomNameLikeOrCreatorIn(keyword, db.GerUsersIDByUsernameLike(keyword))) + scopes = append(scopes, db.WhereRoomNameLikeOrCreatorInOrIDLike(keyword, db.GerUsersIDByUsernameLike(keyword), keyword)) case "name": scopes = append(scopes, db.WhereRoomNameLike(keyword)) case "creator": scopes = append(scopes, db.WhereCreatorIDIn(db.GerUsersIDByUsernameLike(keyword))) + case "id": + scopes = append(scopes, db.WhereIDLike(keyword)) } } ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{ - "total": db.GetAllRoomsWithoutHiddenCount(scopes...), + "total": db.GetAllRoomsCount(scopes...), "list": genRoomListResp(append(scopes, db.Paginate(page, pageSize))...), })) } func genRoomListResp(scopes ...func(db *gorm.DB) *gorm.DB) []*model.RoomListResp { - rs := db.GetAllRoomsWithoutHidden(scopes...) + rs := db.GetAllRooms(scopes...) resp := make([]*model.RoomListResp, len(rs)) for i, r := range rs { resp[i] = &model.RoomListResp{ diff --git a/server/handlers/root.go b/server/handlers/root.go index 22b0f62..6278b2e 100644 --- a/server/handlers/root.go +++ b/server/handlers/root.go @@ -4,28 +4,11 @@ import ( "net/http" "github.com/gin-gonic/gin" - "github.com/synctv-org/synctv/internal/db" dbModel "github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/op" "github.com/synctv-org/synctv/server/model" ) -func Admins(ctx *gin.Context) { - // user := ctx.MustGet("user").(*op.User) - - u := db.GetAdmins() - us := make([]model.UserInfoResp, len(u)) - for i, v := range u { - us[i] = model.UserInfoResp{ - ID: v.ID, - Username: v.Username, - Role: v.Role, - CreatedAt: v.CreatedAt.UnixMilli(), - } - } - ctx.JSON(http.StatusOK, model.NewApiDataResp(us)) -} - func AddAdmin(ctx *gin.Context) { user := ctx.MustGet("user").(*op.User) diff --git a/server/handlers/user.go b/server/handlers/user.go index 5867f3b..2e8737d 100644 --- a/server/handlers/user.go +++ b/server/handlers/user.go @@ -5,6 +5,7 @@ import ( "github.com/gin-gonic/gin" "github.com/synctv-org/synctv/internal/db" + dbModel "github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/op" "github.com/synctv-org/synctv/server/model" "gorm.io/gorm" @@ -48,13 +49,19 @@ func UserRooms(ctx *gin.Context) { var desc = ctx.DefaultQuery("sort", "desc") == "desc" - // search mode, all, name - var search = ctx.DefaultQuery("search", "all") - scopes := []func(db *gorm.DB) *gorm.DB{ db.WhereCreatorID(user.ID), } + switch ctx.DefaultQuery("status", "active") { + case "active": + scopes = append(scopes, db.WhereStatus(dbModel.RoomStatusActive)) + case "pending": + scopes = append(scopes, db.WhereStatus(dbModel.RoomStatusPending)) + case "banned": + scopes = append(scopes, db.WhereStatus(dbModel.RoomStatusBanned)) + } + switch order { case "createdAt": if desc { @@ -62,49 +69,37 @@ func UserRooms(ctx *gin.Context) { } else { scopes = append(scopes, db.OrderByCreatedAtAsc) } - if keyword := ctx.Query("keyword"); keyword != "" { - switch search { - case "all": - scopes = append(scopes, db.WhereRoomNameLikeOrCreatorIn(keyword, db.GerUsersIDByUsernameLike(keyword))) - case "name": - scopes = append(scopes, db.WhereRoomNameLike(keyword)) - } - } case "roomName": if desc { scopes = append(scopes, db.OrderByDesc("name")) } else { scopes = append(scopes, db.OrderByAsc("name")) } - if keyword := ctx.Query("keyword"); keyword != "" { - switch search { - case "all": - scopes = append(scopes, db.WhereRoomNameLikeOrCreatorIn(keyword, db.GerUsersIDByUsernameLike(keyword))) - case "name": - scopes = append(scopes, db.WhereRoomNameLike(keyword)) - } - } case "roomId": if desc { scopes = append(scopes, db.OrderByIDDesc) } else { scopes = append(scopes, db.OrderByIDAsc) } - if keyword := ctx.Query("keyword"); keyword != "" { - switch search { - case "all": - scopes = append(scopes, db.WhereRoomNameLikeOrCreatorIn(keyword, db.GerUsersIDByUsernameLike(keyword))) - case "name": - scopes = append(scopes, db.WhereRoomNameLike(keyword)) - } - } default: ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("not support order")) return } + if keyword := ctx.Query("keyword"); keyword != "" { + // search mode, all, name, creator + switch ctx.DefaultQuery("search", "all") { + case "all": + scopes = append(scopes, db.WhereRoomNameLikeOrCreatorInOrIDLike(keyword, db.GerUsersIDByUsernameLike(keyword), keyword)) + case "name": + scopes = append(scopes, db.WhereRoomNameLike(keyword)) + case "id": + scopes = append(scopes, db.WhereIDLike(keyword)) + } + } + ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{ - "total": db.GetAllRoomsWithoutHiddenCount(scopes...), + "total": db.GetAllRooms(scopes...), "list": genRoomListResp(append(scopes, db.Paginate(page, pageSize))...), })) }