From 36f22a6092dd871a86a73bedfacd61e26327fbff Mon Sep 17 00:00:00 2001 From: micah Date: Sat, 28 Mar 2026 19:29:40 +0800 Subject: [PATCH] feat: init --- .gitignore | 37 + README.md | 13 + app/config/config.go | 136 ++++ app/initialize/initialize.go | 14 + biz/handler/api_service/health_service.go | 35 + biz/handler/ping.go | 18 + biz/middleware/cors.go | 24 + biz/middleware/log.go | 27 + biz/middleware/reqeustid.go | 21 + biz/model/api_service/api_service.go | 431 +++++++++++ biz/model/base/base.go | 895 ++++++++++++++++++++++ biz/model/health/health.go | 404 ++++++++++ biz/router/api_service/api_service.go | 27 + biz/router/api_service/middleware.go | 27 + biz/router/register.go | 14 + build.sh | 8 + conf/conf.yml | 4 + conf/deploy_conf.yml | 4 + go.mod | 42 + go.sum | 146 ++++ idl/api_service.thrift | 7 + idl/base.thrift | 23 + idl/health/health.thrift | 11 + main.go | 37 + pkg/env/environment.go | 10 + pkg/env/system.go | 71 ++ pkg/jsonx/json.go | 43 ++ pkg/logx/log.go | 111 +++ pkg/logx/log_test.go | 110 +++ pkg/requestid/requestid.go | 27 + pkg/restyx/basic.go | 29 + pkg/restyx/resty.go | 315 ++++++++ pkg/uniqueid/unique.go | 16 + router.go | 15 + router_gen.go | 16 + script/bootstrap.sh | 5 + 36 files changed, 3173 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 app/config/config.go create mode 100644 app/initialize/initialize.go create mode 100644 biz/handler/api_service/health_service.go create mode 100644 biz/handler/ping.go create mode 100644 biz/middleware/cors.go create mode 100644 biz/middleware/log.go create mode 100644 biz/middleware/reqeustid.go create mode 100644 biz/model/api_service/api_service.go create mode 100644 biz/model/base/base.go create mode 100644 biz/model/health/health.go create mode 100644 biz/router/api_service/api_service.go create mode 100644 biz/router/api_service/middleware.go create mode 100644 biz/router/register.go create mode 100755 build.sh create mode 100644 conf/conf.yml create mode 100644 conf/deploy_conf.yml create mode 100644 go.mod create mode 100644 go.sum create mode 100644 idl/api_service.thrift create mode 100644 idl/base.thrift create mode 100644 idl/health/health.thrift create mode 100644 main.go create mode 100644 pkg/env/environment.go create mode 100644 pkg/env/system.go create mode 100644 pkg/jsonx/json.go create mode 100644 pkg/logx/log.go create mode 100644 pkg/logx/log_test.go create mode 100644 pkg/requestid/requestid.go create mode 100644 pkg/restyx/basic.go create mode 100644 pkg/restyx/resty.go create mode 100644 pkg/uniqueid/unique.go create mode 100644 router.go create mode 100644 router_gen.go create mode 100755 script/bootstrap.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f01e162 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +*.o +*.a +*.so +_obj +_test +*.[568vq] +[568vq].out +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* +_testmain.go +*.exe +*.exe~ +*.test +*.prof +*.rar +*.zip +*.gz +*.psd +*.bmd +*.cfg +*.pptx +*.log +*nohup.out +*settings.pyc +*.sublime-project +*.sublime-workspace +!.gitkeep +.DS_Store +/.idea +/.vscode +/output +/logs +*.local.yml +dumped_hertz_remote_config.json \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..812abe6 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# starter + +```shell +# 1. 安装插件 +go install github.com/cloudwego/hertz/cmd/hz@latest +go install github.com/cloudwego/thriftgo@v0.4.2 + +# 2. 初始化项目 +hz new -module gitea.micah.wiki/pandora/starter -idl idl/api_service.thrift + +# 3. 更新项目 +hz update -idl idl/api_service.thrift +``` \ No newline at end of file diff --git a/app/config/config.go b/app/config/config.go new file mode 100644 index 0000000..c00a516 --- /dev/null +++ b/app/config/config.go @@ -0,0 +1,136 @@ +package config + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "sync" + + "gopkg.in/yaml.v3" +) + +var ( + config *Config + once sync.Once +) + +func Init(args []string) { + _initConfig(args) +} + +type Config struct { + Server struct { + Host string `yaml:"host"` + Port int `yaml:"port"` + Env string `yaml:"env"` + } `yaml:"server"` + // 内部加工配置 + LogFile string +} + +func GetConfig() *Config { + return _initConfig(nil) +} + +func _initConfig(args []string) *Config { + if config == nil { + once.Do(func() { + c, err := loadConfig(args) + if err != nil { + panic(err) + } + config = c + }) + } + return config +} + +// 获取配置文件的绝对路径 +func getConfigFile(confFile string) string { + if confFile != "" { + if _, err := os.Stat(confFile); err == nil { + return confFile + } + } + // 方案:优先从工作目录查找(适配 GoLand 直接运行的场景) + workDir, err := os.Getwd() + if err == nil { + workDirConfig := filepath.Join(workDir, "output/conf/conf.yml") + if _, err := os.Stat(workDirConfig); err == nil { + return workDirConfig + } + workDirConfig = filepath.Join(workDir, "conf/conf.yml") + if _, err := os.Stat(workDirConfig); err == nil { + return workDirConfig + } + if strings.Contains(workDirConfig, "starter") { + values := strings.Split(workDirConfig, "/starter") + if len(values) > 1 { + v := filepath.Join(values[0], "starter", "conf/conf.yml") + if _, err := os.Stat(v); err == nil { + return v + } + } + } + } + + // 方案:从程序执行路径推导(适配部署环境) + exePath, err := os.Executable() + if err != nil { + panic(fmt.Sprintf("获取程序路径失败: %v", err)) + } + exeDir := filepath.Dir(exePath) + // 判断是否是部署环境(bin 目录下) + if filepath.Base(exeDir) == "bin" { + // 部署环境:output/bin/ -> output/conf/conf.yml + return filepath.Join(exeDir, "../conf/conf.yml") + } + + // 兜底:程序目录下的 conf/conf.yaml + return filepath.Join(exeDir, "conf/conf.yml") +} + +// 加载配置文件 +func loadConfig(args []string) (*Config, error) { + confFile := getValueFromArgs(args, "config") + configFile := getConfigFile(confFile) + fmt.Println("configFile:", configFile) + // 读取配置文件内容 + data, err := os.ReadFile(configFile) + if err != nil { + return nil, fmt.Errorf("读取配置文件失败: %v", err) + } + + // 解析 YAML 到结构体 + var c Config + if err := yaml.Unmarshal(data, &c); err != nil { + return nil, fmt.Errorf("解析 YAML 失败: %v", err) + } + prefix := "" + if !strings.Contains(configFile, "/output/conf/") { + prefix = "/output" + } + pathArr := strings.Split(configFile, "/conf/") + if len(pathArr) == 0 { + panic("配置文件需要在`conf`目录下") + } + logDir := pathArr[0] + prefix + "/logs" + fmt.Println("logDir:", logDir) + // 自动创建日志目录(关键:避免目录不存在导致写入失败) + if err := os.MkdirAll(logDir, 0755); err != nil { + panic(fmt.Sprintf("创建日志目录失败: %v", err)) + } + c.LogFile = filepath.Join(logDir, "starter.log") + return &c, nil +} + +func getValueFromArgs(args []string, key string) string { + for _, arg := range args { + if strings.HasPrefix(arg, fmt.Sprintf("%s=", key)) { + value := strings.ReplaceAll(arg, fmt.Sprintf("%s=", key), "") + return value + } + } + return "" +} diff --git a/app/initialize/initialize.go b/app/initialize/initialize.go new file mode 100644 index 0000000..6beef6a --- /dev/null +++ b/app/initialize/initialize.go @@ -0,0 +1,14 @@ +package initialize + +import ( + "gitea.micah.wiki/pandora/starter/app/config" + "gitea.micah.wiki/pandora/starter/pkg/logx" +) + +func Init(args []string) { + config.Init(args) + logx.Init() +} +func Close() { + logx.Close() +} diff --git a/biz/handler/api_service/health_service.go b/biz/handler/api_service/health_service.go new file mode 100644 index 0000000..763f090 --- /dev/null +++ b/biz/handler/api_service/health_service.go @@ -0,0 +1,35 @@ +// Code generated by hertz generator. + +package api_service + +import ( + "context" + + "gitea.micah.wiki/pandora/starter/biz/model/base" + health "gitea.micah.wiki/pandora/starter/biz/model/health" + "github.com/cloudwego/hertz/pkg/app" + "github.com/cloudwego/hertz/pkg/protocol/consts" +) + +// Ping . +// @router /openapi/health/ping [GET] +func Ping(ctx context.Context, c *app.RequestContext) { + var err error + var req health.PingRequest + err = c.BindAndValidate(&req) + if err != nil { + c.String(consts.StatusBadRequest, err.Error()) + return + } + + resp := &health.PingResponse{ + Code: 0, + Message: "pong", + Base: &base.BaseResp{ + StatusMessage: "", + StatusCode: 0, + }, + } + + c.JSON(consts.StatusOK, resp) +} diff --git a/biz/handler/ping.go b/biz/handler/ping.go new file mode 100644 index 0000000..950d476 --- /dev/null +++ b/biz/handler/ping.go @@ -0,0 +1,18 @@ +// Code generated by hertz generator. + +package handler + +import ( + "context" + + "github.com/cloudwego/hertz/pkg/app" + "github.com/cloudwego/hertz/pkg/common/utils" + "github.com/cloudwego/hertz/pkg/protocol/consts" +) + +// Ping . +func Ping(ctx context.Context, c *app.RequestContext) { + c.JSON(consts.StatusOK, utils.H{ + "message": "pong", + }) +} diff --git a/biz/middleware/cors.go b/biz/middleware/cors.go new file mode 100644 index 0000000..55cff75 --- /dev/null +++ b/biz/middleware/cors.go @@ -0,0 +1,24 @@ +package middleware + +import ( + "context" + + "github.com/cloudwego/hertz/pkg/app" +) + +func CorsMiddleware() app.HandlerFunc { + return func(c context.Context, ctx *app.RequestContext) { + origin := ctx.Request.Header.Get("Origin") + ctx.Header("Access-Control-Allow-Origin", ctx.Request.Header.Get("origin")) + if origin != "" { + ctx.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") + ctx.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token,Authorization,Cookie,FTF-Cookie-accessToken, x-origin") + ctx.Header("Access-Control-Allow-Credentials", "true") + } + method := ctx.Request.Method() + if string(method) == "OPTIONS" { + ctx.AbortWithStatus(200) + } + ctx.Next(c) + } +} diff --git a/biz/middleware/log.go b/biz/middleware/log.go new file mode 100644 index 0000000..724b6b9 --- /dev/null +++ b/biz/middleware/log.go @@ -0,0 +1,27 @@ +package middleware + +import ( + "context" + "strings" + "time" + + "github.com/cloudwego/hertz/pkg/app" + + "gitea.micah.wiki/pandora/starter/pkg/logx" +) + +func LogMiddleware() app.HandlerFunc { + return func(ctx context.Context, c *app.RequestContext) { + start := time.Now() + + uri := string(c.Request.URI().Path()) + query := string(c.Request.URI().QueryString()) + body := string(c.Request.Body()) + if len(body) > 0 { + body = strings.ReplaceAll(body, "\n", "\\n") + } + logx.CtxInfo(ctx, "com_request_in uri: `%s`, query: `%s`, body: `%s`", uri, query, body) + c.Next(ctx) + logx.CtxInfo(ctx, "com_request_out uri: `%s`, cost: `%+v`, resp: `%s`", uri, time.Since(start), string(c.Response.Body())) + } +} diff --git a/biz/middleware/reqeustid.go b/biz/middleware/reqeustid.go new file mode 100644 index 0000000..29b93af --- /dev/null +++ b/biz/middleware/reqeustid.go @@ -0,0 +1,21 @@ +package middleware + +import ( + "context" + + "gitea.micah.wiki/pandora/starter/pkg/requestid" + "gitea.micah.wiki/pandora/starter/pkg/uniqueid" + "github.com/cloudwego/hertz/pkg/app" +) + +func RequestIDMiddleware() app.HandlerFunc { + return func(ctx context.Context, c *app.RequestContext) { + existingID := c.Request.Header.Get(requestid.KLogIDKey) + if existingID == "" { + existingID = uniqueid.GetUniqueID() + c.Request.Header.Set(requestid.KLogIDKey, existingID) + } + ctx = requestid.SaveLogID(ctx, existingID) + c.Next(ctx) + } +} diff --git a/biz/model/api_service/api_service.go b/biz/model/api_service/api_service.go new file mode 100644 index 0000000..ddf44f8 --- /dev/null +++ b/biz/model/api_service/api_service.go @@ -0,0 +1,431 @@ +// Code generated by thriftgo (0.4.2). DO NOT EDIT. + +package api_service + +import ( + "context" + "fmt" + "gitea.micah.wiki/pandora/starter/biz/model/health" + "github.com/apache/thrift/lib/go/thrift" +) + +type HealthService interface { + Ping(ctx context.Context, req *health.PingRequest) (r *health.PingResponse, err error) +} + +type HealthServiceClient struct { + c thrift.TClient +} + +func NewHealthServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *HealthServiceClient { + return &HealthServiceClient{ + c: thrift.NewTStandardClient(f.GetProtocol(t), f.GetProtocol(t)), + } +} + +func NewHealthServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *HealthServiceClient { + return &HealthServiceClient{ + c: thrift.NewTStandardClient(iprot, oprot), + } +} + +func NewHealthServiceClient(c thrift.TClient) *HealthServiceClient { + return &HealthServiceClient{ + c: c, + } +} + +func (p *HealthServiceClient) Client_() thrift.TClient { + return p.c +} + +func (p *HealthServiceClient) Ping(ctx context.Context, req *health.PingRequest) (r *health.PingResponse, err error) { + var _args HealthServicePingArgs + _args.Req = req + var _result HealthServicePingResult + if err = p.Client_().Call(ctx, "Ping", &_args, &_result); err != nil { + return + } + return _result.GetSuccess(), nil +} + +type HealthServiceProcessor struct { + processorMap map[string]thrift.TProcessorFunction + handler HealthService +} + +func (p *HealthServiceProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) { + p.processorMap[key] = processor +} + +func (p *HealthServiceProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) { + processor, ok = p.processorMap[key] + return processor, ok +} + +func (p *HealthServiceProcessor) ProcessorMap() map[string]thrift.TProcessorFunction { + return p.processorMap +} + +func NewHealthServiceProcessor(handler HealthService) *HealthServiceProcessor { + self := &HealthServiceProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)} + self.AddToProcessorMap("Ping", &healthServiceProcessorPing{handler: handler}) + return self +} +func (p *HealthServiceProcessor) Process(ctx context.Context, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + name, _, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return false, err + } + if processor, ok := p.GetProcessorFunction(name); ok { + return processor.Process(ctx, seqId, iprot, oprot) + } + iprot.Skip(thrift.STRUCT) + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name) + oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, x +} + +type healthServiceProcessorPing struct { + handler HealthService +} + +func (p *healthServiceProcessorPing) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := HealthServicePingArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("Ping", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + result := HealthServicePingResult{} + var retval *health.PingResponse + if retval, err2 = p.handler.Ping(ctx, args.Req); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing Ping: "+err2.Error()) + oprot.WriteMessageBegin("Ping", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush(ctx) + return true, err2 + } else { + result.Success = retval + } + if err2 = oprot.WriteMessageBegin("Ping", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(ctx); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +type HealthServicePingArgs struct { + Req *health.PingRequest `thrift:"req,1"` +} + +func NewHealthServicePingArgs() *HealthServicePingArgs { + return &HealthServicePingArgs{} +} + +func (p *HealthServicePingArgs) InitDefault() { +} + +var HealthServicePingArgs_Req_DEFAULT *health.PingRequest + +func (p *HealthServicePingArgs) GetReq() (v *health.PingRequest) { + if !p.IsSetReq() { + return HealthServicePingArgs_Req_DEFAULT + } + return p.Req +} + +var fieldIDToName_HealthServicePingArgs = map[int16]string{ + 1: "req", +} + +func (p *HealthServicePingArgs) IsSetReq() bool { + return p.Req != nil +} + +func (p *HealthServicePingArgs) Read(iprot thrift.TProtocol) (err error) { + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_HealthServicePingArgs[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *HealthServicePingArgs) ReadField1(iprot thrift.TProtocol) error { + _field := health.NewPingRequest() + if err := _field.Read(iprot); err != nil { + return err + } + p.Req = _field + return nil +} + +func (p *HealthServicePingArgs) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("Ping_args"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *HealthServicePingArgs) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("req", thrift.STRUCT, 1); err != nil { + goto WriteFieldBeginError + } + if err := p.Req.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} + +func (p *HealthServicePingArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("HealthServicePingArgs(%+v)", *p) + +} + +type HealthServicePingResult struct { + Success *health.PingResponse `thrift:"success,0,optional"` +} + +func NewHealthServicePingResult() *HealthServicePingResult { + return &HealthServicePingResult{} +} + +func (p *HealthServicePingResult) InitDefault() { +} + +var HealthServicePingResult_Success_DEFAULT *health.PingResponse + +func (p *HealthServicePingResult) GetSuccess() (v *health.PingResponse) { + if !p.IsSetSuccess() { + return HealthServicePingResult_Success_DEFAULT + } + return p.Success +} + +var fieldIDToName_HealthServicePingResult = map[int16]string{ + 0: "success", +} + +func (p *HealthServicePingResult) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *HealthServicePingResult) Read(iprot thrift.TProtocol) (err error) { + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 0: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField0(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_HealthServicePingResult[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *HealthServicePingResult) ReadField0(iprot thrift.TProtocol) error { + _field := health.NewPingResponse() + if err := _field.Read(iprot); err != nil { + return err + } + p.Success = _field + return nil +} + +func (p *HealthServicePingResult) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("Ping_result"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField0(oprot); err != nil { + fieldId = 0 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *HealthServicePingResult) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err = oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil { + goto WriteFieldBeginError + } + if err := p.Success.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err) +} + +func (p *HealthServicePingResult) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("HealthServicePingResult(%+v)", *p) + +} diff --git a/biz/model/base/base.go b/biz/model/base/base.go new file mode 100644 index 0000000..af21256 --- /dev/null +++ b/biz/model/base/base.go @@ -0,0 +1,895 @@ +// Code generated by thriftgo (0.4.2). DO NOT EDIT. + +package base + +import ( + "fmt" + "github.com/apache/thrift/lib/go/thrift" +) + +type TrafficEnv struct { + Open bool `thrift:"open,1" form:"open" json:"open" query:"open"` + Env string `thrift:"env,2" form:"env" json:"env" query:"env"` +} + +func NewTrafficEnv() *TrafficEnv { + return &TrafficEnv{ + + Open: false, + Env: "", + } +} + +func (p *TrafficEnv) InitDefault() { + p.Open = false + p.Env = "" +} + +func (p *TrafficEnv) GetOpen() (v bool) { + return p.Open +} + +func (p *TrafficEnv) GetEnv() (v string) { + return p.Env +} + +var fieldIDToName_TrafficEnv = map[int16]string{ + 1: "open", + 2: "env", +} + +func (p *TrafficEnv) Read(iprot thrift.TProtocol) (err error) { + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.BOOL { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 2: + if fieldTypeId == thrift.STRING { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_TrafficEnv[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *TrafficEnv) ReadField1(iprot thrift.TProtocol) error { + + var _field bool + if v, err := iprot.ReadBool(); err != nil { + return err + } else { + _field = v + } + p.Open = _field + return nil +} +func (p *TrafficEnv) ReadField2(iprot thrift.TProtocol) error { + + var _field string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = v + } + p.Env = _field + return nil +} + +func (p *TrafficEnv) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("TrafficEnv"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *TrafficEnv) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("open", thrift.BOOL, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteBool(p.Open); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} +func (p *TrafficEnv) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("env", thrift.STRING, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Env); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} + +func (p *TrafficEnv) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("TrafficEnv(%+v)", *p) + +} + +type Base struct { + LogID string `thrift:"log_id,1" form:"log_id" json:"log_id" query:"log_id"` + Caller string `thrift:"caller,2" form:"caller" json:"caller" query:"caller"` + Addr string `thrift:"addr,3" form:"addr" json:"addr" query:"addr"` + Client string `thrift:"client,4" form:"client" json:"client" query:"client"` + TrafficEnv *TrafficEnv `thrift:"traffic_env,5,optional" form:"traffic_env" json:"traffic_env,omitempty" query:"traffic_env"` + Extra map[string]string `thrift:"extra,6,optional" form:"extra" json:"extra,omitempty" query:"extra"` +} + +func NewBase() *Base { + return &Base{ + + LogID: "", + Caller: "", + Addr: "", + Client: "", + } +} + +func (p *Base) InitDefault() { + p.LogID = "" + p.Caller = "" + p.Addr = "" + p.Client = "" +} + +func (p *Base) GetLogID() (v string) { + return p.LogID +} + +func (p *Base) GetCaller() (v string) { + return p.Caller +} + +func (p *Base) GetAddr() (v string) { + return p.Addr +} + +func (p *Base) GetClient() (v string) { + return p.Client +} + +var Base_TrafficEnv_DEFAULT *TrafficEnv + +func (p *Base) GetTrafficEnv() (v *TrafficEnv) { + if !p.IsSetTrafficEnv() { + return Base_TrafficEnv_DEFAULT + } + return p.TrafficEnv +} + +var Base_Extra_DEFAULT map[string]string + +func (p *Base) GetExtra() (v map[string]string) { + if !p.IsSetExtra() { + return Base_Extra_DEFAULT + } + return p.Extra +} + +var fieldIDToName_Base = map[int16]string{ + 1: "log_id", + 2: "caller", + 3: "addr", + 4: "client", + 5: "traffic_env", + 6: "extra", +} + +func (p *Base) IsSetTrafficEnv() bool { + return p.TrafficEnv != nil +} + +func (p *Base) IsSetExtra() bool { + return p.Extra != nil +} + +func (p *Base) Read(iprot thrift.TProtocol) (err error) { + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 2: + if fieldTypeId == thrift.STRING { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 3: + if fieldTypeId == thrift.STRING { + if err = p.ReadField3(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 4: + if fieldTypeId == thrift.STRING { + if err = p.ReadField4(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 5: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField5(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 6: + if fieldTypeId == thrift.MAP { + if err = p.ReadField6(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_Base[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *Base) ReadField1(iprot thrift.TProtocol) error { + + var _field string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = v + } + p.LogID = _field + return nil +} +func (p *Base) ReadField2(iprot thrift.TProtocol) error { + + var _field string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = v + } + p.Caller = _field + return nil +} +func (p *Base) ReadField3(iprot thrift.TProtocol) error { + + var _field string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = v + } + p.Addr = _field + return nil +} +func (p *Base) ReadField4(iprot thrift.TProtocol) error { + + var _field string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = v + } + p.Client = _field + return nil +} +func (p *Base) ReadField5(iprot thrift.TProtocol) error { + _field := NewTrafficEnv() + if err := _field.Read(iprot); err != nil { + return err + } + p.TrafficEnv = _field + return nil +} +func (p *Base) ReadField6(iprot thrift.TProtocol) error { + _, _, size, err := iprot.ReadMapBegin() + if err != nil { + return err + } + _field := make(map[string]string, size) + for i := 0; i < size; i++ { + var _key string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _key = v + } + + var _val string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _val = v + } + + _field[_key] = _val + } + if err := iprot.ReadMapEnd(); err != nil { + return err + } + p.Extra = _field + return nil +} + +func (p *Base) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("Base"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + if err = p.writeField3(oprot); err != nil { + fieldId = 3 + goto WriteFieldError + } + if err = p.writeField4(oprot); err != nil { + fieldId = 4 + goto WriteFieldError + } + if err = p.writeField5(oprot); err != nil { + fieldId = 5 + goto WriteFieldError + } + if err = p.writeField6(oprot); err != nil { + fieldId = 6 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *Base) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("log_id", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.LogID); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} +func (p *Base) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("caller", thrift.STRING, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Caller); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} +func (p *Base) writeField3(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("addr", thrift.STRING, 3); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Addr); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err) +} +func (p *Base) writeField4(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("client", thrift.STRING, 4); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Client); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 4 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 4 end error: ", p), err) +} +func (p *Base) writeField5(oprot thrift.TProtocol) (err error) { + if p.IsSetTrafficEnv() { + if err = oprot.WriteFieldBegin("traffic_env", thrift.STRUCT, 5); err != nil { + goto WriteFieldBeginError + } + if err := p.TrafficEnv.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 5 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 5 end error: ", p), err) +} +func (p *Base) writeField6(oprot thrift.TProtocol) (err error) { + if p.IsSetExtra() { + if err = oprot.WriteFieldBegin("extra", thrift.MAP, 6); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteMapBegin(thrift.STRING, thrift.STRING, len(p.Extra)); err != nil { + return err + } + for k, v := range p.Extra { + if err := oprot.WriteString(k); err != nil { + return err + } + if err := oprot.WriteString(v); err != nil { + return err + } + } + if err := oprot.WriteMapEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 6 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 6 end error: ", p), err) +} + +func (p *Base) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("Base(%+v)", *p) + +} + +type BaseResp struct { + StatusMessage string `thrift:"status_message,1" form:"status_message" json:"status_message" query:"status_message"` + StatusCode int32 `thrift:"status_code,2" form:"status_code" json:"status_code" query:"status_code"` + Extra map[string]string `thrift:"extra,3,optional" form:"extra" json:"extra,omitempty" query:"extra"` +} + +func NewBaseResp() *BaseResp { + return &BaseResp{ + + StatusMessage: "", + StatusCode: 0, + } +} + +func (p *BaseResp) InitDefault() { + p.StatusMessage = "" + p.StatusCode = 0 +} + +func (p *BaseResp) GetStatusMessage() (v string) { + return p.StatusMessage +} + +func (p *BaseResp) GetStatusCode() (v int32) { + return p.StatusCode +} + +var BaseResp_Extra_DEFAULT map[string]string + +func (p *BaseResp) GetExtra() (v map[string]string) { + if !p.IsSetExtra() { + return BaseResp_Extra_DEFAULT + } + return p.Extra +} + +var fieldIDToName_BaseResp = map[int16]string{ + 1: "status_message", + 2: "status_code", + 3: "extra", +} + +func (p *BaseResp) IsSetExtra() bool { + return p.Extra != nil +} + +func (p *BaseResp) Read(iprot thrift.TProtocol) (err error) { + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.STRING { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 2: + if fieldTypeId == thrift.I32 { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 3: + if fieldTypeId == thrift.MAP { + if err = p.ReadField3(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_BaseResp[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *BaseResp) ReadField1(iprot thrift.TProtocol) error { + + var _field string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = v + } + p.StatusMessage = _field + return nil +} +func (p *BaseResp) ReadField2(iprot thrift.TProtocol) error { + + var _field int32 + if v, err := iprot.ReadI32(); err != nil { + return err + } else { + _field = v + } + p.StatusCode = _field + return nil +} +func (p *BaseResp) ReadField3(iprot thrift.TProtocol) error { + _, _, size, err := iprot.ReadMapBegin() + if err != nil { + return err + } + _field := make(map[string]string, size) + for i := 0; i < size; i++ { + var _key string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _key = v + } + + var _val string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _val = v + } + + _field[_key] = _val + } + if err := iprot.ReadMapEnd(); err != nil { + return err + } + p.Extra = _field + return nil +} + +func (p *BaseResp) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("BaseResp"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + if err = p.writeField3(oprot); err != nil { + fieldId = 3 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *BaseResp) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("status_message", thrift.STRING, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.StatusMessage); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} +func (p *BaseResp) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("status_code", thrift.I32, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteI32(p.StatusCode); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} +func (p *BaseResp) writeField3(oprot thrift.TProtocol) (err error) { + if p.IsSetExtra() { + if err = oprot.WriteFieldBegin("extra", thrift.MAP, 3); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteMapBegin(thrift.STRING, thrift.STRING, len(p.Extra)); err != nil { + return err + } + for k, v := range p.Extra { + if err := oprot.WriteString(k); err != nil { + return err + } + if err := oprot.WriteString(v); err != nil { + return err + } + } + if err := oprot.WriteMapEnd(); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err) +} + +func (p *BaseResp) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("BaseResp(%+v)", *p) + +} diff --git a/biz/model/health/health.go b/biz/model/health/health.go new file mode 100644 index 0000000..841c298 --- /dev/null +++ b/biz/model/health/health.go @@ -0,0 +1,404 @@ +// Code generated by thriftgo (0.4.2). DO NOT EDIT. + +package health + +import ( + "fmt" + "gitea.micah.wiki/pandora/starter/biz/model/base" + "github.com/apache/thrift/lib/go/thrift" +) + +type PingRequest struct { + Base *base.Base `thrift:"base,255" form:"base" json:"base" query:"base"` +} + +func NewPingRequest() *PingRequest { + return &PingRequest{} +} + +func (p *PingRequest) InitDefault() { +} + +var PingRequest_Base_DEFAULT *base.Base + +func (p *PingRequest) GetBase() (v *base.Base) { + if !p.IsSetBase() { + return PingRequest_Base_DEFAULT + } + return p.Base +} + +var fieldIDToName_PingRequest = map[int16]string{ + 255: "base", +} + +func (p *PingRequest) IsSetBase() bool { + return p.Base != nil +} + +func (p *PingRequest) Read(iprot thrift.TProtocol) (err error) { + var fieldTypeId thrift.TType + var fieldId int16 + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 255: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField255(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_PingRequest[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +} + +func (p *PingRequest) ReadField255(iprot thrift.TProtocol) error { + _field := base.NewBase() + if err := _field.Read(iprot); err != nil { + return err + } + p.Base = _field + return nil +} + +func (p *PingRequest) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("PingRequest"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField255(oprot); err != nil { + fieldId = 255 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *PingRequest) writeField255(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("base", thrift.STRUCT, 255); err != nil { + goto WriteFieldBeginError + } + if err := p.Base.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 255 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 255 end error: ", p), err) +} + +func (p *PingRequest) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("PingRequest(%+v)", *p) + +} + +type PingResponse struct { + Code int32 `thrift:"code,1,required" form:"code,required" json:"code,required" query:"code,required"` + Message string `thrift:"message,2,required" form:"message,required" json:"message,required" query:"message,required"` + Base *base.BaseResp `thrift:"base,255" form:"base" json:"base" query:"base"` +} + +func NewPingResponse() *PingResponse { + return &PingResponse{} +} + +func (p *PingResponse) InitDefault() { +} + +func (p *PingResponse) GetCode() (v int32) { + return p.Code +} + +func (p *PingResponse) GetMessage() (v string) { + return p.Message +} + +var PingResponse_Base_DEFAULT *base.BaseResp + +func (p *PingResponse) GetBase() (v *base.BaseResp) { + if !p.IsSetBase() { + return PingResponse_Base_DEFAULT + } + return p.Base +} + +var fieldIDToName_PingResponse = map[int16]string{ + 1: "code", + 2: "message", + 255: "base", +} + +func (p *PingResponse) IsSetBase() bool { + return p.Base != nil +} + +func (p *PingResponse) Read(iprot thrift.TProtocol) (err error) { + var fieldTypeId thrift.TType + var fieldId int16 + var issetCode bool = false + var issetMessage bool = false + + if _, err = iprot.ReadStructBegin(); err != nil { + goto ReadStructBeginError + } + + for { + _, fieldTypeId, fieldId, err = iprot.ReadFieldBegin() + if err != nil { + goto ReadFieldBeginError + } + if fieldTypeId == thrift.STOP { + break + } + + switch fieldId { + case 1: + if fieldTypeId == thrift.I32 { + if err = p.ReadField1(iprot); err != nil { + goto ReadFieldError + } + issetCode = true + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 2: + if fieldTypeId == thrift.STRING { + if err = p.ReadField2(iprot); err != nil { + goto ReadFieldError + } + issetMessage = true + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + case 255: + if fieldTypeId == thrift.STRUCT { + if err = p.ReadField255(iprot); err != nil { + goto ReadFieldError + } + } else if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + default: + if err = iprot.Skip(fieldTypeId); err != nil { + goto SkipFieldError + } + } + if err = iprot.ReadFieldEnd(); err != nil { + goto ReadFieldEndError + } + } + if err = iprot.ReadStructEnd(); err != nil { + goto ReadStructEndError + } + + if !issetCode { + fieldId = 1 + goto RequiredFieldNotSetError + } + + if !issetMessage { + fieldId = 2 + goto RequiredFieldNotSetError + } + return nil +ReadStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) +ReadFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) +ReadFieldError: + return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_PingResponse[fieldId]), err) +SkipFieldError: + return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) + +ReadFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) +ReadStructEndError: + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) +RequiredFieldNotSetError: + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName_PingResponse[fieldId])) +} + +func (p *PingResponse) ReadField1(iprot thrift.TProtocol) error { + + var _field int32 + if v, err := iprot.ReadI32(); err != nil { + return err + } else { + _field = v + } + p.Code = _field + return nil +} +func (p *PingResponse) ReadField2(iprot thrift.TProtocol) error { + + var _field string + if v, err := iprot.ReadString(); err != nil { + return err + } else { + _field = v + } + p.Message = _field + return nil +} +func (p *PingResponse) ReadField255(iprot thrift.TProtocol) error { + _field := base.NewBaseResp() + if err := _field.Read(iprot); err != nil { + return err + } + p.Base = _field + return nil +} + +func (p *PingResponse) Write(oprot thrift.TProtocol) (err error) { + var fieldId int16 + if err = oprot.WriteStructBegin("PingResponse"); err != nil { + goto WriteStructBeginError + } + if p != nil { + if err = p.writeField1(oprot); err != nil { + fieldId = 1 + goto WriteFieldError + } + if err = p.writeField2(oprot); err != nil { + fieldId = 2 + goto WriteFieldError + } + if err = p.writeField255(oprot); err != nil { + fieldId = 255 + goto WriteFieldError + } + } + if err = oprot.WriteFieldStop(); err != nil { + goto WriteFieldStopError + } + if err = oprot.WriteStructEnd(); err != nil { + goto WriteStructEndError + } + return nil +WriteStructBeginError: + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) +WriteFieldError: + return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err) +WriteFieldStopError: + return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err) +WriteStructEndError: + return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err) +} + +func (p *PingResponse) writeField1(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("code", thrift.I32, 1); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteI32(p.Code); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err) +} +func (p *PingResponse) writeField2(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("message", thrift.STRING, 2); err != nil { + goto WriteFieldBeginError + } + if err := oprot.WriteString(p.Message); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err) +} +func (p *PingResponse) writeField255(oprot thrift.TProtocol) (err error) { + if err = oprot.WriteFieldBegin("base", thrift.STRUCT, 255); err != nil { + goto WriteFieldBeginError + } + if err := p.Base.Write(oprot); err != nil { + return err + } + if err = oprot.WriteFieldEnd(); err != nil { + goto WriteFieldEndError + } + return nil +WriteFieldBeginError: + return thrift.PrependError(fmt.Sprintf("%T write field 255 begin error: ", p), err) +WriteFieldEndError: + return thrift.PrependError(fmt.Sprintf("%T write field 255 end error: ", p), err) +} + +func (p *PingResponse) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("PingResponse(%+v)", *p) + +} diff --git a/biz/router/api_service/api_service.go b/biz/router/api_service/api_service.go new file mode 100644 index 0000000..4d108c3 --- /dev/null +++ b/biz/router/api_service/api_service.go @@ -0,0 +1,27 @@ +// Code generated by hertz generator. DO NOT EDIT. + +package api_service + +import ( + api_service "gitea.micah.wiki/pandora/starter/biz/handler/api_service" + "github.com/cloudwego/hertz/pkg/app/server" +) + +/* + This file will register all the routes of the services in the master idl. + And it will update automatically when you use the "update" command for the idl. + So don't modify the contents of the file, or your code will be deleted when it is updated. +*/ + +// Register register routes based on the IDL 'api.${HTTP Method}' annotation. +func Register(r *server.Hertz) { + + root := r.Group("/", rootMw()...) + { + _openapi := root.Group("/openapi", _openapiMw()...) + { + _health := _openapi.Group("/health", _healthMw()...) + _health.GET("/ping", append(_pingMw(), api_service.Ping)...) + } + } +} diff --git a/biz/router/api_service/middleware.go b/biz/router/api_service/middleware.go new file mode 100644 index 0000000..ed1cb20 --- /dev/null +++ b/biz/router/api_service/middleware.go @@ -0,0 +1,27 @@ +// Code generated by hertz generator. + +package api_service + +import ( + "github.com/cloudwego/hertz/pkg/app" +) + +func rootMw() []app.HandlerFunc { + // your code... + return nil +} + +func _openapiMw() []app.HandlerFunc { + // your code... + return nil +} + +func _healthMw() []app.HandlerFunc { + // your code... + return nil +} + +func _pingMw() []app.HandlerFunc { + // your code... + return nil +} diff --git a/biz/router/register.go b/biz/router/register.go new file mode 100644 index 0000000..bacc9e8 --- /dev/null +++ b/biz/router/register.go @@ -0,0 +1,14 @@ +// Code generated by hertz generator. DO NOT EDIT. + +package router + +import ( + api_service "gitea.micah.wiki/pandora/starter/biz/router/api_service" + "github.com/cloudwego/hertz/pkg/app/server" +) + +// GeneratedRegister registers routers generated by IDL. +func GeneratedRegister(r *server.Hertz) { + //INSERT_POINT: DO NOT DELETE THIS LINE! + api_service.Register(r) +} diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..140b6d2 --- /dev/null +++ b/build.sh @@ -0,0 +1,8 @@ +#!/bin/bash +RUN_NAME=hertz_service +mkdir -p output/bin +cp script/* output 2>/dev/null +mkdir -p output/conf +cp conf/* output/conf 2>/dev/null +chmod +x output/bootstrap.sh +go build -o output/bin/${RUN_NAME} \ No newline at end of file diff --git a/conf/conf.yml b/conf/conf.yml new file mode 100644 index 0000000..63bcb59 --- /dev/null +++ b/conf/conf.yml @@ -0,0 +1,4 @@ +server: + host: 127.0.0.1 + port: 8888 + env: local \ No newline at end of file diff --git a/conf/deploy_conf.yml b/conf/deploy_conf.yml new file mode 100644 index 0000000..e61816e --- /dev/null +++ b/conf/deploy_conf.yml @@ -0,0 +1,4 @@ +server: + host: 127.0.0.1 + port: 8055 + env: prod \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..32300e1 --- /dev/null +++ b/go.mod @@ -0,0 +1,42 @@ +module gitea.micah.wiki/pandora/starter + +go 1.24 + +replace github.com/apache/thrift => github.com/apache/thrift v0.13.0 + +require ( + github.com/apache/thrift v0.22.0 + github.com/bytedance/gopkg v0.1.3 + github.com/cloudwego/hertz v0.10.3 + github.com/go-resty/resty/v2 v2.17.1 + github.com/oklog/ulid/v2 v2.1.1 + go.uber.org/zap v1.27.1 + gopkg.in/natefinch/lumberjack.v2 v2.2.1 + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + github.com/bytedance/sonic v1.14.1 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect + github.com/cloudwego/gopkg v0.1.6 // indirect + github.com/cloudwego/netpoll v0.7.2 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/nyaruka/phonenumbers v1.0.56 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect + github.com/tidwall/gjson v1.17.3 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + go.uber.org/multierr v1.10.0 // indirect + golang.org/x/arch v0.14.0 // indirect + golang.org/x/net v0.43.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.28.0 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/protobuf v1.34.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..81617ba --- /dev/null +++ b/go.sum @@ -0,0 +1,146 @@ +github.com/apache/thrift v0.13.0 h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/bytedance/gopkg v0.1.1/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= +github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= +github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= +github.com/bytedance/sonic v1.14.1 h1:FBMC0zVz5XUmE4z9wF4Jey0An5FueFvOsTKKKtwIl7w= +github.com/bytedance/sonic v1.14.1/go.mod h1:gi6uhQLMbTdeP0muCnrjHLeCUPyb70ujhnNlhOylAFc= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= +github.com/cloudwego/gopkg v0.1.4/go.mod h1:FQuXsRWRsSqJLsMVd5SYzp8/Z1y5gXKnVvRrWUOsCMI= +github.com/cloudwego/gopkg v0.1.6 h1:EMlOHg975CxKX1/BtIVYKGW8hxNptTkjjJ7bvfXu4L4= +github.com/cloudwego/gopkg v0.1.6/go.mod h1:FQuXsRWRsSqJLsMVd5SYzp8/Z1y5gXKnVvRrWUOsCMI= +github.com/cloudwego/hertz v0.10.3 h1:NFcQAjouVJsod79XPLC/PaFfHgjMTYbiErmW+vGBi8A= +github.com/cloudwego/hertz v0.10.3/go.mod h1:W5dUFXZPZkyfjMMo3EQrMQbofuvTsctM9IxmhbkuT18= +github.com/cloudwego/netpoll v0.7.2 h1:4qDBGQ6CG2SvEXhZSDxMdtqt/NLDxjAVk0PC/biKiJo= +github.com/cloudwego/netpoll v0.7.2/go.mod h1:PI+YrmyS7cIr0+SD4seJz3Eo3ckkXdu2ZVKBLhURLNU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4= +github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= +github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/nyaruka/phonenumbers v1.0.56 h1:WdOfLJMyhXibLTBHu1MIrPmZ5eylfGaXZ9vl9h9SB08= +github.com/nyaruka/phonenumbers v1.0.56/go.mod h1:sDaTZ/KPX5f8qyV9qN+hIm+4ZBARJrupC6LuhshJq1U= +github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s= +github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= +github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94= +github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/arch v0.14.0 h1:z9JUEZWr8x4rR0OU6c4/4t6E6jOZ8/QBS2bBYBm4tx4= +golang.org/x/arch v0.14.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/idl/api_service.thrift b/idl/api_service.thrift new file mode 100644 index 0000000..dca6e53 --- /dev/null +++ b/idl/api_service.thrift @@ -0,0 +1,7 @@ +include "base.thrift" +include "health/health.thrift" +namespace go api_service + +service HealthService { + health.PingResponse Ping(1: health.PingRequest req)(api.get='/openapi/health/ping', api.serializer='json', api.category='健康检查') +}(api.service_path="health") \ No newline at end of file diff --git a/idl/base.thrift b/idl/base.thrift new file mode 100644 index 0000000..6dcb146 --- /dev/null +++ b/idl/base.thrift @@ -0,0 +1,23 @@ +namespace py base +namespace go base +namespace rs base +namespace java com.bytedance.thrift.base + +struct TrafficEnv { + 1: bool open = false, + 2: string env = "", +} +struct Base { + 1: string log_id = "", + 2: string caller = "", + 3: string addr = "", + 4: string client = "", + 5: optional TrafficEnv traffic_env, + 6: optional map extra, +} + +struct BaseResp { + 1: string status_message = "", + 2: i32 status_code = 0, + 3: optional map extra, +} diff --git a/idl/health/health.thrift b/idl/health/health.thrift new file mode 100644 index 0000000..e9664d4 --- /dev/null +++ b/idl/health/health.thrift @@ -0,0 +1,11 @@ +include "../base.thrift" +namespace go health + +struct PingRequest{ + 255: base.Base base +} +struct PingResponse{ + 1: required i32 code + 2: required string message + 255: base.BaseResp base +} \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..8a9ecfe --- /dev/null +++ b/main.go @@ -0,0 +1,37 @@ +// Code generated by hertz generator. + +package main + +import ( + "fmt" + "os" + + "github.com/cloudwego/hertz/pkg/app/server" + + "gitea.micah.wiki/pandora/starter/app/config" + "gitea.micah.wiki/pandora/starter/app/initialize" + "gitea.micah.wiki/pandora/starter/biz/middleware" +) + +func main() { + var args []string + if len(os.Args) > 1 { + args = os.Args[1:] + } + initialize.Init(args) + defer func() { + initialize.Close() + }() + var h *server.Hertz + conf := config.GetConfig() + if len(conf.Server.Host) > 0 && conf.Server.Port > 0 { + listenAddr := fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port) + h = server.New(server.WithHostPorts(listenAddr)) + } else { + h = server.Default() + } + + h.Use(middleware.RequestIDMiddleware(), middleware.CorsMiddleware(), middleware.LogMiddleware()) + register(h) + h.Spin() +} diff --git a/pkg/env/environment.go b/pkg/env/environment.go new file mode 100644 index 0000000..fcc4751 --- /dev/null +++ b/pkg/env/environment.go @@ -0,0 +1,10 @@ +package env + +import "gitea.micah.wiki/pandora/starter/app/config" + +func IsProd() bool { + return config.GetConfig().Server.Env == "prod" +} +func IsLocal() bool { + return config.GetConfig().Server.Env == "local" +} diff --git a/pkg/env/system.go b/pkg/env/system.go new file mode 100644 index 0000000..3b578d2 --- /dev/null +++ b/pkg/env/system.go @@ -0,0 +1,71 @@ +package env + +import ( + "runtime" + "strconv" + "syscall" +) + +// IsWindows 判断当前系统是否是 Windows +func IsWindows() bool { + return runtime.GOOS == "windows" +} + +// IsLinux 判断当前系统是否是 Linux +func IsLinux() bool { + return runtime.GOOS == "linux" +} + +// IsMacOS 判断当前系统是否是 macOS +func IsMacOS() bool { + return runtime.GOOS == "darwin" +} + +// IsMacIntel 判断当前 macOS 系统是否是 Intel 架构(x86_64) +// 非 macOS 系统返回 false +func IsMacIntel() bool { + if !IsMacOS() { + return false + } + + // 先通过 GOARCH 快速判断,兼容绝大多数场景 + if runtime.GOARCH == "amd64" { + // 验证硬件是否真的是 Intel(避免 Rosetta 兼容模式误判) + return !isAppleSiliconHardware() + } + return false +} + +// IsMacArm 判断当前 macOS 系统是否是 ARM 架构(Apple Silicon/M1/M2/M3) +// 非 macOS 系统返回 false +func IsMacArm() bool { + if !IsMacOS() { + return false + } + + // 场景1:原生 ARM 编译运行(GOARCH=arm64) + if runtime.GOARCH == "arm64" { + return true + } + + // 场景2:Intel 编译但运行在 ARM macOS 的 Rosetta 兼容模式下 + if runtime.GOARCH == "amd64" { + return isAppleSiliconHardware() + } + + return false +} + +// isAppleSiliconHardware 底层方法:判断 macOS 硬件是否是 Apple Silicon(ARM) +// 仅在 macOS 下调用有效,返回 true 表示 ARM 硬件,false 表示 Intel 硬件 +func isAppleSiliconHardware() bool { + val, err := syscall.Sysctl("hw.optional.arm64") + if err != nil { + return false + } + num, err := strconv.Atoi(val) + if err != nil { + return false + } + return num == 1 +} diff --git a/pkg/jsonx/json.go b/pkg/jsonx/json.go new file mode 100644 index 0000000..5474903 --- /dev/null +++ b/pkg/jsonx/json.go @@ -0,0 +1,43 @@ +package jsonx + +import ( + "context" + "encoding/json" + + "gitea.micah.wiki/pandora/starter/pkg/logx" +) + +var ( + Marshal = json.Marshal + Unmarshal = json.Unmarshal +) + +func UnsafeMarshal(ctx context.Context, v any) string { + b, err := Marshal(v) + if err != nil { + logx.CtxError(ctx, "Json UnsafeMarshal error, value: %+v, err: %+v.", v, err) + return "" + } + return string(b) +} + +func UnsafeUnmarshal(ctx context.Context, data string, v any) { + err := Unmarshal([]byte(data), v) + if err != nil { + logx.CtxError(ctx, "Json UnsafeUnmarshal error, data: %s, err: %+v.", data, err) + return + } +} + +func ConvertMarshal(ctx context.Context, from any, to any) { + b, err := Marshal(from) + if err != nil { + logx.CtxError(ctx, "Json ConvertMarshal error, from: %+v, err: %+v.", from, err) + return + } + err = json.Unmarshal(b, to) + if err != nil { + logx.CtxError(ctx, "Json ConvertMarshal error, from: %+v, err: %+v.", from, err) + return + } +} diff --git a/pkg/logx/log.go b/pkg/logx/log.go new file mode 100644 index 0000000..a4e5bd0 --- /dev/null +++ b/pkg/logx/log.go @@ -0,0 +1,111 @@ +package logx + +import ( + "context" + "fmt" + "sync" + + "gitea.micah.wiki/pandora/starter/app/config" + "gitea.micah.wiki/pandora/starter/pkg/env" + "gitea.micah.wiki/pandora/starter/pkg/requestid" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "gopkg.in/natefinch/lumberjack.v2" +) + +var ( + logger *zap.Logger + once sync.Once +) + +func Init() { + _ = _getLogger() +} + +func _getLogger() *zap.Logger { + if logger == nil { + once.Do(func() { + logFile := config.GetConfig().LogFile + encoderConfig := zapcore.EncoderConfig{ + TimeKey: "time", + LevelKey: "level", + NameKey: "logger", + CallerKey: "caller", + MessageKey: "msg", + StacktraceKey: "stacktrace", + LineEnding: zapcore.DefaultLineEnding, + EncodeLevel: zapcore.CapitalLevelEncoder, + EncodeTime: zapcore.ISO8601TimeEncoder, + EncodeDuration: zapcore.SecondsDurationEncoder, + EncodeCaller: zapcore.ShortCallerEncoder, + // 自定义控制台输出的字段顺序(仅对ConsoleEncoder生效) + ConsoleSeparator: " ", // 字段之间的分隔符 + } + var writer zapcore.WriteSyncer + var encoder zapcore.Encoder + writer = zapcore.AddSync(&lumberjack.Logger{ + Filename: logFile, + MaxSize: 10, // megabytes + MaxBackups: 30, + MaxAge: 7, // days + Compress: true, + }) + if env.IsLocal() { + encoder = zapcore.NewConsoleEncoder(encoderConfig) + } else { + // 其他系统保持 JSON 编码器 + encoder = zapcore.NewJSONEncoder(encoderConfig) + } + + core := zapcore.NewCore( + encoder, + writer, + zap.DebugLevel, + ) + logger = zap.New(core) + }) + } + return logger + +} +func Close() { + if logger != nil { + _ = logger.Sync() + } +} + +// 统一封装日志方法,根据编码器类型处理logid +func logWithCtx(ctx context.Context, level zapcore.Level, template string, args ...interface{}) { + logid := requestid.GetLogID(ctx) + msg := fmt.Sprintf(template, args...) + + // 根据编码器类型决定 logid 的展示方式 + if env.IsMacOS() { + // macOS控制台模式:将logid嵌入到消息中,保证文本可读性 + msg = fmt.Sprintf("%s %s", logid, msg) + _getLogger().Log(level, msg) + } else { + // 其他系统JSON模式:使用zap字段,保证JSON结构清晰 + _getLogger().With(zap.String("logid", logid)).Log(level, msg) + } +} + +// CtxInfo 带上下文的Info级别日志 +func CtxInfo(ctx context.Context, template string, args ...interface{}) { + logWithCtx(ctx, zapcore.InfoLevel, template, args...) +} + +// CtxError 带上下文的Error级别日志 +func CtxError(ctx context.Context, template string, args ...interface{}) { + logWithCtx(ctx, zapcore.ErrorLevel, template, args...) +} + +// CtxWarn 带上下文的Warn级别日志 +func CtxWarn(ctx context.Context, template string, args ...interface{}) { + logWithCtx(ctx, zapcore.WarnLevel, template, args...) +} + +// CtxDebug 带上下文的Debug级别日志 +func CtxDebug(ctx context.Context, template string, args ...interface{}) { + logWithCtx(ctx, zapcore.DebugLevel, template, args...) +} diff --git a/pkg/logx/log_test.go b/pkg/logx/log_test.go new file mode 100644 index 0000000..1aefe88 --- /dev/null +++ b/pkg/logx/log_test.go @@ -0,0 +1,110 @@ +package logx + +import ( + "context" + "testing" +) + +func TestCtxError(t *testing.T) { + type args struct { + ctx context.Context + template string + args []interface{} + } + tests := []struct { + name string + args args + }{ + { + name: "", + args: args{ + ctx: context.Background(), + template: "你好", + args: nil, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + CtxError(tt.args.ctx, tt.args.template, tt.args.args...) + }) + } +} + +func TestCtxWarn(t *testing.T) { + type args struct { + ctx context.Context + template string + args []interface{} + } + tests := []struct { + name string + args args + }{ + { + name: "", + args: args{ + ctx: context.Background(), + template: "你好 Warn", + args: nil, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + CtxWarn(tt.args.ctx, tt.args.template, tt.args.args...) + }) + } +} + +func TestCtxDebug(t *testing.T) { + type args struct { + ctx context.Context + template string + args []interface{} + } + tests := []struct { + name string + args args + }{ + { + name: "", + args: args{ + ctx: context.Background(), + template: "你好 Debug", + args: nil, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + CtxDebug(tt.args.ctx, tt.args.template, tt.args.args...) + }) + } +} + +func TestCtxInfo(t *testing.T) { + type args struct { + ctx context.Context + template string + args []interface{} + } + tests := []struct { + name string + args args + }{ + { + name: "", + args: args{ + ctx: context.Background(), + template: "你好呀", + args: nil, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + CtxInfo(tt.args.ctx, tt.args.template, tt.args.args...) + }) + } +} diff --git a/pkg/requestid/requestid.go b/pkg/requestid/requestid.go new file mode 100644 index 0000000..e66fa08 --- /dev/null +++ b/pkg/requestid/requestid.go @@ -0,0 +1,27 @@ +package requestid + +import ( + "context" + + "github.com/bytedance/gopkg/cloud/metainfo" +) + +const ( + KLogIDKey = "X_LOGID" +) + +func SaveLogID(ctx context.Context, requestID string) context.Context { + ctx = metainfo.WithValue(ctx, KLogIDKey, requestID) + return ctx +} + +func GetLogID(ctx context.Context) string { + v, ok := metainfo.GetValue(ctx, KLogIDKey) + if !ok { + return "-" + } + if v == "" { + return "-" + } + return v +} diff --git a/pkg/restyx/basic.go b/pkg/restyx/basic.go new file mode 100644 index 0000000..1923b61 --- /dev/null +++ b/pkg/restyx/basic.go @@ -0,0 +1,29 @@ +package restyx + +import ( + "bufio" + "context" +) + +type Basic struct { + LogID string `json:"log_id"` +} + +func (b *Basic) SetLogID(logID string) { + b.LogID = logID +} + +type SpecialResponse struct { + Headers string `json:"header"` + Data string `json:"data"` +} + +func (r *SpecialResponse) SetData(data string) { + r.Data = data +} + +func (r *SpecialResponse) SetHeaders(headers string) { + r.Headers = headers +} + +type StreamFunc func(ctx context.Context, scanner *bufio.Scanner) (interface{}, error) diff --git a/pkg/restyx/resty.go b/pkg/restyx/resty.go new file mode 100644 index 0000000..6b04a43 --- /dev/null +++ b/pkg/restyx/resty.go @@ -0,0 +1,315 @@ +// Package restyx this is http client wrapper. +package restyx + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "reflect" + "runtime" + "time" + + "gitea.micah.wiki/pandora/starter/pkg/jsonx" + "gitea.micah.wiki/pandora/starter/pkg/logx" + "gitea.micah.wiki/pandora/starter/pkg/requestid" + "github.com/go-resty/resty/v2" +) + +var ( + headerKeys []string +) + +const ( + HeaderJWTTokenKey = "X-Jwt-Token" + HeaderLogIDKey = requestid.KLogIDKey + + // PrintLogTypeDefault = 0 + + PrintLogTypeForce = 1 + PrintLogTypeDisable = 2 + + MaxPrintLogLength = 100000 + + maxCapacity = 10 * 1024 * 1024 + initCapacity = 1024 * 1024 +) + +func init() { + headerKeys = make([]string, 0) + headerKeys = append(headerKeys, HeaderJWTTokenKey) +} + +type Auth struct { + User string + Token string +} + +func (a *Auth) String() string { + if a == nil { + return "Auto: {nil}" + } + return fmt.Sprintf("Auth{User: %s, Token: %s}", a.User, a.Token) +} + +type Request struct { + Auth *Auth + URL string + Body interface{} + FormData map[string]string + QueryData map[string]string + Header map[string]string + PathParam map[string]string + Timeout int + PrintLogType int // 相见头部var定义 0: 默认; 1: 打印;2: 不打印; +} + +func (r *Request) String() string { + if r == nil { + return "Request: {nil}" + } + return fmt.Sprintf("Request: {Auth: %s, URL: %s, Body: %+v, FormData: %+v, QueryData: %+v, Header: %+v, PathParm: %+v, Timeout: %d, PrintLogType: %d}", + r.Auth, r.URL, r.Body, r.FormData, r.QueryData, r.Header, r.PathParam, r.Timeout, r.PrintLogType) +} + +type Response struct { + LogID string + Header map[string]string + TargetPoint interface{} +} + +func (r *Response) String() string { + if r == nil { + return "Response: {nil}" + } + return fmt.Sprintf("Response: {LogID: %s, Header: %+v, TargetPoint: %+v}", r.LogID, r.Header, r.TargetPoint) +} + +type StreamResponse struct { + LogID string + Header map[string]string + Target interface{} +} + +func PostStream(ctx context.Context, req *Request, streamFunc StreamFunc) (*StreamResponse, error) { + return DoStream(ctx, resty.MethodPost, req, streamFunc) +} +func DoStream(ctx context.Context, method string, req *Request, streamFunc StreamFunc) (*StreamResponse, error) { + start := time.Now() + request := getClient(ctx, req) + request = request.SetDoNotParseResponse(true) + var ( + resp *resty.Response + err error + ) + switch method { + case resty.MethodGet: + resp, err = request.Get(req.URL) + case resty.MethodPost: + resp, err = request.Post(req.URL) + case resty.MethodHead: + resp, err = request.Head(req.URL) + case resty.MethodDelete: + resp, err = request.Delete(req.URL) + default: + resp, err = request.Get(req.URL) + } + if err != nil { + return nil, err + } + + if !resp.IsSuccess() { + logx.CtxError(ctx, "HttpResty Resp IsFail. req: %+v, respCode: %d, respStatus: %s, resp: %+v, cost: %+v.", req, resp.StatusCode(), resp.Status(), resp, time.Since(start)) + return nil, err + } + defer func() { + _ = resp.RawResponse.Body.Close() // 记得关闭流,防止资源泄露 + }() + scanner := bufio.NewScanner(resp.RawResponse.Body) + + buf := make([]byte, initCapacity) // 初始缓冲区1MB + scanner.Buffer(buf, maxCapacity) // 设置最大缓冲区大小,比如 10MB + data, err := streamFunc(ctx, scanner) + if err != nil { + logx.CtxError(ctx, "HttpResty Resp streamFunc error. req: %+v, cost: %+v, err: %+v.", req, time.Since(start), err) + return nil, err + } + if err = scanner.Err(); err != nil { + logx.CtxError(ctx, "HttpResty Resp scanner error. req: %+v, respCode: %d, respStatus: %s, cost: %+v, err: %+v.", req, resp.StatusCode(), resp.Status(), time.Since(start), err) + return nil, err + } + + return &StreamResponse{ + LogID: resp.Header().Get(HeaderLogIDKey), + Target: data, + }, nil +} + +func Post(ctx context.Context, req *Request, targetPoint interface{}) error { + return Do(ctx, resty.MethodPost, req, targetPoint) +} + +func Get(ctx context.Context, req *Request, targetPoint interface{}) error { + return Do(ctx, resty.MethodGet, req, targetPoint) +} + +func Do(ctx context.Context, method string, req *Request, targetPoint interface{}) error { + restyResp, err := doRemote(ctx, method, req) + response := fillResponse(restyResp) + + if err != nil { + return err + } + if targetPoint != nil { + if _, ok := targetPoint.(*SpecialResponse); ok { + v := reflect.ValueOf(targetPoint) + setDataMethod := v.MethodByName("SetData") + if setDataMethod.IsValid() { + args := []reflect.Value{reflect.ValueOf(string(restyResp.Body()))} + setDataMethod.Call(args) + } + setHeadersMethod := v.MethodByName("SetHeaders") + if setHeadersMethod.IsValid() { + args := []reflect.Value{reflect.ValueOf(jsonx.UnsafeMarshal(ctx, response.Header))} + setHeadersMethod.Call(args) + } + + return nil + } + err = json.Unmarshal(restyResp.Body(), targetPoint) + if err != nil { + logx.CtxInfo(ctx, "HttpResty Resp Unmarshal Error. req: %+v, targetType: %+v, restyResp: %+v, err: %+v.", req, reflect.TypeOf(targetPoint), string(restyResp.Body()), err) + return err + } + fillTargetBase(ctx, response, targetPoint) + } + + return nil +} + +func getClient(ctx context.Context, req *Request) *resty.Request { + cli := resty.New() + if req.Timeout > 0 { + cli = cli.SetTimeout(time.Second * time.Duration(req.Timeout)) + } + request := cli.R().SetContext(ctx) + if req.Auth != nil && len(req.Auth.User) > 0 && len(req.Auth.Token) > 0 { + request = request.SetBasicAuth(req.Auth.User, req.Auth.Token) + } + headers := getHeaders(ctx, req.Header) + if len(headers) > 0 { + request = request.SetHeaders(headers) + } + if len(req.PathParam) > 0 { + request = request.SetPathParams(req.PathParam) + } + if req.Body != nil { + request = request.SetBody(req.Body) + } + if req.FormData != nil { + request = request.SetFormData(req.FormData) + } + if len(req.QueryData) > 0 { + request = request.SetQueryParams(req.QueryData) + } + return request +} + +func doRemote(ctx context.Context, method string, req *Request) (*resty.Response, error) { + start := time.Now() + if req.PrintLogType != PrintLogTypeDisable { + logx.CtxInfo(ctx, "HttpResty start. req: %+v", req) + } + request := getClient(ctx, req) + var ( + resp *resty.Response + err error + ) + switch method { + case resty.MethodGet: + resp, err = request.Get(req.URL) + case resty.MethodPost: + resp, err = request.Post(req.URL) + case resty.MethodHead: + resp, err = request.Head(req.URL) + case resty.MethodDelete: + resp, err = request.Delete(req.URL) + default: + resp, err = request.Get(req.URL) + } + if err != nil { + logx.CtxError(ctx, "HttpResty Handler Error. req: %+v, err: %+v, cost: %+v.", req, err, time.Since(start)) + return nil, err + } + + if !resp.IsSuccess() { + logx.CtxError(ctx, "HttpResty Resp IsFail. req: %+v, respCode: %d, respStatus: %s, resp: %+v, cost: %+v.", req, resp.StatusCode(), resp.Status(), resp, time.Since(start)) + return resp, err + } + // 如果这里返回结构中过多,不进行日志打印。 + if req.PrintLogType != PrintLogTypeDisable { + if req.PrintLogType == PrintLogTypeForce || len(resp.Body()) < MaxPrintLogLength { + logx.CtxInfo(ctx, "HttpResty finish. req: %+v, resp: %+v, cost: %+v.", req, resp, time.Since(start)) + } else { + logx.CtxInfo(ctx, "HttpResty finish. req: %+v, resp: too many resp(not print to log), cost: %+v.", req, time.Since(start)) + } + } + + return resp, nil +} + +func fillResponse(resp *resty.Response) *Response { + response := &Response{} + if resp == nil { + return response + } + response.LogID = resp.Header().Get(HeaderLogIDKey) + response.Header = make(map[string]string) + if token := resp.Header().Get(HeaderJWTTokenKey); len(token) > 0 { + response.Header[HeaderJWTTokenKey] = token + } + return response +} + +func fillTargetBase(ctx context.Context, response *Response, target interface{}) { + defer func() { + if err := recover(); err != nil { + buf := make([]byte, 1<<16) + runtime.Stack(buf, false) + logx.CtxError(ctx, "HttpResty fillTargetBase panic, response: %+v, err:%+v,\n%s", response, err, buf) + } + }() + if target == nil { + return + } + + t := reflect.TypeOf(target) + switch t.Kind() { + case reflect.Ptr: + v := reflect.ValueOf(target) + m := v.MethodByName("SetLogID") + if m.IsValid() { + args := []reflect.Value{reflect.ValueOf(response.LogID)} + m.Call(args) + } + case reflect.Struct: + b, ok := target.(Basic) + if !ok { + return + } + b.LogID = response.LogID + default: + } +} + +func getHeaders(ctx context.Context, headers map[string]string) map[string]string { + newHeaders := make(map[string]string) + for key, value := range headers { + newHeaders[key] = value + } + logID := requestid.GetLogID(ctx) + if len(logID) > 0 { + newHeaders[HeaderLogIDKey] = logID + } + return newHeaders +} diff --git a/pkg/uniqueid/unique.go b/pkg/uniqueid/unique.go new file mode 100644 index 0000000..dad2fb1 --- /dev/null +++ b/pkg/uniqueid/unique.go @@ -0,0 +1,16 @@ +package uniqueid + +import ( + "strings" + "time" + + "github.com/oklog/ulid/v2" +) + +func GetUniqueID() string { + datePart := time.Now().Format("20060102150405") + + machineInfoPart := strings.ToLower(ulid.Make().String()) + + return datePart + "L" + machineInfoPart +} diff --git a/router.go b/router.go new file mode 100644 index 0000000..e55572b --- /dev/null +++ b/router.go @@ -0,0 +1,15 @@ +// Code generated by hertz generator. + +package main + +import ( + handler "gitea.micah.wiki/pandora/starter/biz/handler" + "github.com/cloudwego/hertz/pkg/app/server" +) + +// customizeRegister registers customize routers. +func customizedRegister(r *server.Hertz) { + r.GET("/ping", handler.Ping) + + // your code ... +} diff --git a/router_gen.go b/router_gen.go new file mode 100644 index 0000000..05ee3c1 --- /dev/null +++ b/router_gen.go @@ -0,0 +1,16 @@ +// Code generated by hertz generator. DO NOT EDIT. + +package main + +import ( + router "gitea.micah.wiki/pandora/starter/biz/router" + "github.com/cloudwego/hertz/pkg/app/server" +) + +// register registers all routers. +func register(r *server.Hertz) { + + router.GeneratedRegister(r) + + customizedRegister(r) +} diff --git a/script/bootstrap.sh b/script/bootstrap.sh new file mode 100755 index 0000000..afbc47d --- /dev/null +++ b/script/bootstrap.sh @@ -0,0 +1,5 @@ +#!/bin/bash +CURDIR=$(cd $(dirname $0); pwd) +BinaryName=hertz_service +echo "$CURDIR/bin/${BinaryName}" +exec $CURDIR/bin/${BinaryName} $@ \ No newline at end of file