2026-05-25 15:45:57 +08:00

134 lines
4.8 KiB
Go

package service
import (
"context"
"strings"
roomv1 "hyapp.local/api/proto/room/v1"
"hyapp/pkg/appcode"
"hyapp/pkg/xerr"
)
var adminSeatCandidates = []int32{10, 15, 20, 25, 30}
func (s *Service) AdminGetRoomSeatConfig(ctx context.Context, _ *roomv1.AdminGetRoomSeatConfigRequest) (*roomv1.AdminGetRoomSeatConfigResponse, error) {
config, err := s.currentRoomSeatConfig(ctx)
if err != nil {
return nil, err
}
return &roomv1.AdminGetRoomSeatConfigResponse{Config: seatConfigToAdminProto(config), ServerTimeMs: s.clock.Now().UnixMilli()}, nil
}
func (s *Service) AdminUpdateRoomSeatConfig(ctx context.Context, req *roomv1.AdminUpdateRoomSeatConfigRequest) (*roomv1.AdminUpdateRoomSeatConfigResponse, error) {
if req == nil {
return nil, xerr.New(xerr.InvalidArgument, "room seat config is required")
}
config, err := normalizeRoomSeatConfig(RoomSeatConfig{
AppCode: appcode.FromContext(ctx),
AllowedSeatCounts: req.GetAllowedSeatCounts(),
DefaultSeatCount: req.GetDefaultSeatCount(),
UpdatedAtMS: s.clock.Now().UTC().UnixMilli(),
})
if err != nil {
return nil, xerr.New(xerr.InvalidArgument, err.Error())
}
if err := s.repository.UpsertRoomSeatConfig(ctx, config); err != nil {
return nil, err
}
return &roomv1.AdminUpdateRoomSeatConfigResponse{Config: seatConfigToAdminProto(config), ServerTimeMs: config.UpdatedAtMS}, nil
}
func (s *Service) AdminListRoomPins(ctx context.Context, req *roomv1.AdminListRoomPinsRequest) (*roomv1.AdminListRoomPinsResponse, error) {
nowMS := s.clock.Now().UTC().UnixMilli()
pins, total, err := s.repository.AdminListRoomPins(ctx, AdminRoomPinQuery{
Page: int(req.GetPage()),
PageSize: int(req.GetPageSize()),
Keyword: strings.TrimSpace(req.GetKeyword()),
Status: strings.TrimSpace(req.GetStatus()),
RegionID: req.GetVisibleRegionId(),
NowMS: nowMS,
})
if err != nil {
return nil, err
}
out := make([]*roomv1.AdminRoomPin, 0, len(pins))
for _, pin := range pins {
out = append(out, roomPinToAdminProto(pin))
}
return &roomv1.AdminListRoomPinsResponse{Pins: out, Total: total, ServerTimeMs: nowMS}, nil
}
func (s *Service) AdminCreateRoomPin(ctx context.Context, req *roomv1.AdminCreateRoomPinRequest) (*roomv1.AdminCreateRoomPinResponse, error) {
if req == nil || strings.TrimSpace(req.GetRoomId()) == "" {
return nil, xerr.New(xerr.InvalidArgument, "room id is required")
}
if req.GetWeight() < 0 || req.GetDurationDays() <= 0 {
return nil, xerr.New(xerr.InvalidArgument, "room pin weight or duration is invalid")
}
nowMS := s.clock.Now().UTC().UnixMilli()
pin, ok, err := s.repository.AdminCreateRoomPin(ctx, AdminCreateRoomPinInput{
RoomID: strings.TrimSpace(req.GetRoomId()),
Weight: req.GetWeight(),
DurationDays: req.GetDurationDays(),
AdminID: req.GetAdminId(),
NowMS: nowMS,
})
if err != nil {
return nil, err
}
if !ok {
return nil, xerr.New(xerr.Conflict, "room is not active or not found")
}
return &roomv1.AdminCreateRoomPinResponse{Pin: roomPinToAdminProto(pin), ServerTimeMs: nowMS}, nil
}
func (s *Service) AdminCancelRoomPin(ctx context.Context, req *roomv1.AdminCancelRoomPinRequest) (*roomv1.AdminCancelRoomPinResponse, error) {
if req == nil || req.GetPinId() <= 0 {
return nil, xerr.New(xerr.InvalidArgument, "room pin id is invalid")
}
nowMS := s.clock.Now().UTC().UnixMilli()
pin, ok, err := s.repository.AdminCancelRoomPin(ctx, req.GetPinId(), req.GetAdminId(), nowMS)
if err != nil {
return nil, err
}
if !ok {
return nil, xerr.New(xerr.NotFound, "room pin not found")
}
return &roomv1.AdminCancelRoomPinResponse{Pin: roomPinToAdminProto(pin), ServerTimeMs: nowMS}, nil
}
func seatConfigToAdminProto(config RoomSeatConfig) *roomv1.AdminRoomSeatConfig {
return &roomv1.AdminRoomSeatConfig{
CandidateSeatCounts: append([]int32(nil), adminSeatCandidates...),
AllowedSeatCounts: append([]int32(nil), config.AllowedSeatCounts...),
DefaultSeatCount: config.DefaultSeatCount,
UpdatedAtMs: config.UpdatedAtMS,
}
}
func roomPinToAdminProto(pin AdminRoomPinEntry) *roomv1.AdminRoomPin {
return &roomv1.AdminRoomPin{
Id: pin.ID,
VisibleRegionId: pin.VisibleRegionID,
RoomId: pin.RoomID,
Weight: pin.Weight,
Status: pin.Status,
PinnedAtMs: pin.PinnedAtMS,
ExpiresAtMs: pin.ExpiresAtMS,
CancelledAtMs: pin.CancelledAtMS,
CreatedByAdminId: pin.CreatedByAdminID,
CancelledByAdminId: pin.CancelledByAdminID,
CreatedAtMs: pin.CreatedAtMS,
UpdatedAtMs: pin.UpdatedAtMS,
Room: &roomv1.AdminRoomPinRoom{
RoomId: pin.RoomID,
RoomShortId: pin.RoomShortID,
VisibleRegionId: pin.VisibleRegionID,
OwnerUserId: pin.OwnerUserID,
Title: pin.Title,
CoverUrl: pin.CoverURL,
Status: pin.RoomStatus,
},
}
}