• 手把手开发Admin 系列三(自定义模板篇)


    文档:https://docs.arklnk.com

    前端:https://github.com/arklnk/ark-admin-vuenext

    后端:https://github.com/arklnk/ark-admin-zero

    go-zero:https://go-zero.dev/cn

    演示: http://arkadmin.si-yee.com

    账号密码备注
    demo123456演示账号

    main

    ark-admin自定义了main模板(位置:dev/goctl/1.4.0/api/main.tpl)

    在main中增加了自定义错误处理

    package main
    
    import (
    	"flag"
    	"fmt"
    	"net/http"
    
        "ark-admin-zero/common/errorx"
    	{{.importPackages}}
    	"github.com/zeromicro/go-zero/rest/httpx"
    )
    
    var configFile = flag.String("f", "etc/{{.serviceName}}.yaml", "the config file")
    
    func main() {
    	flag.Parse()
    
    	var c config.Config
    	conf.MustLoad(*configFile, &c)
    
    	server := rest.MustNewServer(c.RestConf)
    	defer server.Stop()
    
    	ctx := svc.NewServiceContext(c)
    	handler.RegisterHandlers(server, ctx)
    
    	// 自定义错误
    	httpx.SetErrorHandler(func(err error) (int, interface{}) {
            switch e := err.(type) {
            case *errorx.CodeError:
                return http.StatusOK, e.Data()
            default:
                return http.StatusInternalServerError, nil
            }
        })
    
    	fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
    	server.Start()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    handler

    为了引入go-playground/validatoropen,ark-admin自定义了handler(位置:dev/goctl/1.4.0/api/handler.tpl)

    在main中增加了参数校验和中文错误提示

    package {{.PkgName}}
    
    import (
        {{if .HasRequest}}"errors"{{end}}
    	"net/http"
    	{{if .HasRequest}}"reflect"{{end}}
    
        {{if .HasRequest}}"ark-admin-zero/common/errorx"{{end}}
    	"ark-admin-zero/common/response"
    	{{.ImportPackages}}
        {{if .HasRequest}}
        "github.com/go-playground/locales/zh"
        ut "github.com/go-playground/universal-translator"
        "github.com/go-playground/validator/v10"
        translations "github.com/go-playground/validator/v10/translations/zh"{{end}}
        "github.com/zeromicro/go-zero/rest/httpx"
    )
    
    func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc {
    	return func(w http.ResponseWriter, r *http.Request) {
    		{{if .HasRequest}}var req types.{{.RequestType}}
    		if err := httpx.Parse(r, &req); err != nil {
                httpx.Error(w, errorx.NewHandlerError(errorx.ParamErrorCode, err.Error()))
    			return
    		}
    
    		validate := validator.New()
            validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
                name := fld.Tag.Get("label")
                return name
            })
    
            trans, _ := ut.New(zh.New()).GetTranslator("zh")
            validateErr := translations.RegisterDefaultTranslations(validate, trans)
            if validateErr = validate.StructCtx(r.Context(), req); validateErr != nil {
                for _, err := range validateErr.(validator.ValidationErrors) {
                    httpx.Error(w, errorx.NewHandlerError(errorx.ParamErrorCode, errors.New(err.Translate(trans)).Error()))
                    return
                }
            }
    
    		{{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), svcCtx)
    		{{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}&req{{end}})
    		if err != nil {
    			httpx.Error(w, err)
    			return
    		}
    
            {{if .HasResp}}response.Response(w, resp, err){{else}}response.Response(w, nil, err){{end}}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    解析

    由于自定义了goctl模板,所以在使用goctl生成api时,请指定goctl模板路径为:dev/goctl

    例如(在项目根目录下执行)

    goctl api go -api app/core/cmd/api/core.api -dir app/core/cmd/api -home ./dev/goctl
    
    • 1

    自定义main模板后生成的main方法如下

    package main
    
    import (
    	"flag"
    	"fmt"
    	"net/http"
    
    	"ark-admin-zero/app/core/cmd/api/internal/config"
    	"ark-admin-zero/app/core/cmd/api/internal/handler"
    	"ark-admin-zero/app/core/cmd/api/internal/svc"
    	"ark-admin-zero/common/errorx"
    
    	"github.com/zeromicro/go-zero/core/conf"
    	"github.com/zeromicro/go-zero/core/logx"
    	"github.com/zeromicro/go-zero/rest"
    	"github.com/zeromicro/go-zero/rest/httpx"
    )
    
    var configFile = flag.String("f", "etc/core-api.yaml", "the config file")
    
    func main() {
    	flag.Parse()
    
    	var c config.Config
    	conf.MustLoad(*configFile, &c)
    
    	server := rest.MustNewServer(c.RestConf)
    	defer server.Stop()
    
    	ctx := svc.NewServiceContext(c)
    	handler.RegisterHandlers(server, ctx)
    
    	// 自定义错误
    	httpx.SetErrorHandler(func(err error) (int, interface{}) {
    		switch e := err.(type) {
    		case *errorx.CodeError:
    			return http.StatusOK, e.Data()
    		default:
    			return http.StatusInternalServerError, nil
    		}
    	})
    
    	fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
    	server.Start()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    以登录接口为例,自定义handler模板后生成的LoginHandler如下

    package user
    
    import (
    	"errors"
    	"net/http"
    	"reflect"
    
    	"ark-admin-zero/app/core/cmd/api/internal/logic/user"
    	"ark-admin-zero/app/core/cmd/api/internal/svc"
    	"ark-admin-zero/app/core/cmd/api/internal/types"
    	"ark-admin-zero/common/errorx"
    	"ark-admin-zero/common/response"
    
    	"github.com/go-playground/locales/zh"
    	ut "github.com/go-playground/universal-translator"
    	"github.com/go-playground/validator/v10"
    	translations "github.com/go-playground/validator/v10/translations/zh"
    	"github.com/zeromicro/go-zero/rest/httpx"
    )
    
    func LoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
    	return func(w http.ResponseWriter, r *http.Request) {
    		var req types.LoginReq
    		if err := httpx.Parse(r, &req); err != nil {
    			httpx.Error(w, errorx.NewHandlerError(errorx.ParamErrorCode, err.Error()))
    			return
    		}
    
    		validate := validator.New()
    		validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
    			name := fld.Tag.Get("label")
    			return name
    		})
    
    		trans, _ := ut.New(zh.New()).GetTranslator("zh")
    		validateErr := translations.RegisterDefaultTranslations(validate, trans)
    		if validateErr = validate.StructCtx(r.Context(), req); validateErr != nil {
    			for _, err := range validateErr.(validator.ValidationErrors) {
    				httpx.Error(w, errorx.NewHandlerError(errorx.ParamErrorCode, errors.New(err.Translate(trans)).Error()))
    				return
    			}
    		}
    
    		l := user.NewLoginLogic(r.Context(), svcCtx)
    		resp, err := l.Login(&req, r)
    		if err != nil {
    			httpx.Error(w, err)
    			return
    		}
    
    		response.Response(w, resp, err)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
  • 相关阅读:
    jpg怎么转换成png?
    ES6 入门教程 8 函数的扩展 8.2 rest 参数 & 8.3 严格模式
    Unity --- 给物体添加重力
    Flash、eeprom、rom、ram
    C++刷题 -- 二分查找
    前端新宠 Svelte,呜呜,卷不动了
    什么是WPF的值转换器
    云原生-利用容器和编排器
    SNZ资本的首席信息官Gavin确认出席Hack .Summit() 2024香港开发者大会!
    数字化转型孕育而来的在线文档协同工具:Baklib知识库及帮助中心
  • 原文地址:https://blog.csdn.net/lwqBrell/article/details/126622055