feat: Introduce MediaAssetVariant for better asset management
- Added MediaAssetVariant enum with values 'main' and 'preview'. - Updated media asset service logic to utilize MediaAssetVariant for variant handling. - Refactored database models and queries to include variant and source_asset_id fields. - Enhanced validation for asset variants in upload and processing functions. - Updated Swagger documentation to reflect new variant structure and descriptions. - Implemented necessary database migrations to support the new variant constraints.
This commit is contained in:
@@ -19,18 +19,20 @@ const TableNameMediaAsset = "media_assets"
|
||||
|
||||
// MediaAsset mapped from table <media_assets>
|
||||
type MediaAsset struct {
|
||||
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true;comment:主键ID:自增;仅用于内部关联" json:"id"` // 主键ID:自增;仅用于内部关联
|
||||
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null;comment:租户ID:多租户隔离关键字段;所有查询/写入必须限定 tenant_id" json:"tenant_id"` // 租户ID:多租户隔离关键字段;所有查询/写入必须限定 tenant_id
|
||||
UserID int64 `gorm:"column:user_id;type:bigint;not null;comment:用户ID:资源上传者;用于审计与权限控制" json:"user_id"` // 用户ID:资源上传者;用于审计与权限控制
|
||||
Type consts.MediaAssetType `gorm:"column:type;type:character varying(32);not null;default:video;comment:资源类型:video/audio/image;决定后续处理流程(转码/缩略图/封面等)" json:"type"` // 资源类型:video/audio/image;决定后续处理流程(转码/缩略图/封面等)
|
||||
Status consts.MediaAssetStatus `gorm:"column:status;type:character varying(32);not null;default:uploaded;comment:处理状态:uploaded/processing/ready/failed/deleted;ready 才可被内容引用对外提供" json:"status"` // 处理状态:uploaded/processing/ready/failed/deleted;ready 才可被内容引用对外提供
|
||||
Provider string `gorm:"column:provider;type:character varying(64);not null;comment:存储提供方:例如 s3/minio/oss;便于多存储扩展" json:"provider"` // 存储提供方:例如 s3/minio/oss;便于多存储扩展
|
||||
Bucket string `gorm:"column:bucket;type:character varying(128);not null;comment:存储桶:对象所在 bucket;与 provider 组合确定存储定位" json:"bucket"` // 存储桶:对象所在 bucket;与 provider 组合确定存储定位
|
||||
ObjectKey string `gorm:"column:object_key;type:character varying(512);not null;comment:对象键:对象在 bucket 内的 key;不得暴露可长期复用的直链(通过签名URL/token下发)" json:"object_key"` // 对象键:对象在 bucket 内的 key;不得暴露可长期复用的直链(通过签名URL/token下发)
|
||||
Meta types.JSON `gorm:"column:meta;type:jsonb;not null;default:{};comment:元数据:JSON;包含 hash、duration、width、height、bitrate、codec 等;用于展示与计费/风控" json:"meta"` // 元数据:JSON;包含 hash、duration、width、height、bitrate、codec 等;用于展示与计费/风控
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp with time zone;comment:软删除时间:非空表示已删除;对外接口需过滤" json:"deleted_at"` // 软删除时间:非空表示已删除;对外接口需过滤
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now();comment:创建时间:默认 now();用于审计与排序" json:"created_at"` // 创建时间:默认 now();用于审计与排序
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now();comment:更新时间:默认 now();更新状态/元数据时写入" json:"updated_at"` // 更新时间:默认 now();更新状态/元数据时写入
|
||||
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true;comment:主键ID:自增;仅用于内部关联" json:"id"` // 主键ID:自增;仅用于内部关联
|
||||
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null;comment:租户ID:多租户隔离关键字段;所有查询/写入必须限定 tenant_id" json:"tenant_id"` // 租户ID:多租户隔离关键字段;所有查询/写入必须限定 tenant_id
|
||||
UserID int64 `gorm:"column:user_id;type:bigint;not null;comment:用户ID:资源上传者;用于审计与权限控制" json:"user_id"` // 用户ID:资源上传者;用于审计与权限控制
|
||||
Type consts.MediaAssetType `gorm:"column:type;type:character varying(32);not null;default:video;comment:资源类型:video/audio/image;决定后续处理流程(转码/缩略图/封面等)" json:"type"` // 资源类型:video/audio/image;决定后续处理流程(转码/缩略图/封面等)
|
||||
Status consts.MediaAssetStatus `gorm:"column:status;type:character varying(32);not null;default:uploaded;comment:处理状态:uploaded/processing/ready/failed/deleted;ready 才可被内容引用对外提供" json:"status"` // 处理状态:uploaded/processing/ready/failed/deleted;ready 才可被内容引用对外提供
|
||||
Provider string `gorm:"column:provider;type:character varying(64);not null;comment:存储提供方:例如 s3/minio/oss;便于多存储扩展" json:"provider"` // 存储提供方:例如 s3/minio/oss;便于多存储扩展
|
||||
Bucket string `gorm:"column:bucket;type:character varying(128);not null;comment:存储桶:对象所在 bucket;与 provider 组合确定存储定位" json:"bucket"` // 存储桶:对象所在 bucket;与 provider 组合确定存储定位
|
||||
ObjectKey string `gorm:"column:object_key;type:character varying(512);not null;comment:对象键:对象在 bucket 内的 key;不得暴露可长期复用的直链(通过签名URL/token下发)" json:"object_key"` // 对象键:对象在 bucket 内的 key;不得暴露可长期复用的直链(通过签名URL/token下发)
|
||||
Meta types.JSON `gorm:"column:meta;type:jsonb;not null;default:{};comment:元数据:JSON;包含 hash、duration、width、height、bitrate、codec 等;用于展示与计费/风控" json:"meta"` // 元数据:JSON;包含 hash、duration、width、height、bitrate、codec 等;用于展示与计费/风控
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp with time zone;comment:软删除时间:非空表示已删除;对外接口需过滤" json:"deleted_at"` // 软删除时间:非空表示已删除;对外接口需过滤
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now();comment:创建时间:默认 now();用于审计与排序" json:"created_at"` // 创建时间:默认 now();用于审计与排序
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now();comment:更新时间:默认 now();更新状态/元数据时写入" json:"updated_at"` // 更新时间:默认 now();更新状态/元数据时写入
|
||||
Variant consts.MediaAssetVariant `gorm:"column:variant;type:character varying(32);not null;default:main;comment:产物类型:main/preview;用于强制试看资源必须绑定独立产物,避免用正片绕过" json:"variant"` // 产物类型:main/preview;用于强制试看资源必须绑定独立产物,避免用正片绕过
|
||||
SourceAssetID int64 `gorm:"column:source_asset_id;type:bigint;comment:派生来源资源ID:preview 产物可指向对应 main 资源;用于建立 preview/main 的 1:1 追溯关系" json:"source_asset_id"` // 派生来源资源ID:preview 产物可指向对应 main 资源;用于建立 preview/main 的 1:1 追溯关系
|
||||
}
|
||||
|
||||
// Quick operations without importing query package
|
||||
|
||||
@@ -37,6 +37,8 @@ func newMediaAsset(db *gorm.DB, opts ...gen.DOOption) mediaAssetQuery {
|
||||
_mediaAssetQuery.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||
_mediaAssetQuery.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_mediaAssetQuery.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||
_mediaAssetQuery.Variant = field.NewField(tableName, "variant")
|
||||
_mediaAssetQuery.SourceAssetID = field.NewInt64(tableName, "source_asset_id")
|
||||
|
||||
_mediaAssetQuery.fillFieldMap()
|
||||
|
||||
@@ -46,19 +48,21 @@ func newMediaAsset(db *gorm.DB, opts ...gen.DOOption) mediaAssetQuery {
|
||||
type mediaAssetQuery struct {
|
||||
mediaAssetQueryDo mediaAssetQueryDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // 主键ID:自增;仅用于内部关联
|
||||
TenantID field.Int64 // 租户ID:多租户隔离关键字段;所有查询/写入必须限定 tenant_id
|
||||
UserID field.Int64 // 用户ID:资源上传者;用于审计与权限控制
|
||||
Type field.Field // 资源类型:video/audio/image;决定后续处理流程(转码/缩略图/封面等)
|
||||
Status field.Field // 处理状态:uploaded/processing/ready/failed/deleted;ready 才可被内容引用对外提供
|
||||
Provider field.String // 存储提供方:例如 s3/minio/oss;便于多存储扩展
|
||||
Bucket field.String // 存储桶:对象所在 bucket;与 provider 组合确定存储定位
|
||||
ObjectKey field.String // 对象键:对象在 bucket 内的 key;不得暴露可长期复用的直链(通过签名URL/token下发)
|
||||
Meta field.JSONB // 元数据:JSON;包含 hash、duration、width、height、bitrate、codec 等;用于展示与计费/风控
|
||||
DeletedAt field.Field // 软删除时间:非空表示已删除;对外接口需过滤
|
||||
CreatedAt field.Time // 创建时间:默认 now();用于审计与排序
|
||||
UpdatedAt field.Time // 更新时间:默认 now();更新状态/元数据时写入
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // 主键ID:自增;仅用于内部关联
|
||||
TenantID field.Int64 // 租户ID:多租户隔离关键字段;所有查询/写入必须限定 tenant_id
|
||||
UserID field.Int64 // 用户ID:资源上传者;用于审计与权限控制
|
||||
Type field.Field // 资源类型:video/audio/image;决定后续处理流程(转码/缩略图/封面等)
|
||||
Status field.Field // 处理状态:uploaded/processing/ready/failed/deleted;ready 才可被内容引用对外提供
|
||||
Provider field.String // 存储提供方:例如 s3/minio/oss;便于多存储扩展
|
||||
Bucket field.String // 存储桶:对象所在 bucket;与 provider 组合确定存储定位
|
||||
ObjectKey field.String // 对象键:对象在 bucket 内的 key;不得暴露可长期复用的直链(通过签名URL/token下发)
|
||||
Meta field.JSONB // 元数据:JSON;包含 hash、duration、width、height、bitrate、codec 等;用于展示与计费/风控
|
||||
DeletedAt field.Field // 软删除时间:非空表示已删除;对外接口需过滤
|
||||
CreatedAt field.Time // 创建时间:默认 now();用于审计与排序
|
||||
UpdatedAt field.Time // 更新时间:默认 now();更新状态/元数据时写入
|
||||
Variant field.Field // 产物类型:main/preview;用于强制试看资源必须绑定独立产物,避免用正片绕过
|
||||
SourceAssetID field.Int64 // 派生来源资源ID:preview 产物可指向对应 main 资源;用于建立 preview/main 的 1:1 追溯关系
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
@@ -87,6 +91,8 @@ func (m *mediaAssetQuery) updateTableName(table string) *mediaAssetQuery {
|
||||
m.DeletedAt = field.NewField(table, "deleted_at")
|
||||
m.CreatedAt = field.NewTime(table, "created_at")
|
||||
m.UpdatedAt = field.NewTime(table, "updated_at")
|
||||
m.Variant = field.NewField(table, "variant")
|
||||
m.SourceAssetID = field.NewInt64(table, "source_asset_id")
|
||||
|
||||
m.fillFieldMap()
|
||||
|
||||
@@ -119,7 +125,7 @@ func (m *mediaAssetQuery) GetFieldByName(fieldName string) (field.OrderExpr, boo
|
||||
}
|
||||
|
||||
func (m *mediaAssetQuery) fillFieldMap() {
|
||||
m.fieldMap = make(map[string]field.Expr, 12)
|
||||
m.fieldMap = make(map[string]field.Expr, 14)
|
||||
m.fieldMap["id"] = m.ID
|
||||
m.fieldMap["tenant_id"] = m.TenantID
|
||||
m.fieldMap["user_id"] = m.UserID
|
||||
@@ -132,6 +138,8 @@ func (m *mediaAssetQuery) fillFieldMap() {
|
||||
m.fieldMap["deleted_at"] = m.DeletedAt
|
||||
m.fieldMap["created_at"] = m.CreatedAt
|
||||
m.fieldMap["updated_at"] = m.UpdatedAt
|
||||
m.fieldMap["variant"] = m.Variant
|
||||
m.fieldMap["source_asset_id"] = m.SourceAssetID
|
||||
}
|
||||
|
||||
func (m mediaAssetQuery) clone(db *gorm.DB) mediaAssetQuery {
|
||||
|
||||
Reference in New Issue
Block a user