diff --git a/cmd/server/main.go b/cmd/server/main.go index 68bb937..12e12d7 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -47,14 +47,6 @@ func main() { log.Fatal("initialize database", zap.Error(err)) } - if err := preparePublicIDColumns(gormDB); err != nil { - log.Fatal("prepare public_id columns", zap.Error(err)) - } - - if err := backfillPublicIDs(gormDB); err != nil { - log.Fatal("backfill public ids", zap.Error(err)) - } - if err := gormDB.AutoMigrate( &models.User{}, &models.Room{}, @@ -68,6 +60,14 @@ func main() { log.Fatal("auto migrate models", zap.Error(err)) } + if err := preparePublicIDColumns(gormDB); err != nil { + log.Fatal("prepare public_id columns", zap.Error(err)) + } + + if err := backfillPublicIDs(gormDB); err != nil { + log.Fatal("backfill public ids", zap.Error(err)) + } + sqlDB, err := gormDB.DB() if err != nil { log.Fatal("get sql db", zap.Error(err)) diff --git a/go.mod b/go.mod index 92abda1..eb7cfdf 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.25.0 require ( github.com/gin-gonic/gin v1.12.0 + github.com/google/uuid v1.6.0 github.com/joho/godotenv v1.5.1 github.com/oapi-codegen/runtime v1.3.1 go.uber.org/zap v1.27.1 @@ -24,7 +25,6 @@ require ( github.com/go-playground/validator/v10 v10.30.1 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/goccy/go-yaml v1.19.2 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgx/v5 v5.6.0 // indirect diff --git a/internal/repository/room_repository.go b/internal/repository/room_repository.go index 1462b78..fb7b094 100644 --- a/internal/repository/room_repository.go +++ b/internal/repository/room_repository.go @@ -236,3 +236,29 @@ func (r *RoomRepository) CountPendingJoinRequestsByUser(ctx context.Context, use } return count, nil } + +/*为了避免多次查询数据库*/ +func (r *RoomRepository) CountMembersByRoomIDs(ctx context.Context, roomIDs []uint) (map[uint]int64, error) { + var results []struct { + RoomID uint + Count int64 + } + + err := r.db.WithContext(ctx). + Model(&models.RoomMember{}). + Select("room_id, COUNT(*) as count"). + Where("room_id IN ? AND status = ?", roomIDs, "joined"). + Group("room_id"). + Scan(&results).Error + + if err != nil { + return nil, err + } + + countMap := make(map[uint]int64) + for _, r := range results { + countMap[r.RoomID] = r.Count + } + + return countMap, nil +} \ No newline at end of file diff --git a/internal/service/room_service.go b/internal/service/room_service.go index 5b59fb5..9ddc39b 100644 --- a/internal/service/room_service.go +++ b/internal/service/room_service.go @@ -7,6 +7,9 @@ import ( "github.com/QSCTech/SRTP-Backend/internal/repository" "github.com/QSCTech/SRTP-Backend/models" + + "errors" + "gorm.io/gorm" ) type RoomService struct { @@ -103,8 +106,56 @@ type UserStatsOutput struct { PendingJoinRequestCount int64 } +/*基础功能:拿数据、加工成RoomCardItem*/ func (s *RoomService) List(ctx context.Context, input ListRoomsInput) (*ListRoomsOutput, error) { - return nil, fmt.Errorf("room service List not implemented") + filter := repository.RoomFilter{ + Keyword: input.Keyword, + SportType: input.SportType, + Campus: input.Campus, + Date: input.Date, + TimeRange: input.TimeRange, + Organization: input.Organization, + Level: input.Level, + Page: int(input.Page), + PageSize: int(input.PageSize), + } + + result, err := s.repo.List(ctx, filter) + if err != nil { + return nil, err + } + + rooms := result.Items + + roomIDs := make([]uint, 0, len(rooms)) + for _, r := range rooms { + roomIDs = append(roomIDs, r.ID) + } + + countMap := make(map[uint]int64) + if len(roomIDs) > 0 { + countMap, err = s.repo.CountMembersByRoomIDs(ctx, roomIDs) + if err != nil { + return nil, err + } + } + + items := make([]RoomCardItem, 0, len(rooms)) + for _, r := range rooms { + count := countMap[r.ID] + + items = append(items, RoomCardItem{ + Room: r, + CurrentMemberCount: int32(count), + }) + } + + return &ListRoomsOutput{ + Page: int32(input.Page), + PageSize: int32(input.PageSize), + Total: result.Total, + Items: items, + }, nil } func (s *RoomService) ListMineCreated(ctx context.Context, page, pageSize int) (*ListRoomsOutput, error) { @@ -119,8 +170,24 @@ func (s *RoomService) GetMyStats(ctx context.Context) (*UserStatsOutput, error) return nil, fmt.Errorf("room service GetMyStats not implemented") } +/*基础功能:拿数据、判断*/ + func (s *RoomService) GetByID(ctx context.Context, id uint) (*models.Room, []models.RoomMember, error) { - return nil, nil, fmt.Errorf("room service GetByID not implemented") + room, err := s.repo.GetByID(ctx, id) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + var ErrRoomNotFound = errors.New("room not found") + return nil, nil, ErrRoomNotFound + } + return nil, nil, err + } + + members, err := s.repo.GetMembersByRoomID(ctx, id) + if err != nil { + return nil, nil, err + } + + return room, members, nil } func (s *RoomService) Create(ctx context.Context, input CreateRoomInput) (*models.Room, error) {