diff --git a/server/upload/internal/logic/uploadfilebackendlogic.go b/server/upload/internal/logic/uploadfilebackendlogic.go index 6b43a0d6..b0aee8fb 100644 --- a/server/upload/internal/logic/uploadfilebackendlogic.go +++ b/server/upload/internal/logic/uploadfilebackendlogic.go @@ -5,6 +5,7 @@ import ( "fusenapi/utils/basic" "fusenapi/utils/check" "fusenapi/utils/format" + "log" "time" "context" @@ -13,6 +14,7 @@ import ( "fusenapi/server/upload/internal/types" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/service/s3" "github.com/zeromicro/go-zero/core/logx" ) @@ -55,26 +57,61 @@ func (l *UploadFileBackendLogic) UploadFileBackend(req *types.RequestUploadFileB return resp.SetStatus(basic.CodeS3CategoryErr) } + var s3req *request.Request now := time.Now() - s3req, _ := svc.PutObjectRequest( - &s3.PutObjectInput{ - Bucket: aws.String("storage.fusenpack.com"), - Key: aws.String(format.FormatS3KeyName( - keytype, - uid, - now, - l.svcCtx.Config.Env, - req.Category, - req.File.Filename, - )), - }, - ) + category := format.TypeCategory(req.Category) + ObjectKey := aws.String(format.FormatS3KeyName( + keytype, + uid, + now, + l.svcCtx.Config.Env, + category, + req.File.Filename, + )) + + switch category { + case format.TCategoryRenderMegre: + + lifecycleConfiguration := &s3.BucketLifecycleConfiguration{ + Rules: []*s3.LifecycleRule{ + { + Status: aws.String("Enabled"), + // Status: aws.String("Disabled"), + Filter: &s3.LifecycleRuleFilter{ + Prefix: ObjectKey, + }, + Expiration: &s3.LifecycleExpiration{ + // Date: aws.Time(time.Now().UTC().Add(time.Minute)), + Days: aws.Int64(1), // 设置过期天数,例如:30天 + }, + // ID: aws.String("ExpireAfter01Days"), // 设置规则的唯一标识符 + }, + }, + } + + s3req, _ = svc.PutBucketLifecycleConfigurationRequest( + &s3.PutBucketLifecycleConfigurationInput{ + Bucket: basic.StorageBucketName, + LifecycleConfiguration: lifecycleConfiguration, + }, + ) + default: + s3req, _ = svc.PutObjectRequest( + &s3.PutObjectInput{ + Bucket: basic.StorageBucketName, + Key: ObjectKey, + }, + ) + + } s3req.SetBufferBody(req.File.Data) err := s3req.Send() if err != nil { + logx.Error(err) return resp.SetStatus(basic.CodeS3PutObjectRequestErr) } + log.Println(s3req.HTTPRequest.URL) return resp.SetStatus(basic.CodeOK, map[string]interface{}{ "upload_url": s3req.HTTPRequest.URL.String(), diff --git a/server/upload/internal/logic/uploadfilefrontendlogic.go b/server/upload/internal/logic/uploadfilefrontendlogic.go index b9396c67..847fbc4e 100644 --- a/server/upload/internal/logic/uploadfilefrontendlogic.go +++ b/server/upload/internal/logic/uploadfilefrontendlogic.go @@ -61,6 +61,7 @@ func (l *UploadFileFrontendLogic) UploadFileFrontend(req *types.RequestUploadFil } now := time.Now() + s3req, _ := svc.PutObjectRequest( &s3.PutObjectInput{ Bucket: aws.String("storage.fusenpack.com"), @@ -69,7 +70,7 @@ func (l *UploadFileFrontendLogic) UploadFileFrontend(req *types.RequestUploadFil uid, now, l.svcCtx.Config.Env, - req.Category, + format.TypeCategory(req.Category), req.FileName, )), ContentLength: aws.Int64(req.FileSize), diff --git a/server/upload/test/uploadfilebackendhandler_test.go b/server/upload/test/uploadfilebackendhandler_test.go new file mode 100644 index 00000000..2baf73cb --- /dev/null +++ b/server/upload/test/uploadfilebackendhandler_test.go @@ -0,0 +1,56 @@ +package test + +import ( + "fmt" + "fusenapi/utils/format" + fstests "fusenapi/utils/fstests" + "testing" + + "github.com/474420502/requests" + "github.com/tidwall/gjson" +) + +func TestCaseRenderMegre(t *testing.T) { + var err error + var resp *requests.Response + var result gjson.Result + + // 获取 session,并携带 JWT token + ses := fstests.GetSessionWithUserToken(t, userver, cnf.Host, cnf.Port) + tp := ses.Post(fmt.Sprintf("http://%s:%d/upload/upload-file-backend", cnf.Host, cnf.Port)) + + // data, err := ioutil.ReadFile("./fusen.webp") + // if err != nil { + // t.Error(err) + // return + // } + + mp := tp.CreateBodyMultipart() + mp.WriteField("file_type", "image") + mp.WriteField("category", string(format.TCategoryRenderMegre)) + mp.CreateFormFile("file", "./fusen.web") + tp.SetBodyFormData(mp) + + // 向服务器发送 GET 请求,获取用户基本信息 + resp, err = tp.TestExecute(gserver) + if err != nil { + t.Error(err) + } + + result = resp.Json() + if result.Get("code").Int() != 200 { + t.Error("code != 200") + } + + if !result.Get("data").Exists() { + t.Error("data not exists") + } + + if !result.Get("data.upload_url").Exists() { + t.Error("upload_url not exists") + } + + if resp.GetStatusCode() != 200 { + t.Error("put failed") + } +} diff --git a/server/upload/test/uploadfilefrontendhandler_test.go b/server/upload/test/uploadfilefrontendhandler_test.go index b65f7b07..5cab7f85 100644 --- a/server/upload/test/uploadfilefrontendhandler_test.go +++ b/server/upload/test/uploadfilefrontendhandler_test.go @@ -12,7 +12,7 @@ import ( "github.com/tidwall/gjson" ) -func TestCaseUploadfileFrontend(t *testing.T) { +func TestCasePersonalization(t *testing.T) { var err error var resp *requests.Response var result gjson.Result diff --git a/utils/basic/basic.go b/utils/basic/basic.go index 86ecf94f..5282ef47 100644 --- a/utils/basic/basic.go +++ b/utils/basic/basic.go @@ -6,9 +6,13 @@ import ( "net/http" "reflect" + "github.com/aws/aws-sdk-go/aws" "github.com/zeromicro/go-zero/core/logx" ) +// 全局的BucketName +var StorageBucketName = aws.String("storage.fusenpack.com") + const UploadFileLimitSize = 200 << 20 // File uploadfile 文件(multipart...) diff --git a/utils/format/s3keyname.go b/utils/format/s3keyname.go index c4514795..8765e0c8 100644 --- a/utils/format/s3keyname.go +++ b/utils/format/s3keyname.go @@ -52,10 +52,21 @@ func FormatS3KeyNameUser(userid int64, now time.Time, env string, category TypeC switch category { case TCategoryPersonalization: - // TODO: + // /{env}/personalization/{userid}/{filename} + return fmt.Sprintf("/%s/%s/%d/%s.%s", env, category, userid, name, ext) + case TCategoryRenderMegre: + // /{env}/render_megre/{userid}/{filename} 自动删除 + return fmt.Sprintf("/%s/%s/%d/%s_%d.%s", env, category, userid, name, now.Unix(), ext) + case TCategory3DTools: + // /{env}/3dtools/年月/{userid}/{filename} + return fmt.Sprintf("/%s/%s/%04d%02d/%d/%s_%d.%s", env, category, year, int(month), userid, name, now.Unix(), ext) + case TCategoryQuotation: + // /{env}/quotation/年月/{userid}/{filename} + return fmt.Sprintf("/%s/%s/%04d%02d/%d/%s_%d.%s", env, category, year, int(month), userid, name, now.Unix(), ext) + default: + return fmt.Sprintf("/%s/%s/%d/%04d%02d/%s_%d.%s", env, category, userid, year, int(month), name, now.Unix(), ext) } - return fmt.Sprintf("/%s/%s/%d/%04d%02d/%s_%d.%s", env, category, userid, year, int(month), name, now.Unix(), ext) } // FormatS3KeyNameGuest 游客的格式化存储 @@ -69,5 +80,24 @@ func FormatS3KeyNameGuest(guestid int64, now time.Time, env string, category Typ name = names[0] ext = names[1] } - return fmt.Sprintf("/%s/guest/%s/%d/%04d%02d/%s_%d.%s", env, category, guestid, year, int(month), name, now.Unix(), ext) + + switch category { + case TCategoryPersonalization: + // /{env}/personalization/{guestid}/{filename} + return fmt.Sprintf("/%s/%s/%d/%s.%s", env, category, guestid, name, ext) + case TCategoryRenderMegre: + // /{env}/render_megre/{guestid}/{filename} 自动删除 + return fmt.Sprintf("/%s/%s/%d/%s_%d.%s", env, category, guestid, name, now.Unix(), ext) + case TCategory3DTools: + panic(TCategory3DTools + "不存在游客") + // /{env}/3dtools/年月/{guestid}/{filename} + // return fmt.Sprintf("/%s/%s/%04d%02d/%d/%s_%d.%s", env, category, year, int(month), guestid, name, now.Unix(), ext) + case TCategoryQuotation: + panic(TCategoryQuotation + "不存在游客") + // /{env}/quotation/年月/{guestid}/{filename} + // return fmt.Sprintf("/%s/%s/%04d%02d/%d/%s_%d.%s", env, category, year, int(month), guestid, name, now.Unix(), ext) + default: + return fmt.Sprintf("/%s/%s/%d/%04d%02d/%s_%d.%s", env, category, guestid, year, int(month), name, now.Unix(), ext) + } + }