Feat: add admin api: room users and user rooms

pull/31/head
zijiren233 2 years ago
parent 577490d92d
commit 67658c9398

@ -109,6 +109,14 @@ func WhereRoomID(roomID string) func(db *gorm.DB) *gorm.DB {
}
}
func PreloadRoomUserRelation(scopes ...func(*gorm.DB) *gorm.DB) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Preload("RoomUserRelations", func(db *gorm.DB) *gorm.DB {
return db.Scopes(scopes...)
})
}
}
func WhereUserID(userID string) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("user_id = ?", userID)
@ -151,6 +159,17 @@ func WhereRoomNameLikeOrCreatorInOrIDLike(name string, ids []string, id string)
}
}
func WhereRoomNameLikeOrIDLike(name 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 id ILIKE ?", utils.LIKE(name), id)
default:
return db.Where("name LIKE ? OR id LIKE ?", utils.LIKE(name), id)
}
}
}
func WhereRoomNameLike(name string) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
switch dbType {

@ -81,3 +81,9 @@ func GetAllRoomUsersRelation(roomID string, scopes ...func(*gorm.DB) *gorm.DB) [
db.Where("room_id = ?", roomID).Scopes(scopes...).Find(&roomUserRelations)
return roomUserRelations
}
func GetAllRoomUsersRelationCount(roomID string, scopes ...func(*gorm.DB) *gorm.DB) int64 {
var count int64
db.Model(&model.RoomUserRelation{}).Where("room_id = ?", roomID).Scopes(scopes...).Count(&count)
return count
}

@ -5,7 +5,7 @@ import (
"time"
)
type RoomUserStatus uint
type RoomUserStatus uint64
const (
RoomUserStatusBanned RoomUserStatus = iota + 1
@ -26,7 +26,7 @@ func (r RoomUserStatus) String() string {
}
}
type RoomUserPermission uint32
type RoomUserPermission uint64
const (
PermissionAll RoomUserPermission = 0xffffffff

@ -43,7 +43,7 @@ type User struct {
Providers []UserProvider `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
Username string `gorm:"not null;uniqueIndex"`
Role Role `gorm:"not null;default:2"`
GroupUserRelations []RoomUserRelation `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
RoomUserRelations []RoomUserRelation `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
Rooms []Room `gorm:"foreignKey:CreatorID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
Movies []Movie `gorm:"foreignKey:CreatorID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
StreamingVendorInfos []StreamingVendorInfo `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`

@ -127,6 +127,77 @@ func genUserListResp(us []*dbModel.User) []*model.UserInfoResp {
return resp
}
func GetRoomUsers(ctx *gin.Context) {
id := ctx.Query("id")
if len(id) != 32 {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("room id error"))
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{
db.PreloadRoomUserRelation(db.WhereRoomID(id)),
}
switch ctx.DefaultQuery("order", "name") {
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"))
}
default:
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("not support order"))
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.GetAllUserCount(scopes...),
"list": genRoomUserListResp(db.GetAllUsers(append(scopes, db.Paginate(page, pageSize))...)),
}))
}
func genRoomUserListResp(us []*dbModel.User) []*model.RoomUsersResp {
resp := make([]*model.RoomUsersResp, len(us))
for i, v := range us {
resp[i] = &model.RoomUsersResp{
UserID: v.ID,
Username: v.Username,
Role: v.Role,
JoinAt: v.RoomUserRelations[0].CreatedAt.UnixMilli(),
RoomID: v.RoomUserRelations[0].RoomID,
Status: v.RoomUserRelations[0].Status,
Permissions: v.RoomUserRelations[0].Permissions,
}
}
return resp
}
func ApprovePendingUser(ctx *gin.Context) {
req := model.UserIDReq{}
if err := model.Decode(ctx, &req); err != nil {
@ -259,6 +330,62 @@ func Rooms(ctx *gin.Context) {
scopes = append(scopes, db.WhereRoomNameLike(keyword))
case "creator":
scopes = append(scopes, db.WhereCreatorIDIn(db.GerUsersIDByUsernameLike(keyword)))
case "creatorId":
scopes = append(scopes, db.WhereCreatorID(keyword))
case "id":
scopes = append(scopes, db.WhereIDLike(keyword))
}
}
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"total": db.GetAllRoomsCount(scopes...),
"list": genRoomListResp(append(scopes, db.Paginate(page, pageSize))...),
}))
}
func GetUserRooms(ctx *gin.Context) {
id := ctx.Query("id")
if len(id) != 32 {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("user id error"))
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{
db.WhereCreatorID(id),
}
switch ctx.DefaultQuery("order", "name") {
case "createdAt":
if desc {
scopes = append(scopes, db.OrderByCreatedAtDesc)
} else {
scopes = append(scopes, db.OrderByCreatedAtAsc)
}
case "name":
if desc {
scopes = append(scopes, db.OrderByDesc("name"))
} else {
scopes = append(scopes, db.OrderByAsc("name"))
}
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.WhereRoomNameLikeOrIDLike(keyword, keyword))
case "name":
scopes = append(scopes, db.WhereRoomNameLike(keyword))
case "id":
scopes = append(scopes, db.WhereIDLike(keyword))
}

@ -34,21 +34,36 @@ func Init(e *gin.Engine) {
admin.POST("/settings", EditAdminSettings)
admin.GET("/users", Users)
{
user := admin.Group("/user")
admin.GET("/rooms", Rooms)
// 查找用户
user.GET("/list", Users)
admin.POST("/approve/user", ApprovePendingUser)
user.POST("/approve", ApprovePendingUser)
admin.POST("/approve/room", ApprovePendingRoom)
user.POST("/ban", BanUser)
admin.POST("/ban/user", BanUser)
user.POST("/unban", UnBanUser)
admin.POST("/ban/room", BanRoom)
// 查找某个用户的房间
user.GET("/rooms", GetUserRooms)
}
admin.POST("/unban/user", UnBanUser)
{
room := admin.Group("/room")
admin.POST("/unban/room", UnBanRoom)
// 查找房间
room.GET("/list", Rooms)
room.POST("/room", ApprovePendingRoom)
room.POST("/ban", BanRoom)
room.POST("/unban", UnBanRoom)
room.GET("/users", GetRoomUsers)
}
}
{
@ -83,7 +98,7 @@ func Init(e *gin.Engine) {
needAuthRoom.POST("/settings", SetRoomSetting)
// needAuthRoom.GET("/users", RoomUsers)
needAuthRoom.GET("/users", RoomUsers)
}
{

@ -264,63 +264,61 @@ func SetRoomSetting(ctx *gin.Context) {
ctx.Status(http.StatusNoContent)
}
// func RoomUsers(ctx *gin.Context) {
// room := ctx.MustGet("room").(*op.Room)
// 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{}
// roomUserRelationScopes := []func(db *gorm.DB) *gorm.DB{}
// switch ctx.DefaultQuery("status", "active") {
// case "pending":
// roomUserRelationScopes = append(roomUserRelationScopes, db.WhereRoomUserStatus(dbModel.RoomUserStatusPending))
// case "banned":
// roomUserRelationScopes = append(roomUserRelationScopes, db.WhereRoomUserStatus(dbModel.RoomUserStatusBanned))
// case "active":
// roomUserRelationScopes = append(roomUserRelationScopes, db.WhereRoomUserStatus(dbModel.RoomUserStatusActive))
// default:
// ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("not support role"))
// return
// }
// switch ctx.DefaultQuery("order", "name") {
// case "join":
// if desc {
// roomUserRelationScopes = append(roomUserRelationScopes, db.OrderByCreatedAtDesc)
// } else {
// roomUserRelationScopes = append(roomUserRelationScopes, db.OrderByCreatedAtAsc)
// }
// case "name":
// if desc {
// scopes = append(scopes, db.OrderByDesc("username"))
// } else {
// scopes = append(scopes, db.OrderByAsc("username"))
// }
// default:
// ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("not support order"))
// 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.GetAllRoomUsersCount(room.ID, roomUserRelationScopes, scopes...),
// "list": genUserListResp(db.GetAllRoomUsers(room.ID, roomUserRelationScopes, append(scopes, db.Paginate(page, pageSize))...)),
// }))
// }
func RoomUsers(ctx *gin.Context) {
room := ctx.MustGet("room").(*op.Room)
page, pageSize, err := GetPageAndPageSize(ctx)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
return
}
var desc = ctx.DefaultQuery("sort", "desc") == "desc"
preloadScopes := []func(db *gorm.DB) *gorm.DB{db.WhereRoomID(room.ID)}
scopes := []func(db *gorm.DB) *gorm.DB{}
switch ctx.DefaultQuery("status", "active") {
case "pending":
preloadScopes = append(preloadScopes, db.WhereRoomUserStatus(dbModel.RoomUserStatusPending))
case "banned":
preloadScopes = append(preloadScopes, db.WhereRoomUserStatus(dbModel.RoomUserStatusBanned))
case "active":
preloadScopes = append(preloadScopes, db.WhereRoomUserStatus(dbModel.RoomUserStatusActive))
}
switch ctx.DefaultQuery("order", "name") {
case "join":
if desc {
preloadScopes = append(preloadScopes, db.OrderByCreatedAtDesc)
} else {
preloadScopes = append(preloadScopes, db.OrderByCreatedAtAsc)
}
case "name":
if desc {
scopes = append(scopes, db.OrderByDesc("username"))
} else {
scopes = append(scopes, db.OrderByAsc("username"))
}
default:
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("not support order"))
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)))
}
}
scopes = append(scopes, db.PreloadRoomUserRelation(preloadScopes...))
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"total": db.GetAllUserCount(scopes...),
"list": genRoomUserListResp(db.GetAllUsers(append(scopes, db.Paginate(page, pageSize))...)),
}))
}

@ -131,3 +131,13 @@ func (s *SetRoomSettingReq) Decode(ctx *gin.Context) error {
func (s *SetRoomSettingReq) Validate() error {
return nil
}
type RoomUsersResp struct {
UserID string `json:"userId"`
Username string `json:"username"`
Role dbModel.Role `json:"role"`
JoinAt int64 `json:"joinAt"`
RoomID string `json:"roomId"`
Status dbModel.RoomUserStatus `json:"status"`
Permissions dbModel.RoomUserPermission `json:"permissions"`
}

@ -91,11 +91,3 @@ func (u *UserIDReq) Validate() error {
}
return nil
}
type RoomUserInfoResp struct {
ID string `json:"id"`
Username string `json:"username"`
JoinedAt int64 `json:"joinedAt"`
Status string `json:"status"`
Permission dbModel.RoomUserPermission `json:"permission"`
}

Loading…
Cancel
Save