package service import ( "carrot_bbs/internal/model" "carrot_bbs/internal/repository" "errors" "net/url" "strings" ) var ( ErrStickerAlreadyExists = errors.New("sticker already exists") ErrInvalidStickerURL = errors.New("invalid sticker url") ) // StickerService 自定义表情服务接口 type StickerService interface { // 获取用户的所有表情 GetUserStickers(userID string) ([]model.UserSticker, error) // 添加表情 AddSticker(userID string, url string, width, height int) (*model.UserSticker, error) // 删除表情 DeleteSticker(userID string, stickerID string) error // 检查表情是否已存在 CheckExists(userID string, url string) (bool, error) // 重新排序 ReorderStickers(userID string, orders map[string]int) error // 获取用户表情数量 GetStickerCount(userID string) (int64, error) } // stickerService 自定义表情服务实现 type stickerService struct { stickerRepo repository.StickerRepository } // NewStickerService 创建自定义表情服务 func NewStickerService(stickerRepo repository.StickerRepository) StickerService { return &stickerService{ stickerRepo: stickerRepo, } } // GetUserStickers 获取用户的所有表情 func (s *stickerService) GetUserStickers(userID string) ([]model.UserSticker, error) { stickers, err := s.stickerRepo.GetByUserID(userID) if err != nil { return nil, err } // 兼容历史脏数据:过滤本地文件 URI,避免客户端加载 file:// 报错 filtered := make([]model.UserSticker, 0, len(stickers)) for _, sticker := range stickers { if isValidStickerURL(sticker.URL) { filtered = append(filtered, sticker) } } return filtered, nil } // AddSticker 添加表情 func (s *stickerService) AddSticker(userID string, url string, width, height int) (*model.UserSticker, error) { if !isValidStickerURL(url) { return nil, ErrInvalidStickerURL } // 检查是否已存在 exists, err := s.stickerRepo.Exists(userID, url) if err != nil { return nil, err } if exists { return nil, ErrStickerAlreadyExists } // 获取当前数量用于设置排序 count, err := s.stickerRepo.CountByUserID(userID) if err != nil { return nil, err } sticker := &model.UserSticker{ UserID: userID, URL: url, Width: width, Height: height, SortOrder: int(count), // 新表情添加到末尾 } if err := s.stickerRepo.Create(sticker); err != nil { return nil, err } return sticker, nil } func isValidStickerURL(raw string) bool { trimmed := strings.TrimSpace(raw) if trimmed == "" { return false } parsed, err := url.Parse(trimmed) if err != nil { return false } scheme := strings.ToLower(parsed.Scheme) return scheme == "http" || scheme == "https" } // DeleteSticker 删除表情 func (s *stickerService) DeleteSticker(userID string, stickerID string) error { // 先检查表情是否属于该用户 sticker, err := s.stickerRepo.GetByID(stickerID) if err != nil { return err } if sticker.UserID != userID { return errors.New("sticker not found") } return s.stickerRepo.Delete(stickerID) } // CheckExists 检查表情是否已存在 func (s *stickerService) CheckExists(userID string, url string) (bool, error) { return s.stickerRepo.Exists(userID, url) } // ReorderStickers 重新排序 func (s *stickerService) ReorderStickers(userID string, orders map[string]int) error { return s.stickerRepo.BatchUpdateSortOrder(userID, orders) } // GetStickerCount 获取用户表情数量 func (s *stickerService) GetStickerCount(userID string) (int64, error) { return s.stickerRepo.CountByUserID(userID) }