feat: 添加媒体资产变体和来源ID字段,支持预览产品与主资产的关联
This commit is contained in:
@@ -34,6 +34,16 @@ type ContentDetailResult struct {
|
||||
HasAccess bool
|
||||
}
|
||||
|
||||
func requiredMediaAssetVariantForRole(role consts.ContentAssetRole) string {
|
||||
switch role {
|
||||
case consts.ContentAssetRolePreview:
|
||||
return mediaAssetVariantPreview
|
||||
default:
|
||||
// main/cover 一律要求 main 产物,避免误把 preview 绑定成正片/封面。
|
||||
return mediaAssetVariantMain
|
||||
}
|
||||
}
|
||||
|
||||
func (s *content) Create(ctx context.Context, tenantID, userID int64, form *dto.ContentCreateForm) (*models.Content, error) {
|
||||
log.WithFields(log.Fields{
|
||||
"tenant_id": tenantID,
|
||||
@@ -215,6 +225,60 @@ func (s *content) AttachAsset(ctx context.Context, tenantID, userID, contentID,
|
||||
return nil, errorx.ErrPreconditionFailed.WithMsg("media asset not ready")
|
||||
}
|
||||
|
||||
// C2 规则:preview 必须绑定独立产物(media_assets.variant=preview),main/cover 必须为 main。
|
||||
var assetRow struct {
|
||||
Variant string `gorm:"column:variant"`
|
||||
SourceAssetID *int64 `gorm:"column:source_asset_id"`
|
||||
}
|
||||
if err := _db.WithContext(ctx).
|
||||
Table(models.TableNameMediaAsset).
|
||||
Select("variant, source_asset_id").
|
||||
Where("tenant_id = ? AND id = ? AND deleted_at IS NULL", tenantID, assetID).
|
||||
Take(&assetRow).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errorx.ErrRecordNotFound.WithMsg("media asset not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
variant := assetRow.Variant
|
||||
if variant == "" {
|
||||
variant = mediaAssetVariantMain
|
||||
}
|
||||
requiredVariant := requiredMediaAssetVariantForRole(role)
|
||||
if variant != requiredVariant {
|
||||
return nil, errorx.ErrPreconditionFailed.WithMsg("media asset variant mismatch")
|
||||
}
|
||||
// 关联规则:preview 产物必须声明来源 main;main/cover 不允许带来源。
|
||||
if role == consts.ContentAssetRolePreview {
|
||||
if assetRow.SourceAssetID == nil || *assetRow.SourceAssetID <= 0 {
|
||||
return nil, errorx.ErrPreconditionFailed.WithMsg("preview asset must have source_asset_id")
|
||||
}
|
||||
var srcRow struct {
|
||||
Variant string `gorm:"column:variant"`
|
||||
}
|
||||
if err := _db.WithContext(ctx).
|
||||
Table(models.TableNameMediaAsset).
|
||||
Select("variant").
|
||||
Where("tenant_id = ? AND id = ? AND deleted_at IS NULL", tenantID, *assetRow.SourceAssetID).
|
||||
Take(&srcRow).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errorx.ErrRecordNotFound.WithMsg("preview source asset not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
srcVariant := srcRow.Variant
|
||||
if srcVariant == "" {
|
||||
srcVariant = mediaAssetVariantMain
|
||||
}
|
||||
if srcVariant != mediaAssetVariantMain {
|
||||
return nil, errorx.ErrPreconditionFailed.WithMsg("preview source asset must be main variant")
|
||||
}
|
||||
} else {
|
||||
if assetRow.SourceAssetID != nil && *assetRow.SourceAssetID > 0 {
|
||||
return nil, errorx.ErrPreconditionFailed.WithMsg("main/cover asset must not have source_asset_id")
|
||||
}
|
||||
}
|
||||
|
||||
m := &models.ContentAsset{
|
||||
TenantID: tenantID,
|
||||
UserID: userID,
|
||||
|
||||
Reference in New Issue
Block a user