From d299a2aa3a2eb6858d63f77909765e1bd8ebb96c Mon Sep 17 00:00:00 2001 From: momo <1012651275@qq.com> Date: Wed, 30 Aug 2023 18:56:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=9B=BE=E7=89=87=E7=BC=A9=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 3 +- go.sum | 5 +- .../internal/handler/logoresizehandler.go | 35 +++++ server/resource/internal/handler/routes.go | 5 + .../internal/logic/logoresizelogic.go | 132 ++++++++++++++++++ server/resource/internal/types/types.go | 9 ++ server_api/resource.api | 12 ++ utils/basic/basic.go | 1 + 8 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 server/resource/internal/handler/logoresizehandler.go create mode 100644 server/resource/internal/logic/logoresizelogic.go diff --git a/go.mod b/go.mod index 187d7e92..a0803be1 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.0 github.com/aws/aws-sdk-go v1.44.295 github.com/bwmarrin/snowflake v0.3.0 + github.com/disintegration/imaging v1.6.2 github.com/go-resty/resty/v2 v2.7.0 github.com/golang-jwt/jwt v3.2.2+incompatible github.com/google/uuid v1.3.0 @@ -18,7 +19,7 @@ require ( github.com/streadway/amqp v1.1.0 github.com/stripe/stripe-go/v74 v74.26.0 github.com/zeromicro/go-zero v1.5.4 - golang.org/x/image v0.0.0-20190802002840-cff245a6509b + golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 golang.org/x/oauth2 v0.10.0 gorm.io/driver/mysql v1.5.1 gorm.io/gorm v1.25.1 diff --git a/go.sum b/go.sum index 815b0b69..e2b9c05e 100644 --- a/go.sum +++ b/go.sum @@ -136,6 +136,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4 h1:lS3P5Nw3oPO05Lk2gFiYUOL3QPaH+fRoI1wFOc4G1UY= @@ -627,8 +629,9 @@ golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691 h1:/yRP+0AN7mf5DkD3BAI6TOFnd golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/server/resource/internal/handler/logoresizehandler.go b/server/resource/internal/handler/logoresizehandler.go new file mode 100644 index 00000000..42dd27af --- /dev/null +++ b/server/resource/internal/handler/logoresizehandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/resource/internal/logic" + "fusenapi/server/resource/internal/svc" + "fusenapi/server/resource/internal/types" +) + +func LogoResizeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.LogoResizeReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewLogoResizeLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.LogoResize(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/resource/internal/handler/routes.go b/server/resource/internal/handler/routes.go index 50884ef8..304c232f 100644 --- a/server/resource/internal/handler/routes.go +++ b/server/resource/internal/handler/routes.go @@ -27,6 +27,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/resource/info", Handler: ResourceInfoHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/api/resource/logo-resize", + Handler: LogoResizeHandler(serverCtx), + }, }, ) } diff --git a/server/resource/internal/logic/logoresizelogic.go b/server/resource/internal/logic/logoresizelogic.go new file mode 100644 index 00000000..0f32f469 --- /dev/null +++ b/server/resource/internal/logic/logoresizelogic.go @@ -0,0 +1,132 @@ +package logic + +import ( + "bytes" + "encoding/json" + "fusenapi/model/gmodel" + "fusenapi/utils/auth" + "fusenapi/utils/basic" + "fusenapi/utils/file" + "fusenapi/utils/hash" + "image" + "image/jpeg" + "io" + "net/http" + + "context" + + "fusenapi/server/resource/internal/svc" + "fusenapi/server/resource/internal/types" + + "github.com/disintegration/imaging" + "github.com/zeromicro/go-zero/core/logx" +) + +type LogoResizeLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewLogoResizeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LogoResizeLogic { + return &LogoResizeLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *LogoResizeLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +func (l *LogoResizeLogic) LogoResize(req *types.LogoResizeReq, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + + var userId int64 + var guestId int64 + + // 检查用户是否是游客 + if userinfo.IsGuest() { + // 如果是,使用游客ID和游客键名格式 + guestId = userinfo.GuestId + } else { + // 否则,使用用户ID和用户键名格式 + userId = userinfo.UserId + } + + resourceModel := gmodel.NewFsResourceModel(l.svcCtx.MysqlConn) + resourceInfo, err := resourceModel.FindOneById(l.ctx, req.ResourceId) + if err != nil { + logx.Errorf("find resource err: %v", err) + return resp.SetStatus(basic.CodeFileNoFoundErr) + } + response, err := http.Get(*resourceInfo.ResourceUrl) + if err != nil { + logx.Errorf("http get err: %v", err) + return resp.SetStatus(basic.CodeFileNoFoundErr) + } + defer response.Body.Close() + + imgByte, err := io.ReadAll(response.Body) + if err != nil { + logx.Errorf("io readall err: %v", err) + return resp.SetStatus(basic.CodeFileNoFoundErr) + } + + src, _, err := image.Decode(bytes.NewReader(imgByte)) + if err != nil { + logx.Errorf("image decode err: %v", err) + return resp.SetStatus(basic.CodeFileNoFoundErr) + } + + // Resize the cropped image to width = 200px preserving the aspect ratio. + src = imaging.Resize(src, int(req.Width), int(req.Height), imaging.Lanczos) + if err != nil { + logx.Errorf("imaging esize err: %v", err) + return resp.SetStatus(basic.CodeFileNoFoundErr) + } + + emptyBuff := bytes.NewBuffer(nil) //开辟一个新的空buff + jpeg.Encode(emptyBuff, src, nil) //img写入到buff + + var hashKeyDataMap = make(map[string]interface{}) + + hashKeyDataB, _ := json.Marshal(req) + json.Unmarshal(hashKeyDataB, &hashKeyDataMap) + var resourceId string = hash.JsonHashKey(hashKeyDataMap) + + // 上传文件 + var upload = file.Upload{ + Ctx: l.ctx, + MysqlConn: l.svcCtx.MysqlConn, + AwsSession: l.svcCtx.AwsSession, + } + uploadRes, err := upload.UploadFileByByte(&file.UploadBaseReq{ + FileHash: resourceId, + FileByte: emptyBuff.Bytes(), + UploadBucket: 1, + ApiType: 2, + UserId: userId, + GuestId: guestId, + Source: "logo-resize", + }) + if err != nil { + logx.Errorf("upload UploadFileByByte err: %v", err) + return resp.SetStatus(basic.CodeFileNoFoundErr) + } + + // 原图metadata 更新 + + // 返回成功的响应和上传URL + return resp.SetStatus(basic.CodeOK, map[string]interface{}{ + "resource_id": uploadRes.ResourceId, + "resource_url": uploadRes.ResourceUrl, + }) +} + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *LogoResizeLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } diff --git a/server/resource/internal/types/types.go b/server/resource/internal/types/types.go index b13c8691..ce02c1b4 100644 --- a/server/resource/internal/types/types.go +++ b/server/resource/internal/types/types.go @@ -5,6 +5,15 @@ import ( "fusenapi/utils/basic" ) +type LogoResizeReq struct { + ResourceId string `form:"resource_id"` + Width int64 `form:"width"` + Height int64 `form:"height"` +} + +type LogoResizeRes struct { +} + type LogoRemovebgReq struct { IsRemoveBg string `form:"is_remove_bg"` LogoFile string `form:"logo_file"` diff --git a/server_api/resource.api b/server_api/resource.api index a62b2bca..51404295 100644 --- a/server_api/resource.api +++ b/server_api/resource.api @@ -22,8 +22,20 @@ service resource { @handler ResourceInfoHandler get /api/resource/info(ResourceInfoReq) returns (response); + + @handler LogoResizeHandler + post /api/resource/logo-resize(LogoResizeReq) returns (response); } +type ( + LogoResizeReq { + ResourceId string `form:"resource_id"` + Width int64 `form:"width"` + Height int64 `form:"height"` + } + LogoResizeRes struct{} +) + type ( LogoRemovebgReq { IsRemoveBg string `form:"is_remove_bg"` diff --git a/utils/basic/basic.go b/utils/basic/basic.go index 07e2f2b0..faefee61 100644 --- a/utils/basic/basic.go +++ b/utils/basic/basic.go @@ -92,6 +92,7 @@ var ( CodeFileUploadLogoErr = &StatusResponse{5111, "logo upload err"} // 用户上传LOGO失败 CodeFileUploadLogoErrType = &StatusResponse{5111, "logo upload err file is not image"} // 用户上位LOGO失败"} CodeFileLogoCombineErr = &StatusResponse{5112, "logo upload err"} // 用户合图失败 + CodeFileNoFoundErr = &StatusResponse{5113, "file not found err"} // 文件不存在 ) type Response struct {