package livechat import ( "context" "strings" "time" kratoserrors "github.com/go-kratos/kratos/v3/errors" ) const ( TypeSystem = "system" TypeChat = "chat" TypeGift = "gift" ) var ( ErrInvalidMessage = kratoserrors.BadRequest("LIVE_CHAT_INVALID", "invalid chat message") ErrRoomNotFound = kratoserrors.NotFound("LIVE_CHAT_ROOM_NOT_FOUND", "live room not found") ErrUserNotFound = kratoserrors.NotFound("LIVE_CHAT_USER_NOT_FOUND", "chat user not found") ) type Message struct { ID uint RoomID uint Type string UserID uint Username string Nickname string Avatar string Content string GiftID uint GiftName string GiftIcon string Quantity int DiamondTotal int64 CreatedAt time.Time } type GiftSnapshot struct { RoomID uint UserID uint Username string Nickname string GiftID uint GiftName string GiftIcon string Quantity int DiamondTotal int64 } type Repo interface { ListRecent(context.Context, uint, int) ([]*Message, error) CreateChat(context.Context, uint, uint, string) (*Message, error) CreateGift(context.Context, *GiftSnapshot) (*Message, error) Clear(context.Context, uint) error } type Usecase struct{ repo Repo } func NewUsecase(repo Repo) *Usecase { return &Usecase{repo: repo} } func (uc *Usecase) ListRecent(ctx context.Context, roomID uint, limit int) ([]*Message, error) { if roomID == 0 { return nil, ErrRoomNotFound } if limit < 1 || limit > 100 { limit = 100 } return uc.repo.ListRecent(ctx, roomID, limit) } func (uc *Usecase) Send(ctx context.Context, roomID, userID uint, content string) (*Message, error) { content = strings.TrimSpace(content) if roomID == 0 || userID == 0 || len([]rune(content)) < 1 || len([]rune(content)) > 50 { return nil, ErrInvalidMessage } return uc.repo.CreateChat(ctx, roomID, userID, content) } func (uc *Usecase) RecordGift(ctx context.Context, gift *GiftSnapshot) (*Message, error) { if gift == nil || gift.RoomID == 0 || gift.UserID == 0 || gift.GiftID == 0 || gift.Quantity < 1 || gift.DiamondTotal < 1 { return nil, ErrInvalidMessage } return uc.repo.CreateGift(ctx, gift) } func (uc *Usecase) Clear(ctx context.Context, roomID uint) error { if roomID == 0 { return ErrRoomNotFound } return uc.repo.Clear(ctx, roomID) }