初始化
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
// 创作媒体服务,封装媒体上传前的所有权检查、关联更新和旧媒体清理事务。
|
||||
package service
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"juhe-factory/api/internal/model"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// MediaUploadTarget 汇总上传前需要的业务对象及待替换媒体信息。
|
||||
type MediaUploadTarget struct {
|
||||
Project *model.CreativeProject
|
||||
Episode *model.ProjectEpisode
|
||||
Asset *model.ProjectAsset
|
||||
OldMediaID *uuid.UUID
|
||||
OldObjectKey string
|
||||
}
|
||||
|
||||
// MediaObject 查询当前用户有权播放或下载的媒体对象键。
|
||||
func (s *Creative) MediaObject(userID, mediaID uuid.UUID) (string, error) {
|
||||
var objectKey string
|
||||
err := s.DB.Table("media_assets").
|
||||
Where("id=? AND owner_user_id=? AND deleted_at IS NULL", mediaID, userID).
|
||||
Pluck("object_key", &objectKey).Error
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if strings.TrimSpace(objectKey) == "" {
|
||||
return "", gorm.ErrRecordNotFound
|
||||
}
|
||||
return objectKey, nil
|
||||
}
|
||||
|
||||
// PrepareRedrawMediaUpload 校验重绘项目所有权,并返回指定媒体类型的替换信息。
|
||||
func (s *Creative) PrepareRedrawMediaUpload(userID, projectID uuid.UUID, kind string) (MediaUploadTarget, error) {
|
||||
var project model.CreativeProject
|
||||
if err := s.DB.Where("id=? AND user_id=? AND project_type='video_redraw' AND deleted_at IS NULL", projectID, userID).Take(&project).Error; err != nil {
|
||||
return MediaUploadTarget{}, err
|
||||
}
|
||||
oldMediaID := project.SourceVideoAssetID
|
||||
if kind == "subtitle" {
|
||||
oldMediaID = project.SubtitleAssetID
|
||||
}
|
||||
oldObjectKey, err := s.mediaObjectKey(oldMediaID)
|
||||
if err != nil {
|
||||
return MediaUploadTarget{}, err
|
||||
}
|
||||
return MediaUploadTarget{Project: &project, OldMediaID: oldMediaID, OldObjectKey: oldObjectKey}, nil
|
||||
}
|
||||
|
||||
// PersistRedrawMediaUpload 在事务中保存新媒体、更新项目关联并删除旧媒体记录。
|
||||
func (s *Creative) PersistRedrawMediaUpload(projectID uuid.UUID, kind, currentStatus string, media *model.MediaAsset, oldMediaID *uuid.UUID) error {
|
||||
column, status := "source_video_asset_id", "uploaded"
|
||||
if kind == "subtitle" {
|
||||
column, status = "subtitle_asset_id", currentStatus
|
||||
}
|
||||
return s.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Create(media).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
updates := map[string]any{column: media.ID, "redraw_status": status}
|
||||
if err := tx.Table("creative_projects").Where("id=?", projectID).Updates(updates).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return deleteReplacedMedia(tx, oldMediaID)
|
||||
})
|
||||
}
|
||||
|
||||
// PrepareEpisodeMediaUpload 校验剧集与项目所有权,并返回指定媒体类型的替换信息。
|
||||
func (s *Creative) PrepareEpisodeMediaUpload(userID, projectID, episodeID uuid.UUID, kind string) (MediaUploadTarget, error) {
|
||||
var episode model.ProjectEpisode
|
||||
err := s.DB.Table("project_episodes e").Joins("JOIN creative_projects p ON p.id=e.project_id").
|
||||
Where("e.id=? AND e.project_id=? AND e.deleted_at IS NULL AND p.user_id=? AND p.deleted_at IS NULL", episodeID, projectID, userID).
|
||||
Select("e.*").First(&episode).Error
|
||||
if err != nil {
|
||||
return MediaUploadTarget{}, err
|
||||
}
|
||||
oldMediaID := episode.SourceVideoAssetID
|
||||
if kind == "subtitle" {
|
||||
oldMediaID = episode.SubtitleAssetID
|
||||
}
|
||||
oldObjectKey, err := s.mediaObjectKey(oldMediaID)
|
||||
if err != nil {
|
||||
return MediaUploadTarget{}, err
|
||||
}
|
||||
return MediaUploadTarget{Episode: &episode, OldMediaID: oldMediaID, OldObjectKey: oldObjectKey}, nil
|
||||
}
|
||||
|
||||
// PersistEpisodeMediaUpload 在事务中保存新媒体、更新剧集关联并删除旧媒体记录。
|
||||
func (s *Creative) PersistEpisodeMediaUpload(episodeID uuid.UUID, kind string, status string, media *model.MediaAsset, oldMediaID *uuid.UUID) error {
|
||||
column := "source_video_asset_id"
|
||||
if kind == "subtitle" {
|
||||
column = "subtitle_asset_id"
|
||||
}
|
||||
return s.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Create(media).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Table("project_episodes").Where("id=?", episodeID).Updates(map[string]any{column: media.ID, "status": status}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return deleteReplacedMedia(tx, oldMediaID)
|
||||
})
|
||||
}
|
||||
|
||||
// PrepareAssetMediaUpload 校验普通创作项目中的资产所有权并返回资产信息。
|
||||
func (s *Creative) PrepareAssetMediaUpload(userID, projectID, assetID uuid.UUID) (MediaUploadTarget, error) {
|
||||
var asset model.ProjectAsset
|
||||
err := s.DB.Table("project_assets a").Joins("JOIN creative_projects p ON p.id=a.project_id").
|
||||
Where("a.id=? AND a.project_id=? AND a.deleted_at IS NULL AND p.user_id=? AND p.project_type<>'video_redraw' AND p.deleted_at IS NULL", assetID, projectID, userID).
|
||||
Select("a.*").First(&asset).Error
|
||||
if err != nil {
|
||||
return MediaUploadTarget{}, err
|
||||
}
|
||||
return MediaUploadTarget{Asset: &asset}, nil
|
||||
}
|
||||
|
||||
// AttachUploadedAssetAudio 在事务中保存上传音频并更新资产关联。
|
||||
func (s *Creative) AttachUploadedAssetAudio(assetID uuid.UUID, media *model.MediaAsset) error {
|
||||
return s.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Create(media).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Table("project_assets").Where("id=?", assetID).Update("audio_asset_id", media.ID).Error
|
||||
})
|
||||
}
|
||||
|
||||
// mediaObjectKey 查询待替换媒体的对象键;空媒体标识表示无需清理。
|
||||
func (s *Creative) mediaObjectKey(mediaID *uuid.UUID) (string, error) {
|
||||
if mediaID == nil {
|
||||
return "", nil
|
||||
}
|
||||
var objectKey string
|
||||
if err := s.DB.Table("media_assets").Where("id=?", *mediaID).Pluck("object_key", &objectKey).Error; err != nil {
|
||||
return "", err
|
||||
}
|
||||
return objectKey, nil
|
||||
}
|
||||
|
||||
// deleteReplacedMedia 删除旧媒体的渠道缓存和媒体记录,供上传事务复用。
|
||||
func deleteReplacedMedia(tx *gorm.DB, mediaID *uuid.UUID) error {
|
||||
if mediaID == nil {
|
||||
return nil
|
||||
}
|
||||
if err := tx.Exec("DELETE FROM channel_asset_cache WHERE media_asset_id=?", *mediaID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Exec("DELETE FROM media_assets WHERE id=?", *mediaID).Error
|
||||
}
|
||||
Reference in New Issue
Block a user