Files
MeBox/internal/service/strm_svc.go
T

172 lines
4.2 KiB
Go

// Package service — STRM 文件管理服务。
package service
import (
"context"
"errors"
"strings"
"go.uber.org/zap"
"github.com/ShukeBta/MediaStationGo/internal/config"
"github.com/ShukeBta/MediaStationGo/internal/model"
"github.com/ShukeBta/MediaStationGo/internal/repository"
)
// STRM 错误定义。
var (
ErrSTRMNotFound = errors.New("strm record not found")
ErrSTRMProtocolInvalid = errors.New("invalid strm protocol")
ErrSTRMURLInvalid = errors.New("invalid strm url")
)
// STRMService STRM 文件管理服务。
type STRMService struct {
log *zap.Logger
repo *repository.Container
cfg *config.Config
}
// NewSTRMService 创建 STRM 服务。
func NewSTRMService(log *zap.Logger, repo *repository.Container, cfg *config.Config) *STRMService {
return &STRMService{log: log, repo: repo, cfg: cfg}
}
// Create 创建 STRM 记录。
func (s *STRMService) Create(ctx context.Context, record *model.STRMRecord) (*model.STRMRecord, error) {
if err := s.validateSTRM(record); err != nil {
return nil, err
}
if err := s.repo.STRM.Create(ctx, record); err != nil {
s.log.Error("create strm failed", zap.Error(err))
return nil, err
}
return record, nil
}
// CreateBatch 批量创建 STRM 记录。
func (s *STRMService) CreateBatch(ctx context.Context, records []model.STRMRecord) (int, error) {
created := 0
for i := range records {
if err := s.validateSTRM(&records[i]); err != nil {
s.log.Warn("skip invalid strm record",
zap.String("title", records[i].Title),
zap.Error(err),
)
continue
}
created++
}
validRecords := make([]model.STRMRecord, 0, created)
for _, r := range records {
if model.IsAllowedProtocol(r.Protocol) && r.URL != "" {
validRecords = append(validRecords, r)
}
}
if len(validRecords) == 0 {
return 0, nil
}
if err := s.repo.STRM.CreateBatch(ctx, validRecords); err != nil {
s.log.Error("batch create strm failed", zap.Error(err))
return 0, err
}
return len(validRecords), nil
}
// GetByID 获取 STRM 记录。
func (s *STRMService) GetByID(ctx context.Context, id string) (*model.STRMRecord, error) {
record, err := s.repo.STRM.FindByID(ctx, id)
if err != nil {
return nil, err
}
if record == nil {
return nil, ErrSTRMNotFound
}
return record, nil
}
// List 列出 STRM 记录(支持筛选和分页)。
func (s *STRMService) List(ctx context.Context, filters map[string]string, page, pageSize int) ([]model.STRMRecord, int64, error) {
offset := (page - 1) * pageSize
if offset < 0 {
offset = 0
}
records, total, err := s.repo.STRM.List(ctx, filters, offset, pageSize)
if err != nil {
return nil, 0, err
}
return records, total, nil
}
// Update 更新 STRM 记录。
func (s *STRMService) Update(ctx context.Context, record *model.STRMRecord) (*model.STRMRecord, error) {
existing, err := s.repo.STRM.FindByID(ctx, record.ID)
if err != nil {
return nil, err
}
if existing == nil {
return nil, ErrSTRMNotFound
}
if record.Protocol != "" {
if !model.IsAllowedProtocol(record.Protocol) {
return nil, ErrSTRMProtocolInvalid
}
}
if err := s.repo.STRM.Update(ctx, record); err != nil {
s.log.Error("update strm failed", zap.Error(err))
return nil, err
}
return record, nil
}
// Delete 删除 STRM 记录。
func (s *STRMService) Delete(ctx context.Context, id string) error {
existing, err := s.repo.STRM.FindByID(ctx, id)
if err != nil {
return err
}
if existing == nil {
return ErrSTRMNotFound
}
return s.repo.STRM.Delete(ctx, id)
}
// GetProtocols 获取支持的协议列表。
func (s *STRMService) GetProtocols() []string {
return model.AllowedSTRMProtocols
}
// validateSTRM 验证 STRM 记录。
func (s *STRMService) validateSTRM(record *model.STRMRecord) error {
if record.Title == "" {
return errors.New("title is required")
}
if record.URL == "" {
return ErrSTRMURLInvalid
}
if !model.IsAllowedProtocol(record.Protocol) {
return ErrSTRMProtocolInvalid
}
// 标准化协议名
record.Protocol = strings.ToLower(record.Protocol)
return nil
}
// ListByMediaID 获取关联到指定媒体的 STRM 记录。
func (s *STRMService) ListByMediaID(ctx context.Context, mediaID string) ([]model.STRMRecord, error) {
return s.repo.STRM.FindByMediaID(ctx, mediaID)
}