140 lines
3.5 KiB
Go
140 lines
3.5 KiB
Go
|
|
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)
|
|||
|
|
}
|