diff --git a/constants/render.go b/constants/render.go new file mode 100644 index 00000000..fe8b6a6f --- /dev/null +++ b/constants/render.go @@ -0,0 +1,203 @@ +package constants + +// 渲染要用到的面片模板 +const RENDER_FACE_SLICE_TEMPLATE_JSON = `[ + { + "id": "", + "tag": "MainColor", + "title": "", + "type": "color", + "text": "", + "fill": "{{MainColorFill}}", + "fontSize": 20, + "fontFamily": "Aqum2SmallCaps3", + "ifBr": false, + "ifShow": true, + "ifGroup": false, + "maxNum": 50, + "rotation": 0, + "lineHeight": 1, + "align": "center", + "verticalAlign": "middle", + "material": "", + "materialTime": "", + "materialName": "", + "QRcodeType": "", + "width": 1024, + "height": 1024, + "proportion": 60, + "x": 0, + "y": 0, + "opacity": 1, + "optionalColor": [ + { + "color": "#000000", + "name": "Black", + "default": true + } + ], + "zIndex": 1, + "svgPath": "", + "follow": { + "fill": "", + "ifShow": "", + "content": "" + }, + "group": [], + "cameraStand": { + "x": 0, + "y": 0, + "z": 0 + } + }, + { + "id": "", + "tag": "SecondaryColor", + "title": "贴图3", + "type": "color", + "text": "", + "fill": "{{SecondaryColorFill}}", + "fontSize": 20, + "fontFamily": "Aqum2SmallCaps3", + "ifBr": false, + "ifShow": true, + "ifGroup": false, + "maxNum": 50, + "rotation": 0, + "lineHeight": 1, + "align": "center", + "verticalAlign": "middle", + "material": "", + "materialTime": "", + "materialName": "", + "QRcodeType": "", + "width": 1024, + "height": 1024, + "proportion": 60, + "x": 0, + "y": 0, + "opacity": 1, + "optionalColor": [ + { + "color": "#000000", + "name": "Black", + "default": true + } + ], + "zIndex": 2, + "svgPath": "", + "follow": { + "fill": "", + "ifShow": "", + "content": "" + }, + "group": [], + "cameraStand": { + "x": 0, + "y": 0, + "z": 0 + } + }, + { + "id": "569d7981-25c3-3c03-0e7e-800c14800362", + "tag": "Slogan", + "title": "贴图4", + "type": "text", + "text": "", + "fill": "", + "fontSize": 13, + "fontFamily": "MontserratBold3", + "ifBr": false, + "ifShow": true, + "ifGroup": false, + "maxNum": 50, + "rotation": 0, + "lineHeight": 1, + "align": "center", + "verticalAlign": "middle", + "material": "", + "materialTime": "", + "materialName": "", + "QRcodeType": "", + "width": 309.9999999999993, + "height": 11.999265664648076, + "proportion": 60, + "x": 97.0015259021898, + "y": 575.300725990631, + "opacity": 1, + "optionalColor": [ + { + "color": "#000000", + "name": "Black", + "default": true + } + ], + "zIndex": 3, + "svgPath": "", + "follow": { + "fill": "38c09538-937d-510c-bf32-bfb1ce90cafa", + "ifShow": "", + "content": "" + }, + "group": [], + "cameraStand": { + "x": 0, + "y": 0, + "z": 45 + } + }, + { + "id": "c466e27c-d48f-db86-b85f-3c4c51114046", + "tag": "Logo", + "title": "贴图8", + "type": "image", + "text": "", + "fill": "#0082ca", + "fontSize": 20, + "fontFamily": "Aqum2SmallCaps3", + "ifBr": false, + "ifShow": true, + "ifGroup": false, + "maxNum": 50, + "rotation": 0, + "lineHeight": 1, + "align": "center", + "verticalAlign": "middle", + "material": "{{LogoMaterial}}", + "materialTime": "", + "materialName": "", + "QRcodeType": "", + "width": 282.9999999999999, + "height": 95.99999999999933, + "proportion": 60, + "x": 110.99999999999982, + "y": 438.7192999999991, + "opacity": 1, + "optionalColor": [ + { + "color": "#000000", + "name": "Black", + "default": false + }, + { + "name": "MainColor", + "color": "#0082ca", + "default": true + } + ], + "zIndex": 7, + "svgPath": "", + "follow": { + "fill": "", + "ifShow": "", + "content": "" + }, + "group": [], + "cameraStand": { + "x": 0, + "y": 0, + "z": 0 + } + } +] +` diff --git a/model/gmodel/fs_user_material_logic.go b/model/gmodel/fs_user_material_logic.go index d8ecaaf4..134ced4b 100644 --- a/model/gmodel/fs_user_material_logic.go +++ b/model/gmodel/fs_user_material_logic.go @@ -55,3 +55,18 @@ func (m *FsUserMaterialModel) RowSelectBuilder(selectData []string) *gorm.DB { } return rowBuilder } + +// 获取最新记录 +func (m *FsUserMaterialModel) FindLatestOne(ctx context.Context, userId int64, guestId int64) (resp FsUserMaterial, err error) { + if userId == 0 && guestId == 0 { + return FsUserMaterial{}, nil + } + db := m.db.WithContext(ctx).Model(&FsUserMaterial{}).Order("id DESC") + if userId != 0 { + db = db.Where("`user_id` = ?", userId) + } else { + db = db.Where("`guest_id` = ?", guestId) + } + err = db.Take(&resp).Error + return resp, err +} diff --git a/server/render/internal/handler/getfaceslicehandler.go b/server/render/internal/handler/getfaceslicehandler.go new file mode 100644 index 00000000..ac337bb0 --- /dev/null +++ b/server/render/internal/handler/getfaceslicehandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/render/internal/logic" + "fusenapi/server/render/internal/svc" + "fusenapi/server/render/internal/types" +) + +func GetFaceSliceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.Request + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewGetFaceSliceLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.GetFaceSlice(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/render/internal/handler/routes.go b/server/render/internal/handler/routes.go index 0bbf0d3e..26ad8b15 100644 --- a/server/render/internal/handler/routes.go +++ b/server/render/internal/handler/routes.go @@ -17,6 +17,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/render/render_notify", Handler: RenderNotifyHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/api/render/get_face_slice", + Handler: GetFaceSliceHandler(serverCtx), + }, }, ) } diff --git a/server/render/internal/logic/getfaceslicelogic.go b/server/render/internal/logic/getfaceslicelogic.go new file mode 100644 index 00000000..0afb49fb --- /dev/null +++ b/server/render/internal/logic/getfaceslicelogic.go @@ -0,0 +1,69 @@ +package logic + +import ( + "encoding/json" + "errors" + "fusenapi/constants" + "fusenapi/utils/auth" + "fusenapi/utils/basic" + "gorm.io/gorm" + "strings" + + "context" + + "fusenapi/server/render/internal/svc" + "fusenapi/server/render/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetFaceSliceLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetFaceSliceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetFaceSliceLogic { + return &GetFaceSliceLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *GetFaceSliceLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *GetFaceSliceLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } + +func (l *GetFaceSliceLogic) GetFaceSlice(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) { + if !userinfo.IsUser() && !userinfo.IsGuest() { + return resp.SetStatusWithMessage(basic.CodeUnAuth, "please login or access cookie") + } + //获取用户素材信息 + materialInfo, err := l.svcCtx.AllModels.FsUserMaterial.FindLatestOne(l.ctx, userinfo.UserId, userinfo.GuestId) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "user material info is not exists") + } + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user material info") + } + if materialInfo.Metadata == nil || *materialInfo.Metadata == "" { + return resp.SetStatusWithMessage(basic.CodeServiceErr, "user material info`Metadata is empty") + } + var info map[string]interface{} + if err = json.Unmarshal([]byte(*materialInfo.Metadata), &info); err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeJsonErr, "invalid json format of metadata") + } + str := strings.ReplaceAll(constants.RENDER_FACE_SLICE_TEMPLATE_JSON, "{{MainColorFill}}", info["main_color_fill"].(string)) + str = strings.ReplaceAll(str, "{{SecondaryColorFill}}", info["secondary_color_fill"].(string)) + str = strings.ReplaceAll(str, "{{LogoMaterial}}", info["logo_material"].(string)) + var rspInfo interface{} + _ = json.Unmarshal([]byte(str), &rspInfo) + return resp.SetStatusWithMessage(basic.CodeOK, "success", rspInfo) +} diff --git a/server_api/render.api b/server_api/render.api index f25d6ab3..8dd06347 100644 --- a/server_api/render.api +++ b/server_api/render.api @@ -19,6 +19,9 @@ service render { //云渲染完了通知接口 @handler RenderNotifyHandler post /api/render/render_notify(RenderNotifyReq) returns (response); + //获取面片信息 + @handler GetFaceSliceHandler + post /api/render/get_face_slice(request) returns (response); } //渲染完了通知接口