Files
quyun-v2/backend/app/services/common.go
Rogee 5cf2295f91 feat: Implement notification service and integrate with user interactions
- Added notification service to handle sending and listing notifications.
- Integrated notification sending on user follow and order payment events.
- Updated user service to include fetching followed tenants.
- Enhanced content service to manage access control for content assets.
- Implemented logic for listing content topics based on genre.
- Updated creator service to manage content updates and pricing.
- Improved order service to include detailed order information and notifications.
- Added tests for notification CRUD operations and order details.
2025-12-30 09:57:12 +08:00

85 lines
2.3 KiB
Go

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
}