package gogen import ( "fmt" "path" "strconv" "strings" "github.com/tal-tech/go-zero/tools/goctl/api/parser/g4/gen/api" "github.com/tal-tech/go-zero/tools/goctl/api/spec" "github.com/tal-tech/go-zero/tools/goctl/config" "github.com/tal-tech/go-zero/tools/goctl/util/format" ctlutil "github.com/tal-tech/go-zero/tools/goctl/util/pathx" "github.com/tal-tech/go-zero/tools/goctl/vars" ) const logicTemplate = `package {{.pkgName}} import ( {{.imports}} ) type {{.logic}} struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func New{{.logic}}(ctx context.Context, svcCtx *svc.ServiceContext) {{.logic}} { return {{.logic}}{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *{{.logic}}) {{.function}}({{.request}}) {{.responseType}} { // todo: add your logic here and delete this line {{.returnString}} } ` func genLogic(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error { for _, g := range api.Service.Groups { for _, r := range g.Routes { err := genLogicByRoute(dir, rootPkg, cfg, g, r) if err != nil { return err } } } return nil } func genLogicByRoute(dir, rootPkg string, cfg *config.Config, group spec.Group, route spec.Route) error { logic := getLogicName(route) goFile, err := format.FileNamingFormat(cfg.NamingFormat, logic) if err != nil { return err } imports := genLogicImports(route, rootPkg) var responseString string var returnString string var requestString string if len(route.ResponseTypeName()) > 0 { resp := responseGoTypeName(route, typesPacket) responseString = "(resp " + resp + ", err error)" returnString = "return" } else { responseString = "error" returnString = "return nil" } if len(route.RequestTypeName()) > 0 { requestString = "req " + requestGoTypeName(route, typesPacket) } subDir := getLogicFolderPath(group, route) return genFile(fileGenConfig{ dir: dir, subdir: subDir, filename: goFile + ".go", templateName: "logicTemplate", category: category, templateFile: logicTemplateFile, builtinTemplate: logicTemplate, data: map[string]string{ "pkgName": subDir[strings.LastIndex(subDir, "/")+1:], "imports": imports, "logic": strings.Title(logic), "function": strings.Title(strings.TrimSuffix(logic, "Logic")), "responseType": responseString, "returnString": returnString, "request": requestString, }, }) } func getLogicFolderPath(group spec.Group, route spec.Route) string { folder := route.GetAnnotation(groupProperty) if len(folder) == 0 { folder = group.GetAnnotation(groupProperty) if len(folder) == 0 { return logicDir } } folder = strings.TrimPrefix(folder, "/") folder = strings.TrimSuffix(folder, "/") return path.Join(logicDir, folder) } func genLogicImports(route spec.Route, parentPkg string) string { var imports []string imports = append(imports, `"context"`+"\n") imports = append(imports, fmt.Sprintf("\"%s\"", ctlutil.JoinPackages(parentPkg, contextDir))) if shallImportTypesPackage(route) { imports = append(imports, fmt.Sprintf("\"%s\"\n", ctlutil.JoinPackages(parentPkg, typesDir))) } imports = append(imports, fmt.Sprintf("\"%s/core/logx\"", vars.ProjectOpenSourceURL)) return strings.Join(imports, "\n\t") } func onlyPrimitiveTypes(val string) bool { fields := strings.FieldsFunc(val, func(r rune) bool { return r == '[' || r == ']' || r == ' ' }) for _, field := range fields { if field == "map" { continue } // ignore array dimension number, like [5]int if _, err := strconv.Atoi(field); err == nil { continue } if !api.IsBasicType(field) { return false } } return true } func shallImportTypesPackage(route spec.Route) bool { if len(route.RequestTypeName()) > 0 { return true } respTypeName := route.ResponseTypeName() if len(respTypeName) == 0 { return false } if onlyPrimitiveTypes(respTypeName) { return false } return true }