From 9b56d7ba51704857de851816e902bde7f6fa40de Mon Sep 17 00:00:00 2001 From: eson <9673575+githubcontent@user.noreply.gitee.com> Date: Thu, 29 Jun 2023 18:04:59 +0800 Subject: [PATCH] =?UTF-8?q?TODO:=20render/=20=E7=9B=B8=E5=85=B3=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- constants/concact_service.go | 6 ++ model/gmodel/fs_cloud_pick_up_logic.go | 16 +++- model/gmodel/fs_order_logic.go | 18 ++++- .../internal/logic/usercontactservicelogic.go | 14 ++-- .../test/usercontactservicelogic_test.go | 69 ++++------------ server/render/etc/render.yaml | 8 ++ server/render/internal/config/config.go | 9 +++ .../internal/handler/readimageshandler.go | 78 +++++++++++++++++++ server/render/internal/handler/routes.go | 27 +++++++ .../render/internal/handler/tounityhandler.go | 78 +++++++++++++++++++ .../render/internal/logic/readimageslogic.go | 34 ++++++++ server/render/internal/logic/tounitylogic.go | 34 ++++++++ server/render/internal/svc/servicecontext.go | 60 ++++++++++++++ server/render/internal/types/types.go | 74 ++++++++++++++++++ server/render/render.go | 49 ++++++++++++ server_api/render.api | 25 ++++++ utils/collect/collect.go | 42 ++++++---- utils/collect/collect_test.go | 35 +++++++++ utils/tests/basic.go | 4 +- 19 files changed, 597 insertions(+), 83 deletions(-) create mode 100644 constants/concact_service.go create mode 100644 server/render/etc/render.yaml create mode 100644 server/render/internal/config/config.go create mode 100644 server/render/internal/handler/readimageshandler.go create mode 100644 server/render/internal/handler/routes.go create mode 100644 server/render/internal/handler/tounityhandler.go create mode 100644 server/render/internal/logic/readimageslogic.go create mode 100644 server/render/internal/logic/tounitylogic.go create mode 100644 server/render/internal/svc/servicecontext.go create mode 100644 server/render/internal/types/types.go create mode 100644 server/render/render.go create mode 100644 server_api/render.api diff --git a/constants/concact_service.go b/constants/concact_service.go new file mode 100644 index 00000000..3cf6746d --- /dev/null +++ b/constants/concact_service.go @@ -0,0 +1,6 @@ +package constants + +type ConcactService string + +const TYPE_DEFAULT ConcactService = "default" +const TYPE_ORDER ConcactService = "order" diff --git a/model/gmodel/fs_cloud_pick_up_logic.go b/model/gmodel/fs_cloud_pick_up_logic.go index c6fd862b..f6d8d86c 100644 --- a/model/gmodel/fs_cloud_pick_up_logic.go +++ b/model/gmodel/fs_cloud_pick_up_logic.go @@ -2,6 +2,8 @@ package gmodel import ( "context" + "fusenapi/constants" + "time" "gorm.io/gorm" ) @@ -31,7 +33,19 @@ func (p *FsCloudPickUpModel) SavePickUpWithTransaction(ctx context.Context, pick }) } -func (p *FsCloudPickUpModel) GetCloudPickUpByIDAndUserID(ctx context.Context, userId int64, RelationID int64) (cloudOrder *FsCloudPickUp, err error) { +func (p *FsCloudPickUpModel) GetCloudPickUpByIDAndUserID(ctx context.Context, userId int64, RelationID int64, cs *FsContactService) (cloudOrder *FsCloudPickUp, err error) { + err = p.db.WithContext(ctx).Model(cloudOrder).Transaction(func(tx *gorm.DB) error { + err = tx.Model(cloudOrder).Select("id").Limit(1).Where("`user_id` = ? and `id` = ?", userId, RelationID).Take(&cloudOrder).Error + if err != nil { + return err + } + ctime := time.Now().Unix() + cs.Ctime = &ctime + if constants.ConcactService(*cs.Type) == constants.TYPE_DEFAULT { + *cs.RelationId = 0 + } + return tx.Model(cs).Create(cs).Error + }) return cloudOrder, err } diff --git a/model/gmodel/fs_order_logic.go b/model/gmodel/fs_order_logic.go index bf2d88de..d7e6e4ad 100755 --- a/model/gmodel/fs_order_logic.go +++ b/model/gmodel/fs_order_logic.go @@ -2,6 +2,8 @@ package gmodel import ( "context" + "fusenapi/constants" + "time" "gorm.io/gorm" ) @@ -27,11 +29,19 @@ func (o *FsOrderModel) Create(ctx context.Context, data *FsOrder) error { return o.db.WithContext(ctx).Model(&FsOrder{}).Create(&data).Error } -func (o *FsOrderModel) FindOneAndCreateServiceContact(ctx context.Context, userId int64, OrderId int64) (order *FsOrder, err error) { +func (o *FsOrderModel) FindOneAndCreateServiceContact(ctx context.Context, userId int64, OrderId int64, cs *FsContactService) (order *FsOrder, err error) { err = o.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { - err = tx.Model(order).Where("`user_id` = ? and `id` = ?", userId, OrderId).Take(&order).Error - tx.Table("").Model(FsContactService{}) - return err + err = tx.Model(order).Select("id").Limit(1).Where("`user_id` = ? and `id` = ?", userId, OrderId).Take(&order).Error + if err != nil { + return err + } + ctime := time.Now().Unix() + cs.Ctime = &ctime + if constants.ConcactService(*cs.Type) == constants.TYPE_DEFAULT { + *cs.RelationId = 0 + } + + return tx.Model(cs).Create(cs).Error }) return order, err } diff --git a/server/home-user-auth/internal/logic/usercontactservicelogic.go b/server/home-user-auth/internal/logic/usercontactservicelogic.go index 52afdb46..3b8509fb 100644 --- a/server/home-user-auth/internal/logic/usercontactservicelogic.go +++ b/server/home-user-auth/internal/logic/usercontactservicelogic.go @@ -37,13 +37,14 @@ func (l *UserContactServiceLogic) UserContactService(req *types.RequestContactSe return resp.SetStatus(basic.CodeUnAuth) } - cs := gmodel.FsContactService{} - - collect.LoadJsonTag(cs, req) + cs := gmodel.FsContactService{ + UserId: &userinfo.UserId, + } + collect.LoadJsonTag(&cs, &req) switch req.Type { case "order": - _, err := l.svcCtx.AllModels.FsOrder.FindOneAndCreateServiceContact(l.ctx, userinfo.UserId, req.RelationID) + _, err := l.svcCtx.AllModels.FsOrder.FindOneAndCreateServiceContact(l.ctx, userinfo.UserId, req.RelationID, &cs) if err != nil { if err == gorm.ErrRecordNotFound { return resp.SetStatus(basic.CodeOrderNotFoundErr) @@ -51,16 +52,17 @@ func (l *UserContactServiceLogic) UserContactService(req *types.RequestContactSe return resp.SetStatus(basic.CodeDbSqlErr) } case "cloud": - _, err := l.svcCtx.AllModels.FsCloudPickUp.GetCloudPickUpByIDAndUserID(l.ctx, userinfo.UserId, req.RelationID) + _, err := l.svcCtx.AllModels.FsCloudPickUp.GetCloudPickUpByIDAndUserID(l.ctx, userinfo.UserId, req.RelationID, &cs) if err != nil { if err == gorm.ErrRecordNotFound { return resp.SetStatus(basic.CodeCloudOrderNotFoundErr) } return resp.SetStatus(basic.CodeDbSqlErr) } + return default: return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "type is unknown") } - return resp.SetStatus(basic.CodeOK) + return resp.SetStatus(basic.CodeOK, cs) } diff --git a/server/home-user-auth/test/usercontactservicelogic_test.go b/server/home-user-auth/test/usercontactservicelogic_test.go index 33625fc9..30483af5 100644 --- a/server/home-user-auth/test/usercontactservicelogic_test.go +++ b/server/home-user-auth/test/usercontactservicelogic_test.go @@ -18,16 +18,16 @@ func TestUserContactService(t *testing.T) { // 获取 session,并携带 JWT token ses := fstests.GetSessionWithUserToken(t, gserver, cnf.Host, cnf.Port) tp := ses.Post(fmt.Sprintf("http://%s:%d/user/contact-service", cnf.Host, cnf.Port)) - req := types.RequestContactService{Type: "order", RelationID: 123, Email: "admin@admin.com", Name: "eson"} + req := types.RequestContactService{Type: "order", RelationID: 481, Email: "9107058@qq.com", Name: "zhang"} tp.SetBodyJson(req) // 向服务器发送 GET 请求,获取用户基本信息 resp, err = tp.TestExecute(gserver) if err != nil { t.Error(err) } - + respjson := resp.Json() // 检查返回值中的 code 字段是否存在,并且值是否为 200 - result = resp.Json().Get("code") + result = respjson.Get("code") if !result.Exists() { t.Error("code is not exists") } @@ -36,7 +36,7 @@ func TestUserContactService(t *testing.T) { } // 检查返回值中的 msg 字段是否存在,并且值是否为 "success" - result = resp.Json().Get("msg") + result = respjson.Get("msg") if !result.Exists() { t.Error("msg is not exists") } @@ -45,63 +45,26 @@ func TestUserContactService(t *testing.T) { } // 检查返回值中的 data 字段是否存在 - result = resp.Json().Get("data") + result = respjson.Get("data") if !result.Exists() { t.Error("data is not exists") } - // 检查返回值中的 type 字段是否存在,并且值是否为 0 - result = resp.Json().Get("data.type") + // 检查返回值中的 msg 字段是否存在,并且值是否为 "success" + result = respjson.Get("msg") if !result.Exists() { - t.Error("type is not exists") + t.Error("msg does not exist") } - // 检查返回值中的 is_order_status_email 字段是否存在,并且值是否为 false - result = resp.Json().Get("data.is_order_status_email") - if !result.Exists() { - t.Error("is_order_status_email is not exists") - } + data := respjson.Get("data") - // 检查返回值中的 is_email_advertisement 字段是否存在,并且值是否为 false - result = resp.Json().Get("data.is_email_advertisement") - if !result.Exists() { - t.Error("is_email_advertisement is not exists") - } - - // 检查返回值中的 is_order_status_phone 字段是否存在,并且值是否为 false - result = resp.Json().Get("data.is_order_status_phone") - if !result.Exists() { - t.Error("is_order_status_phone is not exists") - } - - // 检查返回值中的 is_phone_advertisement 字段是否存在,并且值是否为 false - result = resp.Json().Get("data.is_phone_advertisement") - if !result.Exists() { - t.Error("is_phone_advertisement is not exists") - } - - // 检查返回值中的 is_open_render 字段是否存在,并且值是否为 false - result = resp.Json().Get("data.is_open_render") - if !result.Exists() { - t.Error("is_open_render is not exists") - } - - // 检查返回值中的 is_thousand_face 字段是否存在,并且值是否为 false - result = resp.Json().Get("data.is_thousand_face") - if !result.Exists() { - t.Error("is_thousand_face is not exists") - } - - // 检查返回值中的 is_low_rendering 字段是否存在,并且值是否为 false - result = resp.Json().Get("data.is_low_rendering") - if !result.Exists() { - t.Error("is_low_rendering is not exists") - } - - // 检查返回值中的 is_remove_bg 字段是否存在,并且值是否为 true - result = resp.Json().Get("data.is_remove_bg") - if !result.Exists() { - t.Error("is_remove_bg is not exists") + // 补充检查返回值中的每个字段是否存在 + fieldKeys := []string{"id", "type", "relation_id", "user_id", "name", "email", "phone", "remark", "is_handle", "ctime", "handle_remark", "handle_uid", "handle_time"} + for _, key := range fieldKeys { + field := data.Get(key) + if !field.Exists() { + t.Errorf("Field '%s' does not exist", key) + } } } diff --git a/server/render/etc/render.yaml b/server/render/etc/render.yaml new file mode 100644 index 00000000..a4865400 --- /dev/null +++ b/server/render/etc/render.yaml @@ -0,0 +1,8 @@ +Name: render +Host: 0.0.0.0 +Port: 8888 +SourceMysql: "" +Auth: + AccessSecret: fusen2023 + AccessExpire: 604800 + RefreshAfter: 345600 \ No newline at end of file diff --git a/server/render/internal/config/config.go b/server/render/internal/config/config.go new file mode 100644 index 00000000..b24bb7d7 --- /dev/null +++ b/server/render/internal/config/config.go @@ -0,0 +1,9 @@ +package config + +import "github.com/zeromicro/go-zero/rest" + +type Config struct { + rest.RestConf + SourceMysql string + Auth types.Auth +} diff --git a/server/render/internal/handler/readimageshandler.go b/server/render/internal/handler/readimageshandler.go new file mode 100644 index 00000000..26577e20 --- /dev/null +++ b/server/render/internal/handler/readimageshandler.go @@ -0,0 +1,78 @@ +package handler + +import ( + "errors" + "net/http" + + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/rest/httpx" + + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "fusenapi/server/render/internal/logic" + "fusenapi/server/render/internal/svc" + "fusenapi/server/render/internal/types" +) + +func ReadImagesHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var ( + // 定义错误变量 + err error + // 定义用户信息变量 + userinfo *auth.UserInfo + ) + // 解析JWT token,并对空用户进行判断 + claims, err := svcCtx.ParseJwtToken(r) + // 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 401, // 返回401状态码,表示未授权 + Message: "unauthorized", // 返回未授权信息 + }) + logx.Info("unauthorized:", err.Error()) // 记录错误日志 + return + } + + if claims != nil { + // 从token中获取对应的用户信息 + userinfo, err = auth.GetUserInfoFormMapClaims(claims) + // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + return + } + } else { + // 如果claims为nil,则认为用户身份为白板用户 + userinfo = &auth.UserInfo{UserId: 0, GuestId: 0} + } + + var req types.RequestReadImages + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 + if err := httpx.Parse(r, &req); err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 510, + Message: "parameter error", + }) + logx.Info(err) + return + } + // 创建一个业务逻辑层实例 + l := logic.NewReadImagesLogic(r.Context(), svcCtx) + resp := l.ReadImages(&req, userinfo) + // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; + if resp != nil { + httpx.OkJsonCtx(r.Context(), w, resp) + } else { + err := errors.New("server logic is error, resp must not be nil") + httpx.ErrorCtx(r.Context(), w, err) + logx.Error(err) + } + } +} diff --git a/server/render/internal/handler/routes.go b/server/render/internal/handler/routes.go new file mode 100644 index 00000000..2763e81b --- /dev/null +++ b/server/render/internal/handler/routes.go @@ -0,0 +1,27 @@ +// Code generated by goctl. DO NOT EDIT. +package handler + +import ( + "net/http" + + "fusenapi/server/render/internal/svc" + + "github.com/zeromicro/go-zero/rest" +) + +func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { + server.AddRoutes( + []rest.Route{ + { + Method: http.MethodGet, + Path: "/render/to-unity", + Handler: ToUnityHandler(serverCtx), + }, + { + Method: http.MethodGet, + Path: "/render/read-images", + Handler: ReadImagesHandler(serverCtx), + }, + }, + ) +} diff --git a/server/render/internal/handler/tounityhandler.go b/server/render/internal/handler/tounityhandler.go new file mode 100644 index 00000000..80071f59 --- /dev/null +++ b/server/render/internal/handler/tounityhandler.go @@ -0,0 +1,78 @@ +package handler + +import ( + "errors" + "net/http" + + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/rest/httpx" + + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "fusenapi/server/render/internal/logic" + "fusenapi/server/render/internal/svc" + "fusenapi/server/render/internal/types" +) + +func ToUnityHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var ( + // 定义错误变量 + err error + // 定义用户信息变量 + userinfo *auth.UserInfo + ) + // 解析JWT token,并对空用户进行判断 + claims, err := svcCtx.ParseJwtToken(r) + // 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 401, // 返回401状态码,表示未授权 + Message: "unauthorized", // 返回未授权信息 + }) + logx.Info("unauthorized:", err.Error()) // 记录错误日志 + return + } + + if claims != nil { + // 从token中获取对应的用户信息 + userinfo, err = auth.GetUserInfoFormMapClaims(claims) + // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + return + } + } else { + // 如果claims为nil,则认为用户身份为白板用户 + userinfo = &auth.UserInfo{UserId: 0, GuestId: 0} + } + + var req types.RequestToUnity + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 + if err := httpx.Parse(r, &req); err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 510, + Message: "parameter error", + }) + logx.Info(err) + return + } + // 创建一个业务逻辑层实例 + l := logic.NewToUnityLogic(r.Context(), svcCtx) + resp := l.ToUnity(&req, userinfo) + // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; + if resp != nil { + httpx.OkJsonCtx(r.Context(), w, resp) + } else { + err := errors.New("server logic is error, resp must not be nil") + httpx.ErrorCtx(r.Context(), w, err) + logx.Error(err) + } + } +} diff --git a/server/render/internal/logic/readimageslogic.go b/server/render/internal/logic/readimageslogic.go new file mode 100644 index 00000000..34b32eec --- /dev/null +++ b/server/render/internal/logic/readimageslogic.go @@ -0,0 +1,34 @@ +package logic + +import ( + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "context" + + "fusenapi/server/render/internal/svc" + "fusenapi/server/render/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ReadImagesLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewReadImagesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ReadImagesLogic { + return &ReadImagesLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *ReadImagesLogic) ReadImages(req *types.RequestReadImages, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + + return resp.SetStatus(basic.CodeOK) +} diff --git a/server/render/internal/logic/tounitylogic.go b/server/render/internal/logic/tounitylogic.go new file mode 100644 index 00000000..0787ebef --- /dev/null +++ b/server/render/internal/logic/tounitylogic.go @@ -0,0 +1,34 @@ +package logic + +import ( + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "context" + + "fusenapi/server/render/internal/svc" + "fusenapi/server/render/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ToUnityLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewToUnityLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ToUnityLogic { + return &ToUnityLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *ToUnityLogic) ToUnity(req *types.RequestToUnity, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + + return resp.SetStatus(basic.CodeOK) +} diff --git a/server/render/internal/svc/servicecontext.go b/server/render/internal/svc/servicecontext.go new file mode 100644 index 00000000..cc585118 --- /dev/null +++ b/server/render/internal/svc/servicecontext.go @@ -0,0 +1,60 @@ +package svc + +import ( + "errors" + "fmt" + "fusenapi/server/render/internal/config" + "net/http" + + "fusenapi/initalize" + "fusenapi/model/gmodel" + + "github.com/golang-jwt/jwt" + "gorm.io/gorm" +) + +type ServiceContext struct { + Config config.Config + + MysqlConn *gorm.DB + AllModels *gmodel.AllModelsGen +} + +func NewServiceContext(c config.Config) *ServiceContext { + + return &ServiceContext{ + Config: c, + MysqlConn: initalize.InitMysql(c.SourceMysql), + AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)), + } +} + +func (svcCtx *ServiceContext) ParseJwtToken(r *http.Request) (jwt.MapClaims, error) { + AuthKey := r.Header.Get("Authorization") + if AuthKey == "" { + return nil, nil + } + + if len(AuthKey) <= 50 { + return nil, errors.New(fmt.Sprint("Error parsing token, len:", len(AuthKey))) + } + + token, err := jwt.Parse(AuthKey, func(token *jwt.Token) (interface{}, error) { + // 检查签名方法是否为 HS256 + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) + } + // 返回用于验证签名的密钥 + return []byte(svcCtx.Config.Auth.AccessSecret), nil + }) + if err != nil { + return nil, errors.New(fmt.Sprint("Error parsing token:", err)) + } + + // 验证成功返回 + if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { + return claims, nil + } + + return nil, errors.New(fmt.Sprint("Invalid token", err)) +} diff --git a/server/render/internal/types/types.go b/server/render/internal/types/types.go new file mode 100644 index 00000000..a27a43c6 --- /dev/null +++ b/server/render/internal/types/types.go @@ -0,0 +1,74 @@ +// Code generated by goctl. DO NOT EDIT. +package types + +import ( + "fusenapi/utils/basic" +) + +type RequestToUnity struct { +} + +type RequestReadImages struct { +} + +type Request struct { +} + +type Response struct { + Code int `json:"code"` + Message string `json:"msg"` + Data interface{} `json:"data"` +} + +type Auth struct { + AccessSecret string `json:"accessSecret"` + AccessExpire int64 `json:"accessExpire"` + RefreshAfter int64 `json:"refreshAfter"` +} + +type Pagnation struct { + TotalCount int64 `json:"total_count"` + TotalPage int64 `json:"total_page"` + CurPage int64 `json:"cur_page"` + PageSize int64 `json:"page_size"` +} + +// Set 设置Response的Code和Message值 +func (resp *Response) Set(Code int, Message string) *Response { + return &Response{ + Code: Code, + Message: Message, + } +} + +// Set 设置整个Response +func (resp *Response) SetWithData(Code int, Message string, Data interface{}) *Response { + return &Response{ + Code: Code, + Message: Message, + Data: Data, + } +} + +// SetStatus 设置默认StatusResponse(内部自定义) 默认msg, 可以带data, data只使用一个参数 +func (resp *Response) SetStatus(sr *basic.StatusResponse, data ...interface{}) *Response { + newResp := &Response{ + Code: sr.Code, + } + if len(data) == 1 { + newResp.Data = data[0] + } + return newResp +} + +// SetStatusWithMessage 设置默认StatusResponse(内部自定义) 非默认msg, 可以带data, data只使用一个参数 +func (resp *Response) SetStatusWithMessage(sr *basic.StatusResponse, msg string, data ...interface{}) *Response { + newResp := &Response{ + Code: sr.Code, + Message: msg, + } + if len(data) == 1 { + newResp.Data = data[0] + } + return newResp +} diff --git a/server/render/render.go b/server/render/render.go new file mode 100644 index 00000000..901f9a1f --- /dev/null +++ b/server/render/render.go @@ -0,0 +1,49 @@ +package main + +import ( + "flag" + "fmt" + + "fusenapi/server/render/internal/config" + "fusenapi/server/render/internal/handler" + "fusenapi/server/render/internal/svc" + + "github.com/zeromicro/go-zero/core/conf" + "github.com/zeromicro/go-zero/rest" +) + +var configFile = flag.String("f", "etc/render.yaml", "the config file") + +func main() { + flag.Parse() + + var c config.Config + conf.MustLoad(*configFile, &c) + + server := rest.MustNewServer(c.RestConf) + defer server.Stop() + + ctx := svc.NewServiceContext(c) + handler.RegisterHandlers(server, ctx) + + fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) + server.Start() +} + +// var testConfigFile = flag.String("f", "../etc/render.yaml", "the config file") +// var cnf config.Config + +// func GetTestServer() *rest.Server { +// flag.Parse() + +// conf.MustLoad(*testConfigFile, &cnf) + +// server := rest.MustNewServer(cnf.RestConf) +// defer server.Stop() + +// ctx := svc.NewServiceContext(cnf) +// handler.RegisterHandlers(server, ctx) + +// fmt.Printf("Starting server at %s:%d...\n", cnf.Host, cnf.Port) +// return server +// } diff --git a/server_api/render.api b/server_api/render.api new file mode 100644 index 00000000..613f5e31 --- /dev/null +++ b/server_api/render.api @@ -0,0 +1,25 @@ +syntax = "v1" + +info ( + title: "渲染"// TODO: add title + desc: // TODO: add description + author: "" + email: "" +) + +import "basic.api" + +type RequestToUnity { +} + +type RequestReadImages { +} + +service render { + // 发送数据到unity渲染 + @handler ToUnityHandler + get /render/to-unity (RequestToUnity) returns (response); + // 读图像 + @handler ReadImagesHandler + get /render/read-images (RequestReadImages) returns (response); +} \ No newline at end of file diff --git a/utils/collect/collect.go b/utils/collect/collect.go index 796993eb..b0502d61 100644 --- a/utils/collect/collect.go +++ b/utils/collect/collect.go @@ -1,7 +1,6 @@ package collect import ( - "log" "reflect" "strconv" ) @@ -215,23 +214,33 @@ func StructSliceJson2Maps(s interface{}) []map[string]interface{} { return maps } +// LoadJsonTag 根据loader的json tag 赋值 给拥有相同json tag func LoadJsonTag(v interface{}, loaded interface{}) { vtype := reflect.TypeOf(v) + if vtype.Kind() != reflect.Ptr { + panic("v must is a pointer") + } + vtype = vtype.Elem() + + var vvalue reflect.Value if vtype.Kind() == reflect.Ptr { vtype = vtype.Elem() - } - vvalue := reflect.ValueOf(v) - if vvalue.Kind() == reflect.Ptr { - vvalue = vvalue.Elem() + vvalue = reflect.ValueOf(v).Elem().Elem() + } else { + vvalue = reflect.ValueOf(v).Elem() } ltype := reflect.TypeOf(loaded) + if ltype.Kind() != reflect.Ptr { + panic("loaded must is a pointer") + } + ltype = ltype.Elem() + var lvalue reflect.Value if ltype.Kind() == reflect.Ptr { ltype = ltype.Elem() - } - lvalue := reflect.ValueOf(loaded) - if lvalue.Kind() == reflect.Ptr { - lvalue = lvalue.Elem() + lvalue = reflect.ValueOf(loaded).Elem().Elem() + } else { + lvalue = reflect.ValueOf(loaded).Elem() } for i := 0; i < vtype.NumField(); i++ { @@ -244,26 +253,25 @@ func LoadJsonTag(v interface{}, loaded interface{}) { if ltag, ok := lfield.Tag.Lookup("json"); ok && vtag == ltag { vv := vvalue.Field(i) lv := lvalue.Field(j) - log.Println(vv.Kind(), vv.Type().Elem(), lv.Kind()) + if vv.Kind() == reflect.Ptr { + if lv.Kind() == reflect.Ptr { vv.Set(lv) } else { - vv = reflect.New(vv.Type().Elem()) - log.Println(vv.Type().Kind(), vv.Elem().Kind(), lv, reflect.Indirect(vv)) - reflect.Indirect(vv.Addr()).Set(lv.Addr()) - vv = reflect.New(vv.Type().Elem()) - - vv.Set(lv.Addr()) + x := reflect.New(vv.Type().Elem()) + x.Elem().Set(lv) + vv.Set(x) } - vv.Set(lv) } else { + if lv.Kind() != reflect.Ptr { vv.Set(lv) } else { vv.Set(lv.Elem()) } + } } } diff --git a/utils/collect/collect_test.go b/utils/collect/collect_test.go index d2448a8b..d60e40b8 100644 --- a/utils/collect/collect_test.go +++ b/utils/collect/collect_test.go @@ -1,7 +1,9 @@ package collect import ( + "fmt" "log" + "reflect" "testing" ) @@ -40,3 +42,36 @@ func TestArrayColumnTag(t *testing.T) { log.Printf("%##v", a) log.Println(len(a)) } + +func TestCaseMain(t *testing.T) { + + type MyStruct struct { + SomeIntPtr *int + SomeStringPtr *string + } + + var ms MyStruct + + // Set int pointer + { + var i interface{} = 3 // of type int + + f := reflect.ValueOf(&ms).Elem().FieldByName("SomeIntPtr") + x := reflect.New(f.Type().Elem()) + x.Elem().Set(reflect.ValueOf(i)) + f.Set(x) + } + + // Set string pointer + { + var i interface{} = "hi" // of type string + + f := reflect.ValueOf(&ms).Elem().Field(1) + x := reflect.New(f.Type().Elem()) + x.Elem().Set(reflect.ValueOf(i)) + f.Set(x) + } + + fmt.Println("ms.SomeIntPtr", *ms.SomeIntPtr) + fmt.Println("ms.SomeStringPtr", *ms.SomeStringPtr) +} diff --git a/utils/tests/basic.go b/utils/tests/basic.go index 94180b1c..1de9aace 100644 --- a/utils/tests/basic.go +++ b/utils/tests/basic.go @@ -16,8 +16,8 @@ func GetSessionWithUserToken(t *testing.T, server requests.ITestServer, Host str ses := requests.NewSession() tp := ses.Post(fmt.Sprintf("http://%s:%d/user/login", Host, Port)) tp.SetBodyJson(map[string]interface{}{ - "name": "devenv@sina.cn", - "pwd": "$2y$13$6UFDMZQMEfqFYiNLpiUCi.B3fpvGEamPAjIgzUqv/u7jT05nB3pOC", + "name": "9107058@qq.com", + "pwd": "$2y$13$2y4O4OIz/zcK5C0vlSc9LuSpjWySjInLBSe49yDkE.iURb.R1hDsy", }) resp, err := tp.TestExecute(server) if err != nil {