package services import ( "context" "mime/multipart" "quyun/v2/app/errorx" common_dto "quyun/v2/app/http/v1/dto" "quyun/v2/database/fields" "quyun/v2/database/models" "quyun/v2/pkg/consts" "github.com/google/uuid" "github.com/spf13/cast" "go.ipao.vip/gen/types" ) // @provider type common struct{} func (s *common) Upload(ctx context.Context, file *multipart.FileHeader, typeArg string) (*common_dto.UploadResult, error) { userID := ctx.Value(consts.CtxKeyUser) if userID == nil { return nil, errorx.ErrUnauthorized } uid := cast.ToInt64(userID) // Mock Upload to S3/MinIO // objectKey := uuid.NewString() + filepath.Ext(file.Filename) objectKey := uuid.NewString() + "_" + file.Filename url := "http://mock-storage/" + objectKey // Determine TenantID. // Uploads usually happen in context of a tenant? Or personal? // For now assume user's owned tenant if any, or 0. // MediaAsset has TenantID (NOT NULL). // We need to fetch tenant. t, err := models.TenantQuery.WithContext(ctx).Where(models.TenantQuery.UserID.Eq(uid)).First() var tid int64 = 0 if err == nil { tid = t.ID } // If no tenant, and TenantID is NOT NULL, we have a problem for regular users uploading avatar? // Users avatar is URL string in `users` table. // MediaAssets table is for TENANT content. // If this is for user avatar upload, maybe we don't use MediaAssets? // But `upload` endpoint is generic. // Let's assume tid=0 is allowed if system bucket, or enforce tenant. // If table says NOT NULL, 0 is valid int64. asset := &models.MediaAsset{ TenantID: tid, UserID: uid, Type: consts.MediaAssetType(typeArg), Status: consts.MediaAssetStatusUploaded, Provider: "mock", Bucket: "default", ObjectKey: objectKey, Meta: types.NewJSONType(fields.MediaAssetMeta{ Size: file.Size, // MimeType? }), } if err := models.MediaAssetQuery.WithContext(ctx).Create(asset); err != nil { return nil, errorx.ErrDatabaseError.WithCause(err) } return &common_dto.UploadResult{ ID: cast.ToString(asset.ID), URL: url, Filename: file.Filename, Size: file.Size, MimeType: file.Header.Get("Content-Type"), }, nil } func (s *common) GetAssetURL(objectKey string) string { // In future: Implement real S3 presigned URL generation here if objectKey == "" { return "" } return "http://mock-storage/" + objectKey }