Files
backend/internal/service/sticker_service.go
lan 4d8f2ec997 Initial backend repository commit.
Set up project files and add .gitignore to exclude local build/runtime artifacts.

Made-with: Cursor
2026-03-09 21:28:58 +08:00

140 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
}