Files
quyun-v2/backend/app/services/common.go
2025-12-31 17:42:51 +08:00

119 lines
3.1 KiB
Go

package services
import (
"context"
"io"
"mime/multipart"
"os"
"path/filepath"
"time"
"quyun/v2/app/errorx"
common_dto "quyun/v2/app/http/v1/dto"
"quyun/v2/app/requests"
"quyun/v2/database/fields"
"quyun/v2/database/models"
"quyun/v2/pkg/consts"
"quyun/v2/providers/storage"
"github.com/google/uuid"
"github.com/spf13/cast"
"go.ipao.vip/gen/types"
)
// @provider
type common struct {
storage *storage.Storage
}
func (s *common) Options(ctx context.Context) (*common_dto.OptionsResponse, error) {
return &common_dto.OptionsResponse{
ContentStatus: consts.ContentStatusItems(),
ContentGenre: []requests.KV{
requests.NewKV("Jingju", "京剧"),
requests.NewKV("Kunqu", "昆曲"),
requests.NewKV("Yueju", "越剧"),
requests.NewKV("Yuju", "豫剧"),
requests.NewKV("Huangmeixi", "黄梅戏"),
requests.NewKV("Pingju", "评剧"),
requests.NewKV("Qinqiang", "秦腔"),
},
}, nil
}
func (s *common) Upload(ctx context.Context, userID int64, file *multipart.FileHeader, typeArg string) (*common_dto.UploadResult, error) {
// Mock Upload to S3/MinIO (Here we just generate key, actual upload handling via direct upload or stream is better)
// But this Upload endpoint accepts file. So we save it.
objectKey := uuid.NewString() + "_" + file.Filename
// Save file content to local storage
src, err := file.Open()
if err != nil {
return nil, errorx.ErrInternalError.WithCause(err).WithMsg("failed to open uploaded file")
}
defer src.Close()
localPath := s.storage.Config.LocalPath
if localPath == "" {
localPath = "./storage" // Fallback
}
dstPath := filepath.Join(localPath, objectKey)
if err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil {
return nil, errorx.ErrInternalError.WithCause(err).WithMsg("failed to create storage directory")
}
dst, err := os.Create(dstPath)
if err != nil {
return nil, errorx.ErrInternalError.WithCause(err).WithMsg("failed to create destination file")
}
defer dst.Close()
if _, err = io.Copy(dst, src); err != nil {
return nil, errorx.ErrInternalError.WithCause(err).WithMsg("failed to save file content")
}
url := s.GetAssetURL(objectKey)
// ... rest ...
t, err := models.TenantQuery.WithContext(ctx).Where(models.TenantQuery.UserID.Eq(userID)).First()
var tid int64 = 0
if err == nil {
tid = t.ID
}
asset := &models.MediaAsset{
TenantID: tid,
UserID: userID,
Type: consts.MediaAssetType(typeArg),
Status: consts.MediaAssetStatusUploaded,
Provider: "local",
Bucket: "default",
ObjectKey: objectKey,
Meta: types.NewJSONType(fields.MediaAssetMeta{
Size: file.Size,
}),
}
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 {
if objectKey == "" {
return ""
}
url, _ := s.storage.SignURL("GET", objectKey, 1*time.Hour)
return url
}