├── LICENSE ├── README.md ├── converter └── types.go ├── gen ├── api │ ├── api.go │ ├── createfileapi.go │ ├── delete.go │ ├── findlist.go │ ├── findone.go │ ├── gen.go │ ├── insert.go │ └── update.go ├── http │ ├── createfilehttp.go │ ├── gen.go │ └── httpapi.go └── rpc │ ├── createfilerpc.go │ ├── delete.go │ ├── findlist.go │ ├── findone.go │ ├── gen.go │ ├── insert.go │ ├── rpc.go │ └── update.go ├── go.mod ├── gozc.go ├── image └── img.png ├── model └── sql │ ├── api │ ├── sysadmin.api │ ├── sysadminInfologic.go │ ├── sysadminaddlogic.go │ ├── sysadmindellogic.go │ ├── sysadminlistlogic.go │ └── sysadminuplogic.go │ ├── http │ └── sysadmin.json │ ├── rpc │ ├── sysadmin.proto │ ├── sysadminaddlogic.go │ ├── sysadmindellogic.go │ ├── sysadminfindonelogic.go │ ├── sysadminlistlogic.go │ └── sysadminuplogic.go │ └── sys_admin.sql ├── parser └── parser.go ├── tools ├── pathx │ └── pathx.go └── stringx │ └── stringx.go └── tpl ├── api ├── api.tpl ├── delete.tpl ├── find-list.tpl ├── find-one.tpl ├── insert.tpl └── update.tpl ├── http └── http-api.tpl └── rpc ├── delete.tpl ├── find-list.tpl ├── find-one.tpl ├── insert.tpl ├── rpc.tpl └── update.tpl /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Mikael 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #### 主要用于go-zero代码生成: 2 | NAME: 3 | gozc - go-zero CRUD生成器 4 | 5 | USAGE: 6 | gozc.exe [global options] command [command options] [arguments...] 7 | 8 | VERSION: 9 | 1.0 10 | 11 | COMMANDS: 12 | run Print worker info 13 | help, h Shows a list of commands or help for one command 14 | 15 | GLOBAL OPTIONS: 16 | --help, -h show help (default: false) 17 | --version, -v print the version (default: false) 18 | 19 | #### 如何使用 20 | 21 | 首先需配置环境变量 GOZC_PATH 指向项目中tpl模板文件 22 | 23 | 首页注释为程序入口方式 24 | //os.Args = append(os.Args, "run", "--m=admin", "--sql=E:\\Gopath\\src\\gozc\\model\\sql\\sys_admin.sql") 25 | 26 | 如何使用 27 | gozc run --m=服务名称 --sql=sql文件路径 可写运行目录加文件./ 或者.\ 28 | 29 | 生成后目录为图 30 | 31 | ![img.png](image/img.png) 32 | 33 | CRUD 个人架构主观性比较强 这边建议自行修改适配现有项目 34 | 35 | api为API文件 为api go-zero的api文件 和对应sql的 CRUD方法 36 | 37 | http为 OpenAPI/Swagger 文件用于导入 apifox 或者其他软件 38 | 39 | rpc为rpc文件 为rpc go-zero的 rcp文件 和对应的sql的 CRUD方法 编写包应用 40 | "github.com/Masterminds/squirrel" 41 | "github.com/zeromicro/go-zero/core/stores/builder" 42 | "github.com/zeromicro/go-zero/core/stores/cache" 43 | "github.com/zeromicro/go-zero/core/stores/sqlc" 44 | "github.com/zeromicro/go-zero/core/stores/sqlx" 45 | 46 | 用于list方法生成 CRUD内容大部分偏向主观 请自行选择或者修改 47 | 48 | 工具类编写的稍微有点快没那么规范,所以重复的地方可能稍微有点多,功能写的不是那么通用。毕竟我比较笨 49 | 50 | 如果感觉对你有帮助记得给一个start 这个项目肯定会提高你的生产力。 51 | 52 | ps:但是发明了一个更好的工具效率提高了,但是对项目是否有帮助和对人的影响请自行考虑。(有利有弊) 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /converter/types.go: -------------------------------------------------------------------------------- 1 | package converter 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/zeromicro/ddl-parser/parser" 8 | ) 9 | 10 | var unsignedTypeMap = map[string]string{ 11 | "int": "uint", 12 | "int8": "uint8", 13 | "int16": "uint16", 14 | "in32t": "uint32", 15 | "int64": "uint64", 16 | } 17 | 18 | var commonMysqlDataTypeMapInt = map[int]string{ 19 | // For consistency, all integer types are converted to int64 20 | // number 21 | parser.Bit: "byte", 22 | parser.TinyInt: "int64", 23 | parser.SmallInt: "int64", 24 | parser.MediumInt: "int64", 25 | parser.Int: "int64", 26 | parser.MiddleInt: "int64", 27 | parser.Int1: "int64", 28 | parser.Int2: "int64", 29 | parser.Int3: "int64", 30 | parser.Int4: "int64", 31 | parser.Int8: "int64", 32 | parser.Integer: "int64", 33 | parser.BigInt: "int64", 34 | parser.Float: "float64", 35 | parser.Float4: "float64", 36 | parser.Float8: "float64", 37 | parser.Double: "float64", 38 | parser.Decimal: "float64", 39 | parser.Dec: "float64", 40 | parser.Fixed: "float64", 41 | parser.Numeric: "float64", 42 | parser.Real: "float64", 43 | // date&time 44 | parser.Date: "time.Time", 45 | parser.DateTime: "time.Time", 46 | parser.Timestamp: "time.Time", 47 | parser.Time: "string", 48 | parser.Year: "int64", 49 | // string 50 | parser.Char: "string", 51 | parser.VarChar: "string", 52 | parser.NVarChar: "string", 53 | parser.NChar: "string", 54 | parser.Character: "string", 55 | parser.LongVarChar: "string", 56 | parser.LineString: "string", 57 | parser.MultiLineString: "string", 58 | parser.Binary: "string", 59 | parser.VarBinary: "string", 60 | parser.TinyText: "string", 61 | parser.Text: "string", 62 | parser.MediumText: "string", 63 | parser.LongText: "string", 64 | parser.Enum: "string", 65 | parser.Set: "string", 66 | parser.Json: "string", 67 | parser.Blob: "string", 68 | parser.LongBlob: "string", 69 | parser.MediumBlob: "string", 70 | parser.TinyBlob: "string", 71 | // bool 72 | parser.Bool: "bool", 73 | parser.Boolean: "bool", 74 | } 75 | 76 | var commonMysqlDataTypeMapString = map[string]string{ 77 | // For consistency, all integer types are converted to int64 78 | // bool 79 | "bool": "bool", 80 | "boolean": "bool", 81 | // number 82 | "tinyint": "int64", 83 | "smallint": "int64", 84 | "mediumint": "int64", 85 | "int": "int64", 86 | "int1": "int64", 87 | "int2": "int64", 88 | "int3": "int64", 89 | "int4": "int64", 90 | "int8": "int64", 91 | "integer": "int64", 92 | "bigint": "int64", 93 | "float": "float64", 94 | "float4": "float64", 95 | "float8": "float64", 96 | "double": "float64", 97 | "decimal": "float64", 98 | "dec": "float64", 99 | "fixed": "float64", 100 | "real": "float64", 101 | "bit": "byte", 102 | // date & time 103 | "date": "time.Time", 104 | "datetime": "time.Time", 105 | "timestamp": "time.Time", 106 | "time": "string", 107 | "year": "int64", 108 | // string 109 | "linestring": "string", 110 | "multilinestring": "string", 111 | "nvarchar": "string", 112 | "nchar": "string", 113 | "char": "string", 114 | "character": "string", 115 | "varchar": "string", 116 | "binary": "string", 117 | "bytea": "string", 118 | "longvarbinary": "string", 119 | "varbinary": "string", 120 | "tinytext": "string", 121 | "text": "string", 122 | "mediumtext": "string", 123 | "longtext": "string", 124 | "enum": "string", 125 | "set": "string", 126 | "json": "string", 127 | "jsonb": "string", 128 | "blob": "string", 129 | "longblob": "string", 130 | "mediumblob": "string", 131 | "tinyblob": "string", 132 | } 133 | 134 | // ConvertDataType converts mysql column type into golang type 135 | func ConvertDataType(dataBaseType int, isDefaultNull, unsigned bool) (string, error) { 136 | tp, ok := commonMysqlDataTypeMapInt[dataBaseType] 137 | if !ok { 138 | return "", fmt.Errorf("unsupported database type: %v", dataBaseType) 139 | } 140 | 141 | return mayConvertNullType(tp, isDefaultNull, unsigned), nil 142 | } 143 | 144 | // ConvertStringDataType converts mysql column type into golang type 145 | func ConvertStringDataType(dataBaseType string, isDefaultNull, unsigned bool) (string, error) { 146 | tp, ok := commonMysqlDataTypeMapString[strings.ToLower(dataBaseType)] 147 | if !ok { 148 | return "", fmt.Errorf("unsupported database type: %s", dataBaseType) 149 | } 150 | 151 | return mayConvertNullType(tp, isDefaultNull, unsigned), nil 152 | } 153 | 154 | func mayConvertNullType(goDataType string, isDefaultNull, unsigned bool) string { 155 | if !isDefaultNull { 156 | if unsigned { 157 | ret, ok := unsignedTypeMap[goDataType] 158 | if ok { 159 | return ret 160 | } 161 | } 162 | return goDataType 163 | } 164 | 165 | switch goDataType { 166 | case "int64": 167 | return "sql.NullInt64" 168 | case "int32": 169 | return "sql.NullInt32" 170 | case "float64": 171 | return "sql.NullFloat64" 172 | case "bool": 173 | return "sql.NullBool" 174 | case "string": 175 | return "sql.NullString" 176 | case "time.Time": 177 | return "sql.NullTime" 178 | default: 179 | if unsigned { 180 | ret, ok := unsignedTypeMap[goDataType] 181 | if ok { 182 | return ret 183 | } 184 | } 185 | return goDataType 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /gen/api/api.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | "strings" 9 | ) 10 | 11 | func genApi(table Table, pkgName stringx.String) (string, error) { 12 | 13 | camel := table.Name.ToCamel() 14 | xcamel := table.Name.ToCamelWithStartLower() 15 | 16 | var modelname = pkgName.Lower() 17 | var amodelname = pkgName.ToCamel() 18 | 19 | add := GetApiData(table, insertTemplateFile) 20 | del := GetApiData(table, deleteTemplateFile) 21 | up := GetApiData(table, updateTemplateFile) 22 | list := GetApiData(table, findListTemplateFile) 23 | info := GetApiData(table, findOneTemplateFile) 24 | 25 | text, err := pathx.LoadTemplate(category, apiTemplateFile, "") 26 | if err != nil { 27 | return "", err 28 | } 29 | 30 | output, err := util.With("api"). 31 | Parse(text). 32 | Execute(map[string]interface{}{ 33 | "filename": camel, 34 | "xfilename": xcamel, 35 | "modelname": modelname, 36 | "Amodelname": amodelname, 37 | "Add": add, 38 | "Del": del, 39 | "Up": up, 40 | "List": list, 41 | "Info": info, 42 | }) 43 | if err != nil { 44 | return "", err 45 | } 46 | 47 | return output.String(), nil 48 | } 49 | 50 | func GetApiData(table Table, dataType string) string { 51 | modeldatas := make([]string, 0) 52 | var initmodel string 53 | var reqType = "json" 54 | var reqTypeData string 55 | var reqTypeDataInt string 56 | if dataType == findListTemplateFile { 57 | //添加分页 58 | initmodel = fmt.Sprintf("%s %s `form:\"%s\"` // %s", "Current", "int64", "current,default=1,optional", "页码") 59 | modeldatas = append(modeldatas, initmodel) 60 | initmodel = fmt.Sprintf("%s %s `form:\"%s\"` // %s", "PageSize", "int64", "page_size,default=10,optional", "页数") 61 | modeldatas = append(modeldatas, initmodel) 62 | reqType = "form" 63 | } 64 | if dataType == deleteTemplateFile { 65 | reqType = "path" 66 | } 67 | if dataType == findOneTemplateFile { 68 | reqType = "form" 69 | } 70 | 71 | for _, field := range table.Fields { 72 | camel := util.SafeString(field.Name.ToCamel()) 73 | switch dataType { 74 | case findListTemplateFile: 75 | if camel == "Id" || camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || 76 | camel == "CreatedName" || camel == "UpdatedName" || camel == "DeletedName" || camel == "TenantId" || camel == "Sort" { 77 | continue 78 | } 79 | reqTypeData = field.Name.Source() + ",optional" 80 | reqTypeDataInt = field.Name.Source() + ",default=99,optional" 81 | case insertTemplateFile: 82 | if camel == "Id" || camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || 83 | camel == "CreatedName" || camel == "UpdatedName" || camel == "DeletedName" || camel == "TenantId" { 84 | continue 85 | } 86 | reqTypeData = field.Name.Source() + ",optional" 87 | reqTypeDataInt = field.Name.Source() + ",optional" 88 | case deleteTemplateFile: 89 | if camel != "Id" { 90 | continue 91 | } 92 | reqTypeData = field.Name.Source() 93 | reqTypeDataInt = field.Name.Source() 94 | 95 | case updateTemplateFile: 96 | if camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || 97 | camel == "CreatedName" || camel == "UpdatedName" || camel == "DeletedName" || camel == "TenantId" { 98 | continue 99 | } 100 | if camel != "Id" { 101 | reqTypeData = field.Name.Source() + ",optional" 102 | reqTypeDataInt = field.Name.Source() + ",optional" 103 | } else { 104 | reqTypeData = field.Name.Source() 105 | reqTypeDataInt = field.Name.Source() 106 | } 107 | case findOneTemplateFile: 108 | if camel != "Id" { 109 | continue 110 | } 111 | reqTypeData = field.Name.Source() 112 | reqTypeDataInt = field.Name.Source() 113 | } 114 | var model string 115 | switch camel { 116 | case "TenantId": 117 | continue 118 | default: 119 | switch field.DataType { 120 | case "sql.NullString": 121 | model = fmt.Sprintf("%s %s `%s:\"%s\"` // %s", camel, "string", reqType, reqTypeData, field.Comment) 122 | case "string": 123 | model = fmt.Sprintf("%s %s `%s:\"%s\"` // %s", camel, "string", reqType, reqTypeData, field.Comment) 124 | case "sql.NullTime": 125 | model = fmt.Sprintf("%s %s `%s:\"%s\"` // %s", camel, "int64", reqType, reqTypeData, field.Comment) 126 | case "time.Time": 127 | model = fmt.Sprintf("%s %s `%s:\"%s\"` // %s", camel, "int64", reqType, reqTypeData, field.Comment) 128 | case "sql.NullInt64": 129 | model = fmt.Sprintf("%s %s `%s:\"%s\"` // %s", camel, "int64", reqType, reqTypeDataInt, field.Comment) 130 | case "sql.NullInt32": 131 | model = fmt.Sprintf("%s %s `%s:\"%s\"` // %s", camel, "int64", reqType, reqTypeDataInt, field.Comment) 132 | case "int64": 133 | model = fmt.Sprintf("%s %s `%s:\"%s\"` // %s", camel, "int64", reqType, reqTypeDataInt, field.Comment) 134 | case "int32": 135 | model = fmt.Sprintf("%s %s `%s:\"%s\"` // %s", camel, "int64", reqType, reqTypeDataInt, field.Comment) 136 | case "float64": 137 | model = fmt.Sprintf("%s %s `%s:\"%s\"` // %s", camel, "float64", reqType, reqTypeData, field.Comment) 138 | case "float32": 139 | model = fmt.Sprintf("%s %s `%s:\"%s\"` // %s", camel, "float32", reqType, reqTypeData, field.Comment) 140 | case "NullFloat32": 141 | model = fmt.Sprintf("%s %s `%s:\"%s\"` // %s", camel, "float32", reqType, reqTypeData, field.Comment) 142 | case "NullFloat64": 143 | model = fmt.Sprintf("%s %s `%s:\"%s\"` // %s", camel, "float64", reqType, reqTypeData, field.Comment) 144 | default: 145 | continue 146 | } 147 | } 148 | modeldatas = append(modeldatas, model) 149 | 150 | } 151 | modeldata := strings.Join(modeldatas, "\n\t\t") 152 | return modeldata 153 | 154 | } 155 | -------------------------------------------------------------------------------- /gen/api/createfileapi.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "path/filepath" 8 | "strings" 9 | ) 10 | 11 | func CreateFileApi(modelList map[string]*CodeTuple, srcPath string) error { 12 | 13 | dirAbs := filepath.Dir(srcPath) 14 | 15 | dirAbs = filepath.Join(dirAbs, "api") 16 | 17 | is, _ := IsPathExist(dirAbs) 18 | if is == false { 19 | err := os.Mkdir(dirAbs, os.ModePerm) 20 | if err != nil { 21 | return err 22 | } 23 | } 24 | 25 | for tableName, codes := range modelList { 26 | 27 | name := fmt.Sprintf("%v.api", SafeString(tableName)) 28 | filename := filepath.Join(dirAbs, name) 29 | err := ioutil.WriteFile(filename, []byte(codes.Api), os.ModePerm) 30 | if err != nil { 31 | return err 32 | } 33 | 34 | name = fmt.Sprintf("%vaddlogic.go", SafeString(tableName)) 35 | filename = filepath.Join(dirAbs, name) 36 | err = ioutil.WriteFile(filename, []byte(codes.ApiInsert), os.ModePerm) 37 | if err != nil { 38 | return err 39 | } 40 | 41 | name = fmt.Sprintf("%vdellogic.go", SafeString(tableName)) 42 | filename = filepath.Join(dirAbs, name) 43 | err = ioutil.WriteFile(filename, []byte(codes.ApiDelete), os.ModePerm) 44 | if err != nil { 45 | return err 46 | } 47 | 48 | name = fmt.Sprintf("%vuplogic.go", SafeString(tableName)) 49 | filename = filepath.Join(dirAbs, name) 50 | err = ioutil.WriteFile(filename, []byte(codes.ApiUpdate), os.ModePerm) 51 | if err != nil { 52 | return err 53 | } 54 | 55 | name = fmt.Sprintf("%vInfologic.go", SafeString(tableName)) 56 | filename = filepath.Join(dirAbs, name) 57 | err = ioutil.WriteFile(filename, []byte(codes.ApiFindOne), os.ModePerm) 58 | if err != nil { 59 | return err 60 | } 61 | 62 | name = fmt.Sprintf("%vlistlogic.go", SafeString(tableName)) 63 | filename = filepath.Join(dirAbs, name) 64 | err = ioutil.WriteFile(filename, []byte(codes.ApiFindList), os.ModePerm) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | fmt.Println("ApiDone.") 70 | return nil 71 | } 72 | 73 | // SafeString converts the input string into a safe naming style in golang 74 | func SafeString(in string) string { 75 | if len(in) == 0 { 76 | return in 77 | } 78 | if strings.Contains(in, "_") { 79 | in = strings.Replace(in, "_", "", -1) 80 | } 81 | return in 82 | } 83 | 84 | func IsPathExist(path string) (bool, error) { 85 | _, err := os.Stat(path) 86 | if err == nil { 87 | return true, nil 88 | } 89 | if os.IsNotExist(err) { 90 | return false, nil 91 | } 92 | return false, err 93 | } 94 | -------------------------------------------------------------------------------- /gen/api/delete.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | "strings" 9 | ) 10 | 11 | func genDelete(table Table, modelName stringx.String) (string, error) { 12 | datas := make([]string, 0) 13 | for _, field := range table.Fields { 14 | camel := util.SafeString(field.Name.ToCamel()) 15 | if camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || camel == "CreatedName" || camel == "UpdatedName" { 16 | continue 17 | } 18 | var model string 19 | switch camel { 20 | case "DeletedName": 21 | model = fmt.Sprintf("%s:\t tokenData.%s, // %s", camel, "NickName", field.Comment) 22 | case "TenantId": 23 | model = fmt.Sprintf("%s:\t tokenData.%s, // %s", camel, camel, field.Comment) 24 | case "Id": 25 | model = fmt.Sprintf("%s:\t req.%s, // %s", camel, camel, field.Comment) 26 | default: 27 | continue 28 | } 29 | datas = append(datas, model) 30 | } 31 | 32 | data := strings.Join(datas, "\n\t\t") 33 | camel := table.Name.ToCamel() 34 | amodelname := modelName.ToCamel() 35 | xmodelname := modelName.Lower() 36 | text, err := pathx.LoadTemplate(category, deleteTemplateFile, "") 37 | if err != nil { 38 | return "", err 39 | } 40 | output, err := util.With("delete"). 41 | Parse(text). 42 | Execute(map[string]interface{}{ 43 | "filename": camel, 44 | "modelname": amodelname, 45 | "xmodelname": xmodelname, 46 | "data": data, 47 | }) 48 | if err != nil { 49 | return "", err 50 | } 51 | 52 | return output.String(), nil 53 | } 54 | -------------------------------------------------------------------------------- /gen/api/findlist.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | "strings" 9 | ) 10 | 11 | func genFindList(table Table, modelName stringx.String) (string, error) { 12 | datas := make([]string, 0) 13 | modeldatas := make([]string, 0) 14 | var initmodel string 15 | 16 | //添加分页 17 | initmodel = fmt.Sprintf("%s:\t req.%s, // %s", "Current", "Current", "页码") 18 | datas = append(datas, initmodel) 19 | initmodel = fmt.Sprintf("%s:\t req.%s, // %s", "PageSize", "PageSize", "页数") 20 | datas = append(datas, initmodel) 21 | 22 | for _, field := range table.Fields { 23 | camel := util.SafeString(field.Name.ToCamel()) 24 | if camel == "Id" || camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || camel == "CreatedName" || camel == "UpdatedName" || camel == "DeletedName" { 25 | continue 26 | } 27 | var model string 28 | switch camel { 29 | case "TenantId": 30 | model = fmt.Sprintf("%s:\t tokenData.%s, // %s", camel, camel, field.Comment) 31 | default: 32 | model = fmt.Sprintf("%s:\t req.%s, // %s", camel, camel, field.Comment) 33 | } 34 | datas = append(datas, model) 35 | } 36 | 37 | for _, field := range table.Fields { 38 | camel := util.SafeString(field.Name.ToCamel()) 39 | if camel == "DeletedAt" || camel == "DeletedName" || camel == "Sort" { 40 | continue 41 | } 42 | var model string 43 | switch camel { 44 | case "TenantId": 45 | continue 46 | default: 47 | switch field.DataType { 48 | case "sql.NullString": 49 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "string", field.Name.Source(), field.Comment) 50 | case "string": 51 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "string", field.Name.Source(), field.Comment) 52 | case "sql.NullTime": 53 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "int64", field.Name.Source(), field.Comment) 54 | case "time.Time": 55 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "int64", field.Name.Source(), field.Comment) 56 | case "sql.NullInt64": 57 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "int64", field.Name.Source(), field.Comment) 58 | case "sql.NullInt32": 59 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "int64", field.Name.Source(), field.Comment) 60 | case "int64": 61 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "int64", field.Name.Source(), field.Comment) 62 | case "int32": 63 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "int64", field.Name.Source(), field.Comment) 64 | case "float64": 65 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "float64", field.Name.Source(), field.Comment) 66 | case "float32": 67 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "float32", field.Name.Source(), field.Comment) 68 | case "NullFloat32": 69 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "float32", field.Name.Source(), field.Comment) 70 | case "NullFloat64": 71 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "float64", field.Name.Source(), field.Comment) 72 | default: 73 | continue 74 | } 75 | } 76 | modeldatas = append(modeldatas, model) 77 | } 78 | 79 | data := strings.Join(datas, "\n\t\t") 80 | modeldata := strings.Join(modeldatas, ",\n\t") 81 | camel := table.Name.ToCamel() 82 | amodelname := modelName.ToCamel() 83 | xmodelname := modelName.Lower() 84 | text, err := pathx.LoadTemplate(category, findListTemplateFile, "") 85 | if err != nil { 86 | return "", err 87 | } 88 | output, err := util.With("findList"). 89 | Parse(text). 90 | Execute(map[string]interface{}{ 91 | "filename": camel, 92 | "modelname": amodelname, 93 | "xmodelname": xmodelname, 94 | "data": data, 95 | "modeldata": modeldata, 96 | }) 97 | if err != nil { 98 | return "", err 99 | } 100 | 101 | return output.String(), nil 102 | } 103 | -------------------------------------------------------------------------------- /gen/api/findone.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | "strings" 9 | ) 10 | 11 | func genFindOne(table Table, modelName stringx.String) (string, error) { 12 | datas := make([]string, 0) 13 | modeldatas := make([]string, 0) 14 | for _, field := range table.Fields { 15 | camel := util.SafeString(field.Name.ToCamel()) 16 | var model string 17 | switch camel { 18 | case "TenantId": 19 | model = fmt.Sprintf("%s:\t tokenData.%s, // %s", camel, camel, field.Comment) 20 | case "Id": 21 | model = fmt.Sprintf("%s:\t req.%s, // %s", camel, camel, field.Comment) 22 | default: 23 | continue 24 | } 25 | datas = append(datas, model) 26 | } 27 | 28 | for _, field := range table.Fields { 29 | camel := util.SafeString(field.Name.ToCamel()) 30 | if camel == "DeletedAt" || camel == "DeletedName" { 31 | continue 32 | } 33 | var model string 34 | switch camel { 35 | case "TenantId": 36 | continue 37 | default: 38 | switch field.DataType { 39 | case "sql.NullString": 40 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "string", field.Name.Source(), field.Comment) 41 | case "string": 42 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "string", field.Name.Source(), field.Comment) 43 | case "sql.NullTime": 44 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "int64", field.Name.Source(), field.Comment) 45 | case "time.Time": 46 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "int64", field.Name.Source(), field.Comment) 47 | case "sql.NullInt64": 48 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "int64", field.Name.Source(), field.Comment) 49 | case "sql.NullInt32": 50 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "int64", field.Name.Source(), field.Comment) 51 | case "int64": 52 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "int64", field.Name.Source(), field.Comment) 53 | case "int32": 54 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "int64", field.Name.Source(), field.Comment) 55 | case "float64": 56 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "float64", field.Name.Source(), field.Comment) 57 | case "float32": 58 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "float32", field.Name.Source(), field.Comment) 59 | case "NullFloat32": 60 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "float32", field.Name.Source(), field.Comment) 61 | case "NullFloat64": 62 | model = fmt.Sprintf("%s %s `json:\"%s\"` // %s", camel, "float64", field.Name.Source(), field.Comment) 63 | default: 64 | continue 65 | } 66 | } 67 | modeldatas = append(modeldatas, model) 68 | 69 | } 70 | 71 | data := strings.Join(datas, "\n\t\t") 72 | modeldata := strings.Join(modeldatas, ",\n\t") 73 | camel := table.Name.ToCamel() 74 | amodelname := modelName.ToCamel() 75 | xmodelname := modelName.Lower() 76 | text, err := pathx.LoadTemplate(category, findOneTemplateFile, "") 77 | if err != nil { 78 | return "", err 79 | } 80 | output, err := util.With("findOne"). 81 | Parse(text). 82 | Execute(map[string]interface{}{ 83 | "filename": camel, 84 | "modelname": amodelname, 85 | "xmodelname": xmodelname, 86 | "data": data, 87 | "modeldata": modeldata, 88 | }) 89 | if err != nil { 90 | return "", err 91 | } 92 | 93 | return output.String(), nil 94 | } 95 | -------------------------------------------------------------------------------- /gen/api/gen.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "fmt" 5 | "gozc/parser" 6 | "gozc/tools/stringx" 7 | ) 8 | 9 | type Table struct { 10 | parser.Table 11 | } 12 | 13 | type ( 14 | CodeTuple struct { 15 | Api string 16 | ApiInsert string 17 | ApiDelete string 18 | ApiUpdate string 19 | ApiFindOne string 20 | ApiFindList string 21 | } 22 | ) 23 | 24 | const ( 25 | category = "api" 26 | apiTemplateFile = "api.tpl" 27 | insertTemplateFile = "insert.tpl" 28 | deleteTemplateFile = "delete.tpl" 29 | updateTemplateFile = "update.tpl" 30 | findOneTemplateFile = "find-one.tpl" 31 | findListTemplateFile = "find-list.tpl" 32 | ) 33 | 34 | func GenApiModel(in parser.Table, pkgName string, apiType string) (string, error) { 35 | if len(in.PrimaryKey.Name.Source()) == 0 { 36 | return "", fmt.Errorf("table %s: missing primary key", in.Name.Source()) 37 | } 38 | var table Table 39 | table.Table = in 40 | 41 | var modelName stringx.String 42 | modelName = stringx.From(pkgName) 43 | 44 | switch apiType { 45 | case "api": 46 | res, err := genApi(table, modelName) 47 | if err != nil { 48 | return "", err 49 | } 50 | return res, nil 51 | case "Insert": 52 | res, err := genInsert(table, modelName) 53 | if err != nil { 54 | return "", err 55 | } 56 | return res, nil 57 | case "delete": 58 | res, err := genDelete(table, modelName) 59 | if err != nil { 60 | return "", err 61 | } 62 | return res, nil 63 | case "update": 64 | res, err := genUpdate(table, modelName) 65 | if err != nil { 66 | return "", err 67 | } 68 | return res, nil 69 | case "findOne": 70 | res, err := genFindOne(table, modelName) 71 | if err != nil { 72 | return "", err 73 | } 74 | return res, nil 75 | case "findList": 76 | res, err := genFindList(table, modelName) 77 | if err != nil { 78 | return "", err 79 | } 80 | return res, nil 81 | } 82 | return "", nil 83 | } 84 | -------------------------------------------------------------------------------- /gen/api/insert.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | "strings" 9 | ) 10 | 11 | func genInsert(table Table, modelName stringx.String) (string, error) { 12 | datas := make([]string, 0) 13 | for _, field := range table.Fields { 14 | camel := util.SafeString(field.Name.ToCamel()) 15 | if camel == "Id" || camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || camel == "UpdatedName" || camel == "DeletedName" { 16 | continue 17 | } 18 | var model string 19 | switch camel { 20 | case "CreatedName": 21 | model = fmt.Sprintf("%s:\t tokenData.%s, // %s", camel, "NickName", field.Comment) 22 | case "TenantId": 23 | model = fmt.Sprintf("%s:\t tokenData.%s, // %s", camel, camel, field.Comment) 24 | default: 25 | model = fmt.Sprintf("%s:\t req.%s, // %s", camel, camel, field.Comment) 26 | } 27 | datas = append(datas, model) 28 | } 29 | data := strings.Join(datas, "\n\t\t") 30 | camel := table.Name.ToCamel() 31 | amodelname := modelName.ToCamel() 32 | xmodelname := modelName.Lower() 33 | 34 | text, err := pathx.LoadTemplate(category, insertTemplateFile, "") 35 | if err != nil { 36 | return "", err 37 | } 38 | output, err := util.With("insert"). 39 | Parse(text). 40 | Execute(map[string]interface{}{ 41 | "filename": camel, 42 | "modelname": amodelname, 43 | "xmodelname": xmodelname, 44 | "data": data, 45 | }) 46 | if err != nil { 47 | return "", err 48 | } 49 | 50 | return output.String(), nil 51 | } 52 | -------------------------------------------------------------------------------- /gen/api/update.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | "strings" 9 | ) 10 | 11 | func genUpdate(table Table, modelName stringx.String) (string, error) { 12 | datas := make([]string, 0) 13 | for _, field := range table.Fields { 14 | camel := util.SafeString(field.Name.ToCamel()) 15 | if camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || camel == "CreatedName" || camel == "DeletedName" { 16 | continue 17 | } 18 | var model string 19 | switch camel { 20 | case "UpdatedName": 21 | model = fmt.Sprintf("%s:\t tokenData.%s, // %s", camel, "NickName", field.Comment) 22 | case "TenantId": 23 | model = fmt.Sprintf("%s:\t tokenData.%s, // %s", camel, camel, field.Comment) 24 | default: 25 | model = fmt.Sprintf("%s:\t req.%s, // %s", camel, camel, field.Comment) 26 | } 27 | datas = append(datas, model) 28 | } 29 | data := strings.Join(datas, "\n\t\t") 30 | camel := table.Name.ToCamel() 31 | amodelname := modelName.ToCamel() 32 | xmodelname := modelName.Lower() 33 | text, err := pathx.LoadTemplate(category, updateTemplateFile, "") 34 | if err != nil { 35 | return "", err 36 | } 37 | output, err := util.With("update"). 38 | Parse(text). 39 | Execute(map[string]interface{}{ 40 | "filename": camel, 41 | "modelname": amodelname, 42 | "xmodelname": xmodelname, 43 | "data": data, 44 | }) 45 | if err != nil { 46 | return "", err 47 | } 48 | 49 | return output.String(), nil 50 | } 51 | -------------------------------------------------------------------------------- /gen/http/createfilehttp.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "path/filepath" 8 | "strings" 9 | ) 10 | 11 | func CreateFileHttp(modelList map[string]*CodeTuple, srcPath string) error { 12 | 13 | dirAbs := filepath.Dir(srcPath) 14 | 15 | dirAbs = filepath.Join(dirAbs, "http") 16 | 17 | is, _ := IsPathExist(dirAbs) 18 | if is == false { 19 | err := os.Mkdir(dirAbs, os.ModePerm) 20 | if err != nil { 21 | return err 22 | } 23 | } 24 | 25 | for tableName, codes := range modelList { 26 | 27 | name := fmt.Sprintf("%v.json", SafeString(tableName)) 28 | filename := filepath.Join(dirAbs, name) 29 | err := ioutil.WriteFile(filename, []byte(codes.Api), os.ModePerm) 30 | if err != nil { 31 | return err 32 | } 33 | 34 | } 35 | fmt.Println("HttpDone.") 36 | return nil 37 | } 38 | 39 | // SafeString converts the input string into a safe naming style in golang 40 | func SafeString(in string) string { 41 | if len(in) == 0 { 42 | return in 43 | } 44 | if strings.Contains(in, "_") { 45 | in = strings.Replace(in, "_", "", -1) 46 | } 47 | return in 48 | } 49 | 50 | func IsPathExist(path string) (bool, error) { 51 | _, err := os.Stat(path) 52 | if err == nil { 53 | return true, nil 54 | } 55 | if os.IsNotExist(err) { 56 | return false, nil 57 | } 58 | return false, err 59 | } 60 | -------------------------------------------------------------------------------- /gen/http/gen.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "fmt" 5 | "gozc/parser" 6 | "gozc/tools/stringx" 7 | ) 8 | 9 | type Table struct { 10 | parser.Table 11 | } 12 | 13 | type ( 14 | CodeTuple struct { 15 | Api string 16 | } 17 | ) 18 | 19 | const ( 20 | category = "Http" 21 | apiTemplateFile = "http-api.tpl" 22 | ) 23 | 24 | func GenHttpModel(in parser.Table, pkgName string, apiType string) (string, error) { 25 | if len(in.PrimaryKey.Name.Source()) == 0 { 26 | return "", fmt.Errorf("table %s: missing primary key", in.Name.Source()) 27 | } 28 | var table Table 29 | table.Table = in 30 | var modelName stringx.String 31 | modelName = stringx.From(pkgName) 32 | 33 | switch apiType { 34 | case "http-api": 35 | res, err := genHttpApi(table, modelName) 36 | if err != nil { 37 | return "", err 38 | } 39 | return res, nil 40 | 41 | } 42 | return "", nil 43 | 44 | } 45 | -------------------------------------------------------------------------------- /gen/http/httpapi.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | "strings" 9 | ) 10 | 11 | func genHttpApi(table Table, pkgName stringx.String) (string, error) { 12 | 13 | xcamel := table.Name.ToCamelWithStartLower() 14 | var modelname = pkgName.Lower() 15 | var idType, idCommand string 16 | for _, field := range table.Fields { 17 | camel := util.SafeString(field.Name.ToCamel()) 18 | if camel != "Id" { 19 | continue 20 | } 21 | idType = field.DataType 22 | idCommand = field.Comment 23 | } 24 | text, err := pathx.LoadTemplate(category, apiTemplateFile, "") 25 | if err != nil { 26 | return "", err 27 | } 28 | 29 | add := GetHttpData(table, "add") 30 | update := GetHttpData(table, "update") 31 | 32 | query := GetHttpQueryData(table) 33 | output, err := util.With("http-api"). 34 | Parse(text). 35 | Execute(map[string]interface{}{ 36 | "modelname": modelname, 37 | "xfilename": xcamel, 38 | "idCommand": idCommand, 39 | "idType": idType, 40 | "Add": add, 41 | "Update": update, 42 | "Query": query, 43 | }) 44 | if err != nil { 45 | return "", err 46 | } 47 | 48 | return output.String(), nil 49 | } 50 | 51 | func GetHttpData(table Table, dataType string) string { 52 | modeldatas := make([]string, 0) 53 | 54 | for _, field := range table.Fields { 55 | camel := util.SafeString(field.Name.ToCamel()) 56 | xcamel := util.SafeString(field.Name.Lower()) 57 | switch dataType { 58 | case "add": 59 | if camel == "Id" || camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || 60 | camel == "CreatedName" || camel == "UpdatedName" || camel == "DeletedName" || camel == "TenantId" { 61 | continue 62 | } 63 | case "Id": 64 | if camel != "Id" { 65 | continue 66 | } 67 | model := fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "string", field.Comment) 68 | modeldatas = append(modeldatas, model) 69 | modeldata := strings.Join(modeldatas, ",\n\t\t\t\t") 70 | return modeldata 71 | case "update": 72 | if camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || 73 | camel == "CreatedName" || camel == "UpdatedName" || camel == "DeletedName" || camel == "TenantId" { 74 | continue 75 | } 76 | default: 77 | continue 78 | } 79 | var model string 80 | switch camel { 81 | case "TenantId": 82 | continue 83 | default: 84 | switch field.DataType { 85 | case "sql.NullString": 86 | model = fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "string", field.Comment) 87 | case "string": 88 | model = fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "string", field.Comment) 89 | case "sql.NullTime": 90 | model = fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "integer", field.Comment) 91 | case "time.Time": 92 | model = fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "integer", field.Comment) 93 | case "sql.NullInt64": 94 | model = fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "integer", field.Comment) 95 | case "sql.NullInt32": 96 | model = fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "integer", field.Comment) 97 | case "int64": 98 | model = fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "integer", field.Comment) 99 | case "int32": 100 | model = fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "integer", field.Comment) 101 | case "float64": 102 | model = fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "number", field.Comment) 103 | case "float32": 104 | model = fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "number", field.Comment) 105 | case "NullFloat32": 106 | model = fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "number", field.Comment) 107 | case "NullFloat64": 108 | model = fmt.Sprintf(" \"%s\": {\n\t\t\t\t\t\"type\": \"%s\",\n\t\t\t\t\t\"description\": \"%s\"\n\t\t\t\t }", xcamel, "number", field.Comment) 109 | default: 110 | continue 111 | } 112 | } 113 | modeldatas = append(modeldatas, model) 114 | 115 | } 116 | modeldata := strings.Join(modeldatas, ",\n\t\t\t\t") 117 | return modeldata 118 | 119 | } 120 | 121 | func GetHttpQueryData(table Table) string { 122 | modeldatas := make([]string, 0) 123 | var initmodel string 124 | // 添加分页 125 | initmodel = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 126 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", "current", "页码", "integer") 127 | modeldatas = append(modeldatas, initmodel) 128 | initmodel = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 129 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", "page_size", "页数", "integer") 130 | modeldatas = append(modeldatas, initmodel) 131 | 132 | for _, field := range table.Fields { 133 | camel := util.SafeString(field.Name.ToCamel()) 134 | xcamel := util.SafeString(field.Name.Lower()) 135 | if camel == "Id" || camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || 136 | camel == "CreatedName" || camel == "UpdatedName" || camel == "DeletedName" || camel == "TenantId" || camel == "Sort" { 137 | continue 138 | } 139 | 140 | var model string 141 | switch camel { 142 | case "TenantId": 143 | continue 144 | default: 145 | switch field.DataType { 146 | case "sql.NullString": 147 | model = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 148 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", xcamel, field.Comment, "string") 149 | case "string": 150 | model = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 151 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", xcamel, field.Comment, "string") 152 | case "sql.NullTime": 153 | model = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 154 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", xcamel, field.Comment, "integer") 155 | case "time.Time": 156 | model = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 157 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", xcamel, field.Comment, "integer") 158 | case "sql.NullInt64": 159 | model = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 160 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", xcamel, field.Comment, "integer") 161 | case "sql.NullInt32": 162 | model = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 163 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", xcamel, field.Comment, "integer") 164 | case "int64": 165 | model = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 166 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", xcamel, field.Comment, "integer") 167 | case "int32": 168 | model = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 169 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", xcamel, field.Comment, "integer") 170 | case "float64": 171 | model = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 172 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", xcamel, field.Comment, "number") 173 | case "float32": 174 | model = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 175 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", xcamel, field.Comment, "number") 176 | case "NullFloat32": 177 | model = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 178 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", xcamel, field.Comment, "number") 179 | case "NullFloat64": 180 | model = fmt.Sprintf("{\n\t\t\t\"name\": \"%s\",\n\t\t\t\"in\": \"query\",\n\t\t\t\"description\":"+ 181 | " \"%s\",\n\t\t\t\"required\": false,\n\t\t\t\"schema\": {\n\t\t\t \"type\": \"%s\"\n\t\t\t}\n\t\t }", xcamel, field.Comment, "number") 182 | default: 183 | continue 184 | } 185 | } 186 | modeldatas = append(modeldatas, model) 187 | 188 | } 189 | modeldata := strings.Join(modeldatas, ",\n\t\t ") 190 | return modeldata 191 | 192 | } 193 | -------------------------------------------------------------------------------- /gen/rpc/createfilerpc.go: -------------------------------------------------------------------------------- 1 | package rpc 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "path/filepath" 8 | "strings" 9 | ) 10 | 11 | func CreateFileRpc(modelList map[string]*CodeTuple, srcPath string) error { 12 | 13 | dirAbs := filepath.Dir(srcPath) 14 | 15 | dirAbs = filepath.Join(dirAbs, "rpc") 16 | 17 | is, _ := IsPathExist(dirAbs) 18 | if is == false { 19 | err := os.Mkdir(dirAbs, os.ModePerm) 20 | if err != nil { 21 | return err 22 | } 23 | } 24 | 25 | for tableName, codes := range modelList { 26 | 27 | name := fmt.Sprintf("%v.proto", SafeString(tableName)) 28 | filename := filepath.Join(dirAbs, name) 29 | err := ioutil.WriteFile(filename, []byte(codes.Rpc), os.ModePerm) 30 | if err != nil { 31 | return err 32 | } 33 | 34 | name = fmt.Sprintf("%vaddlogic.go", SafeString(tableName)) 35 | filename = filepath.Join(dirAbs, name) 36 | err = ioutil.WriteFile(filename, []byte(codes.RpcInsert), os.ModePerm) 37 | if err != nil { 38 | return err 39 | } 40 | 41 | name = fmt.Sprintf("%vdellogic.go", SafeString(tableName)) 42 | filename = filepath.Join(dirAbs, name) 43 | err = ioutil.WriteFile(filename, []byte(codes.RpcDelete), os.ModePerm) 44 | if err != nil { 45 | return err 46 | } 47 | 48 | name = fmt.Sprintf("%vuplogic.go", SafeString(tableName)) 49 | filename = filepath.Join(dirAbs, name) 50 | err = ioutil.WriteFile(filename, []byte(codes.RpcUpdate), os.ModePerm) 51 | if err != nil { 52 | return err 53 | } 54 | 55 | name = fmt.Sprintf("%vfindonelogic.go", SafeString(tableName)) 56 | filename = filepath.Join(dirAbs, name) 57 | err = ioutil.WriteFile(filename, []byte(codes.RpcFindOne), os.ModePerm) 58 | if err != nil { 59 | return err 60 | } 61 | 62 | name = fmt.Sprintf("%vlistlogic.go", SafeString(tableName)) 63 | filename = filepath.Join(dirAbs, name) 64 | err = ioutil.WriteFile(filename, []byte(codes.RpcFindList), os.ModePerm) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | fmt.Println("RpcDone.") 70 | return nil 71 | } 72 | 73 | // SafeString converts the input string into a safe naming style in golang 74 | func SafeString(in string) string { 75 | if len(in) == 0 { 76 | return in 77 | } 78 | if strings.Contains(in, "_") { 79 | in = strings.Replace(in, "_", "", -1) 80 | } 81 | return in 82 | } 83 | 84 | func IsPathExist(path string) (bool, error) { 85 | _, err := os.Stat(path) 86 | if err == nil { 87 | return true, nil 88 | } 89 | if os.IsNotExist(err) { 90 | return false, nil 91 | } 92 | return false, err 93 | } 94 | -------------------------------------------------------------------------------- /gen/rpc/delete.go: -------------------------------------------------------------------------------- 1 | package rpc 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | ) 9 | 10 | func genDelete(table Table, modelName stringx.String) (string, error) { 11 | var deletedCount = 0 12 | var deletedData = "" 13 | var deletedAtData = "" 14 | var tenantCount = 0 15 | var tenantData = "" 16 | var delType = "Delete(l.ctx,id)" 17 | for _, field := range table.Fields { 18 | camel := util.SafeString(field.Name.ToCamel()) 19 | switch camel { 20 | case "DeletedAt": 21 | deletedCount++ 22 | case "TenantId": 23 | tenantCount++ 24 | } 25 | } 26 | if tenantCount > 0 { 27 | tenantData = "if res.TenantId != in.TenantId {\n\t\treturn nil, errors.New(\"不是一个租户非法操作\")\n\t}" 28 | } 29 | 30 | camel := table.Name.ToCamel() 31 | 32 | if deletedCount > 0 { 33 | deletedData = "res.DeletedAt.Time = time.Now()\n\tres.DeletedAt.Valid = true\n\tres.DeletedName.String = in.DeletedName\n\tres.DeletedName.Valid = true" 34 | delType = "Update(l.ctx,res)" 35 | deletedAtData = fmt.Sprintf("// 判断该数据是否被删除\n\tif res.DeletedAt.Valid == true {\n\t\treturn nil, fmt.Errorf(\"%s该ID已被删除:%s\",in.Id)\n\t}", camel, "%v") 36 | } 37 | 38 | xmodelname := modelName.Lower() 39 | text, err := pathx.LoadTemplate(category, deleteTemplateFile, "") 40 | if err != nil { 41 | return "", err 42 | } 43 | output, err := util.With("delete"). 44 | Parse(text). 45 | Execute(map[string]interface{}{ 46 | "filename": camel, 47 | "xmodelname": xmodelname, 48 | "deletedAtData": deletedAtData, 49 | "tenant": tenantData, 50 | "del": deletedData, 51 | "delType": delType, 52 | }) 53 | if err != nil { 54 | return "", err 55 | } 56 | 57 | return output.String(), nil 58 | } 59 | -------------------------------------------------------------------------------- /gen/rpc/findlist.go: -------------------------------------------------------------------------------- 1 | package rpc 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | "strings" 9 | ) 10 | 11 | func genFindList(table Table, modelName stringx.String) (string, error) { 12 | 13 | var tenantCount = 0 14 | var tenantData = "" 15 | var tenantDataCount = "" 16 | 17 | var deletedCount = 0 18 | var deletedData = "" 19 | var deletedDataCount = "" 20 | 21 | whereBuilderData, tenantCount, deletedCount := getListData(table, "whereBuilder") 22 | countBuilderData, tenantCount, deletedCount := getListData(table, "countBuilder") 23 | 24 | findListData := getFindListData(table) 25 | 26 | if tenantCount > 0 { 27 | tenantData = "whereBuilder = whereBuilder.Where(squirrel.Eq{\n \t\t\"tenant_id\": in.TenantId,\n \t})" 28 | tenantDataCount = "countBuilder = countBuilder.Where(squirrel.Eq{\n \t\"tenant_id\": in.TenantId,\n \t})" 29 | } 30 | 31 | if deletedCount > 0 { 32 | deletedData = "whereBuilder = whereBuilder.Where(\"deleted_at is null\")" 33 | deletedDataCount = "countBuilder = countBuilder.Where(\"deleted_at is null\")" 34 | } 35 | createdData := "\twhereBuilder = whereBuilder.OrderBy(\"created_at DESC, id DESC\")" 36 | 37 | camel := table.Name.ToCamel() 38 | xmodelname := modelName.Lower() 39 | text, err := pathx.LoadTemplate(category, findListTemplateFile, "") 40 | if err != nil { 41 | return "", err 42 | } 43 | output, err := util.With("findOne"). 44 | Parse(text). 45 | Execute(map[string]interface{}{ 46 | "filename": camel, 47 | "xmodelname": xmodelname, 48 | "listDeletedAt": deletedData, 49 | "listCreatedAt": createdData, 50 | "listTenant": tenantData, 51 | "listData": whereBuilderData, 52 | "countDeletedAt": deletedDataCount, 53 | "countTenant": tenantDataCount, 54 | "countData": countBuilderData, 55 | "findlistData": findListData, 56 | }) 57 | if err != nil { 58 | return "", err 59 | } 60 | 61 | return output.String(), nil 62 | } 63 | 64 | func getListData(table Table, builderName string) (data string, tenantCount, deletedCount int) { 65 | datas := make([]string, 0) 66 | for _, field := range table.Fields { 67 | camel := util.SafeString(field.Name.ToCamel()) 68 | xcamel := util.SafeString(field.Name.Lower()) 69 | if camel == "Id" || camel == "CreatedAt" || camel == "UpdatedAt" || camel == "CreatedName" || camel == "UpdatedName" || camel == "DeletedName" { 70 | continue 71 | } 72 | var model string 73 | switch camel { 74 | case "TenantId": 75 | tenantCount++ 76 | continue 77 | case "DeletedAt": 78 | deletedCount++ 79 | continue 80 | case "Sort": 81 | continue 82 | default: 83 | switch field.DataType { 84 | case "sql.NullString": 85 | model = fmt.Sprintf("// %s\n\tif len(in.%v) > 0 {\n\t\t%s = %s.Where(squirrel.Like{\n\t\t\t\"%s \": %s,\n\t\t})\n\t}", field.Comment, camel, builderName, builderName, xcamel, `"%"+in.`+camel+`+"%"`) 86 | case "sql.NullInt64": 87 | model = fmt.Sprintf("// %s\n\tif in.%v != 99 {\n\t\t%s = %s.Where(squirrel.Eq{\n\t\t\t\"%s \": in.%s,\n\t\t})\n\t}", field.Comment, camel, builderName, builderName, xcamel, camel) 88 | case "sql.NullInt32": 89 | model = fmt.Sprintf("// %s\n\tif in.%v != 99 {\n\t\t%s = %s.Where(squirrel.Eq{\n\t\t\t\"%s \": in.%s,\n\t\t})\n\t}", field.Comment, camel, builderName, builderName, xcamel, camel) 90 | case "sql.NullFloat64": 91 | model = fmt.Sprintf("// %s\n\tif in.%v != 99.0 {\n\t\t%s = %s.Where(squirrel.Eq{\n\t\t\t\"%s \": in.%s,\n\t\t})\n\t}", field.Comment, camel, builderName, builderName, xcamel, camel) 92 | case "sql.NullFloat32": 93 | model = fmt.Sprintf("// %s\n\tif in.%v != 99.0 {\n\t\t%s = %s.Where(squirrel.Eq{\n\t\t\t\"%s \": in.%s,\n\t\t})\n\t}", field.Comment, camel, builderName, builderName, xcamel, camel) 94 | case "string": 95 | model = fmt.Sprintf("// %s\n\tif len(in.%v) > 0 {\n\t\t%s = %s.Where(squirrel.Like{\n\t\t\t\"%s \": %s,\n\t\t})\n\t}", field.Comment, camel, builderName, builderName, xcamel, `"%"+in.`+camel+`+"%"`) 96 | case "int64": 97 | model = fmt.Sprintf("// %s\n\tif in.%v != 99 {\n\t\t%s = %s.Where(squirrel.Eq{\n\t\t\t\"%s \": in.%s,\n\t\t})\n\t}", field.Comment, camel, builderName, builderName, xcamel, camel) 98 | case "int32": 99 | model = fmt.Sprintf("// %s\n\tif in.%v != 99 {\n\t\t%s = %s.Where(squirrel.Eq{\n\t\t\t\"%s \": in.%s,\n\t\t})\n\t}", field.Comment, camel, builderName, builderName, xcamel, camel) 100 | case "float32": 101 | model = fmt.Sprintf("// %s\n\tif in.%v != 99.0 {\n\t\t%s = %s.Where(squirrel.Eq{\n\t\t\t\"%s \": in.%s,\n\t\t})\n\t}", field.Comment, camel, builderName, builderName, xcamel, camel) 102 | case "float64": 103 | model = fmt.Sprintf("// %s\n\tif in.%v != 99.0 {\n\t\t%s = %s.Where(squirrel.Eq{\n\t\t\t\"%s \": in.%s,\n\t\t})\n\t}", field.Comment, camel, builderName, builderName, xcamel, camel) 104 | case "sql.NullTime": 105 | continue 106 | case "time.Time": 107 | continue 108 | } 109 | } 110 | datas = append(datas, model) 111 | } 112 | data = strings.Join(datas, "\n\t") 113 | return data, tenantCount, deletedCount 114 | } 115 | 116 | func getFindListData(table Table) string { 117 | datas := make([]string, 0) 118 | for _, field := range table.Fields { 119 | camel := util.SafeString(field.Name.ToCamel()) 120 | if camel == "DeletedName" { 121 | continue 122 | } 123 | var model string 124 | switch camel { 125 | case "TenantId": 126 | continue 127 | case "DeletedAt": 128 | continue 129 | default: 130 | switch field.DataType { 131 | case "sql.NullString": 132 | model = fmt.Sprintf("%s:\titem.%s.String, //%s", camel, camel, field.Comment) 133 | case "sql.NullInt64": 134 | model = fmt.Sprintf("%s:\titem.%s.Int64, //%s", camel, camel, field.Comment) 135 | case "sql.NullInt32": 136 | model = fmt.Sprintf("%s:\titem.%s.Int32, //%s", camel, camel, field.Comment) 137 | case "sql.NullFloat64": 138 | model = fmt.Sprintf("%s:\titem.%s.Float64, //%s", camel, camel, field.Comment) 139 | case "sql.NullFloat32": 140 | model = fmt.Sprintf("%s:\titem.%s.Float32, //%s", camel, camel, field.Comment) 141 | case "sql.NullTime": 142 | model = fmt.Sprintf("%s:\titem.%s.Time.UnixMilli(), //%s", camel, camel, field.Comment) 143 | case "time.Time": 144 | model = fmt.Sprintf("%s:\titem.%s.UnixMilli(), //%s", camel, camel, field.Comment) 145 | default: 146 | model = fmt.Sprintf("%s:\titem.%s, //%s", camel, camel, field.Comment) 147 | } 148 | } 149 | 150 | datas = append(datas, model) 151 | } 152 | 153 | data := strings.Join(datas, "\n\t\t\t") 154 | 155 | return data 156 | 157 | } 158 | -------------------------------------------------------------------------------- /gen/rpc/findone.go: -------------------------------------------------------------------------------- 1 | package rpc 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | "strings" 9 | ) 10 | 11 | func genFindOne(table Table, modelName stringx.String) (string, error) { 12 | datas := make([]string, 0) 13 | var tenantCount = 0 14 | var tenantData = "" 15 | var deletedCount = 0 16 | var deletedAtData = "" 17 | for _, field := range table.Fields { 18 | camel := util.SafeString(field.Name.ToCamel()) 19 | if camel == "DeletedName" { 20 | continue 21 | } 22 | var model string 23 | switch camel { 24 | case "TenantId": 25 | tenantCount++ 26 | continue 27 | case "DeletedAt": 28 | deletedCount++ 29 | continue 30 | default: 31 | switch field.DataType { 32 | case "sql.NullString": 33 | model = fmt.Sprintf("%s:\tres.%s.String, //%s", camel, camel, field.Comment) 34 | case "sql.NullInt64": 35 | model = fmt.Sprintf("%s:\tres.%s.Int64, //%s", camel, camel, field.Comment) 36 | case "sql.NullInt32": 37 | model = fmt.Sprintf("%s:\tres.%s.Int32, //%s", camel, camel, field.Comment) 38 | case "sql.NullFloat64": 39 | model = fmt.Sprintf("%s:\tres.%s.Float64, //%s", camel, camel, field.Comment) 40 | case "sql.NullFloat32": 41 | model = fmt.Sprintf("%s:\tres.%s.Float32, //%s", camel, camel, field.Comment) 42 | case "sql.NullTime": 43 | model = fmt.Sprintf("%s:\tres.%s.Time.UnixMilli(), //%s", camel, camel, field.Comment) 44 | case "time.Time": 45 | model = fmt.Sprintf("%s:\tres.%s.UnixMilli(), //%s", camel, camel, field.Comment) 46 | default: 47 | model = fmt.Sprintf("%s:\tres.%s, //%s", camel, camel, field.Comment) 48 | } 49 | } 50 | 51 | datas = append(datas, model) 52 | } 53 | if tenantCount > 0 { 54 | tenantData = "if res.TenantId != in.TenantId {\n\t\treturn nil, errors.New(\"不是一个租户非法操作\")\n\t}" 55 | } 56 | 57 | camel := table.Name.ToCamel() 58 | 59 | if deletedCount > 0 { 60 | deletedAtData = fmt.Sprintf("// 判断该数据是否被删除\n\tif res.DeletedAt.Valid == true {\n\t\treturn nil, fmt.Errorf(\"%s该ID已被删除:%s\",in.Id)\n\t}", camel, "%v") 61 | } 62 | 63 | data := strings.Join(datas, "\n\t\t") 64 | 65 | xmodelname := modelName.Lower() 66 | text, err := pathx.LoadTemplate(category, findOneTemplateFile, "") 67 | if err != nil { 68 | return "", err 69 | } 70 | output, err := util.With("findOne"). 71 | Parse(text). 72 | Execute(map[string]interface{}{ 73 | "filename": camel, 74 | "xmodelname": xmodelname, 75 | "deletedAtData": deletedAtData, 76 | "tenant": tenantData, 77 | "findoneData": data, 78 | }) 79 | if err != nil { 80 | return "", err 81 | } 82 | 83 | return output.String(), nil 84 | } 85 | -------------------------------------------------------------------------------- /gen/rpc/gen.go: -------------------------------------------------------------------------------- 1 | package rpc 2 | 3 | import ( 4 | "fmt" 5 | "gozc/parser" 6 | "gozc/tools/stringx" 7 | ) 8 | 9 | type Table struct { 10 | parser.Table 11 | } 12 | 13 | type ( 14 | CodeTuple struct { 15 | Rpc string 16 | RpcInsert string 17 | RpcDelete string 18 | RpcUpdate string 19 | RpcFindOne string 20 | RpcFindList string 21 | } 22 | ) 23 | 24 | const ( 25 | category = "rpc" 26 | rpcTemplateFile = "rpc.tpl" 27 | insertTemplateFile = "insert.tpl" 28 | deleteTemplateFile = "delete.tpl" 29 | updateTemplateFile = "update.tpl" 30 | findOneTemplateFile = "find-one.tpl" 31 | findOneRespTemplateFile = "find-one-resp" 32 | findListTemplateFile = "find-list.tpl" 33 | findListRespTemplateFile = "find-list-resp" 34 | findDataTemplateFile = "find-list-data" 35 | ) 36 | 37 | func GenRpcModel(in parser.Table, pkgName string, apiType string) (string, error) { 38 | if len(in.PrimaryKey.Name.Source()) == 0 { 39 | return "", fmt.Errorf("table %s: missing primary key", in.Name.Source()) 40 | } 41 | var table Table 42 | table.Table = in 43 | var modelName stringx.String 44 | modelName = stringx.From(pkgName) 45 | 46 | switch apiType { 47 | case "rpc": 48 | res, err := genRpc(table, modelName) 49 | if err != nil { 50 | return "", err 51 | } 52 | return res, nil 53 | case "Insert": 54 | res, err := genInsert(table, modelName) 55 | if err != nil { 56 | return "", err 57 | } 58 | return res, nil 59 | case "delete": 60 | res, err := genDelete(table, modelName) 61 | if err != nil { 62 | return "", err 63 | } 64 | return res, nil 65 | case "update": 66 | res, err := genUpdate(table, modelName) 67 | if err != nil { 68 | return "", err 69 | } 70 | return res, nil 71 | case "findOne": 72 | res, err := genFindOne(table, modelName) 73 | if err != nil { 74 | return "", err 75 | } 76 | return res, nil 77 | case "findList": 78 | res, err := genFindList(table, modelName) 79 | if err != nil { 80 | return "", err 81 | } 82 | return res, nil 83 | 84 | } 85 | return "", nil 86 | 87 | } 88 | -------------------------------------------------------------------------------- /gen/rpc/insert.go: -------------------------------------------------------------------------------- 1 | package rpc 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | "strings" 9 | ) 10 | 11 | func genInsert(table Table, modelName stringx.String) (string, error) { 12 | datas := make([]string, 0) 13 | for _, field := range table.Fields { 14 | camel := util.SafeString(field.Name.ToCamel()) 15 | if camel == "Id" || camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || camel == "UpdatedName" || camel == "DeletedName" { 16 | continue 17 | } 18 | var model string 19 | switch camel { 20 | default: 21 | switch field.DataType { 22 | case "sql.NullString": 23 | model = fmt.Sprintf("%s:\tsql.NullString{String: in.%s, Valid: in.%s != \"\"}, // %s", camel, camel, camel, field.Comment) 24 | case "sql.NullInt64": 25 | model = fmt.Sprintf("%s:\tsql.NullInt64{Int64: in.%s, Valid: in.%s != \"\"}, // %s", camel, camel, camel, field.Comment) 26 | case "sql.NullInt32": 27 | model = fmt.Sprintf("%s:\tsql.NullInt32{Int32: in.%s, Valid: in.%s != \"\"}, // %s", camel, camel, camel, field.Comment) 28 | case "sql.NullFloat64": 29 | model = fmt.Sprintf("%s:\tsql.NullFloat64{Float64: in.%s, Valid: in.%s != \"\"}, // %s", camel, camel, camel, field.Comment) 30 | case "sql.NullFloat32": 31 | model = fmt.Sprintf("%s:\tsql.NullFloat32{Float32: in.%s, Valid: in.%s != \"\"}, // %s", camel, camel, camel, field.Comment) 32 | case "sql.NullTime": 33 | model = fmt.Sprintf("%s:\tsql.NullTime{Time: in.%s, Valid: in.%s != \"\"}, // %s", camel, camel, camel, field.Comment) 34 | default: 35 | model = fmt.Sprintf("%s:\t in.%s, // %s", camel, camel, field.Comment) 36 | } 37 | } 38 | datas = append(datas, model) 39 | } 40 | data := strings.Join(datas, "\n\t\t") 41 | camel := table.Name.ToCamel() 42 | xmodelname := modelName.Lower() 43 | 44 | text, err := pathx.LoadTemplate(category, insertTemplateFile, "") 45 | if err != nil { 46 | return "", err 47 | } 48 | output, err := util.With("insert"). 49 | Parse(text). 50 | Execute(map[string]interface{}{ 51 | "filename": camel, 52 | "xmodelname": xmodelname, 53 | "data": data, 54 | }) 55 | if err != nil { 56 | return "", err 57 | } 58 | 59 | return output.String(), nil 60 | } 61 | -------------------------------------------------------------------------------- /gen/rpc/rpc.go: -------------------------------------------------------------------------------- 1 | package rpc 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | "strings" 9 | ) 10 | 11 | func genRpc(table Table, pkgName stringx.String) (string, error) { 12 | 13 | camel := table.Name.ToCamel() 14 | 15 | var modelname = pkgName.Lower() 16 | var amodelname = pkgName.ToCamel() 17 | 18 | add := GetRpcData(table, insertTemplateFile) 19 | del := GetRpcData(table, deleteTemplateFile) 20 | up := GetRpcData(table, updateTemplateFile) 21 | findOne := GetRpcData(table, findOneTemplateFile) 22 | findOneResp := GetRpcData(table, findOneRespTemplateFile) 23 | list := GetRpcData(table, findListTemplateFile) 24 | listResp := GetRpcData(table, findListRespTemplateFile) 25 | listData := GetRpcData(table, findDataTemplateFile) 26 | text, err := pathx.LoadTemplate(category, rpcTemplateFile, "") 27 | if err != nil { 28 | return "", err 29 | } 30 | output, err := util.With("rpc"). 31 | Parse(text). 32 | Execute(map[string]interface{}{ 33 | "filename": camel, 34 | "modelname": modelname, 35 | "amodelname": amodelname, 36 | "Add": add, 37 | "Del": del, 38 | "Up": up, 39 | "FindOne": findOne, 40 | "FindOneResp": findOneResp, 41 | "List": list, 42 | "ListResp": listResp, 43 | "ListData": listData, 44 | }) 45 | if err != nil { 46 | return "", err 47 | } 48 | 49 | return output.String(), nil 50 | } 51 | 52 | func GetRpcData(table Table, dataType string) string { 53 | modeldatas := make([]string, 0) 54 | var count = 0 55 | 56 | if dataType == findListTemplateFile { 57 | var model string 58 | model = fmt.Sprintf("%s %s = %v; // %s", "int64", "current", 1, "页码") 59 | modeldatas = append(modeldatas, model) 60 | model = fmt.Sprintf("%s %s = %v; // %s", "int64", "page_size", 2, "页数") 61 | modeldatas = append(modeldatas, model) 62 | count = 2 63 | } 64 | 65 | for _, field := range table.Fields { 66 | camel := util.SafeString(field.Name.ToCamel()) 67 | lowerCamel := util.SafeString(field.Name.Lower()) 68 | switch dataType { 69 | case insertTemplateFile: 70 | if camel == "Id" || camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || 71 | camel == "UpdatedName" || camel == "DeletedName" { 72 | continue 73 | } 74 | case deleteTemplateFile: 75 | if camel != "Id" && camel != "DeletedName" && camel != "TenantId" { 76 | continue 77 | } 78 | case updateTemplateFile: 79 | if camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || 80 | camel == "CreatedName" || camel == "DeletedName" { 81 | continue 82 | } 83 | case findOneTemplateFile: 84 | if camel != "Id" && camel != "TenantId" { 85 | continue 86 | } 87 | case findOneRespTemplateFile: 88 | if camel == "DeletedAt" || 89 | camel == "DeletedName" || camel == "TenantId" { 90 | continue 91 | } 92 | case findListTemplateFile: 93 | if camel == "Id" || camel == "CreatedAt" || camel == "UpdatedAt" || camel == "DeletedAt" || 94 | camel == "CreatedName" || camel == "UpdatedName" || camel == "DeletedName" || camel == "Sort" { 95 | continue 96 | } 97 | case findDataTemplateFile: 98 | if camel == "DeletedAt" || 99 | camel == "DeletedName" || camel == "TenantId" { 100 | continue 101 | } 102 | case findListRespTemplateFile: 103 | var model string 104 | model = fmt.Sprintf("%s %s = %v; // %s", "int64", "total", 1, "总数") 105 | modeldatas = append(modeldatas, model) 106 | model = fmt.Sprintf("%s %s = %v; // %s", "repeated", table.Name.ToCamel()+"ListData list", 2, "内容") 107 | modeldatas = append(modeldatas, model) 108 | modeldata := strings.Join(modeldatas, "\n\t") 109 | return modeldata 110 | default: 111 | return "" 112 | } 113 | 114 | count++ 115 | var model string 116 | switch camel { 117 | default: 118 | switch field.DataType { 119 | case "sql.NullString": 120 | model = fmt.Sprintf("%s %s = %v; // %s", "string", lowerCamel, count, field.Comment) 121 | case "string": 122 | model = fmt.Sprintf("%s %s = %v; // %s", "string", lowerCamel, count, field.Comment) 123 | case "sql.NullTime": 124 | model = fmt.Sprintf("%s %s = %v; // %s", "int64", lowerCamel, count, field.Comment) 125 | case "time.Time": 126 | model = fmt.Sprintf("%s %s = %v; // %s", "int64", lowerCamel, count, field.Comment) 127 | case "sql.NullInt64": 128 | model = fmt.Sprintf("%s %s = %v; // %s", "int64", lowerCamel, count, field.Comment) 129 | case "sql.NullInt32": 130 | model = fmt.Sprintf("%s %s = %v; // %s", "int64", lowerCamel, count, field.Comment) 131 | case "int64": 132 | model = fmt.Sprintf("%s %s = %v; // %s", "int64", lowerCamel, count, field.Comment) 133 | case "int32": 134 | model = fmt.Sprintf("%s %s = %v; // %s", "int64", lowerCamel, count, field.Comment) 135 | case "float64": 136 | model = fmt.Sprintf("%s %s = %v; // %s", "double", lowerCamel, count, field.Comment) 137 | case "float32": 138 | model = fmt.Sprintf("%s %s = %v; // %s", "float", lowerCamel, count, field.Comment) 139 | case "sql.NullFloat64": 140 | model = fmt.Sprintf("%s %s = %v; // %s", "double", lowerCamel, count, field.Comment) 141 | case "sql.NullFloat32": 142 | model = fmt.Sprintf("%s %s = %v; // %s", "float", lowerCamel, count, field.Comment) 143 | default: 144 | continue 145 | } 146 | } 147 | modeldatas = append(modeldatas, model) 148 | 149 | } 150 | modeldata := strings.Join(modeldatas, "\n\t") 151 | return modeldata 152 | 153 | } 154 | -------------------------------------------------------------------------------- /gen/rpc/update.go: -------------------------------------------------------------------------------- 1 | package rpc 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/go-zero/tools/goctl/util" 6 | "gozc/tools/pathx" 7 | "gozc/tools/stringx" 8 | "strings" 9 | ) 10 | 11 | func genUpdate(table Table, modelName stringx.String) (string, error) { 12 | datas := make([]string, 0) 13 | var tenantCount = 0 14 | var tenantData = "" 15 | var deletedCount = 0 16 | var deletedAtData = "" 17 | for _, field := range table.Fields { 18 | camel := util.SafeString(field.Name.ToCamel()) 19 | if camel == "Id" || camel == "CreatedAt" || camel == "UpdatedAt" || 20 | camel == "CreatedName" || camel == "UpdatedName" || camel == "DeletedName" { 21 | continue 22 | } 23 | var model string 24 | switch camel { 25 | case "TenantId": 26 | tenantCount++ 27 | continue 28 | case "DeletedAt": 29 | deletedCount++ 30 | continue 31 | default: 32 | switch field.DataType { 33 | case "sql.NullString": 34 | model = fmt.Sprintf("// %s \n\tif len(in.%v) > 0 {\n\t\tres.%s.String = in.%s\n\t\tres.%s.Valid = true\n\t}", field.Comment, camel, camel, camel, camel) 35 | case "sql.NullInt64": 36 | model = fmt.Sprintf("// %s \n\tif in.%v != 0 {\n\t\tres.%s.Int64 = in.%s\n\t\tres.%s.Valid = true\n\t}", field.Comment, camel, camel, camel, camel) 37 | case "sql.NullInt32": 38 | model = fmt.Sprintf("// %s \n\tif in.%v != 0 {\n\t\tres.%s.Int32 = in.%s\n\t\tres.%s.Valid = true\n\t}", field.Comment, camel, camel, camel, camel) 39 | case "sql.NullFloat64": 40 | model = fmt.Sprintf("// %s \n\tif in.%v != 0.0 {\n\t\tres.%s.Float64 = in.%s\n\t\tres.%s.Valid = true\n\t}", field.Comment, camel, camel, camel, camel) 41 | case "sql.NullFloat32": 42 | model = fmt.Sprintf("// %s \n\tif in.%v != 0.0 {\n\t\tres.%s.Float32 = in.%s\n\t\tres.%s.Valid = true\n\t}", field.Comment, camel, camel, camel, camel) 43 | case "string": 44 | model = fmt.Sprintf("// %s\n\tif len(in.%v) > 0 {\n\t\tres.%s = in.%s\n\t}", field.Comment, camel, camel, camel) 45 | case "int64": 46 | model = fmt.Sprintf("// %s\n\tif in.%v != 0 {\n\t\tres.%s = in.%s\n\t}", field.Comment, camel, camel, camel) 47 | case "int32": 48 | model = fmt.Sprintf("// %s\n\tif in.%v != 0 {\n\t\tres.%s = in.%s\n\t}", field.Comment, camel, camel, camel) 49 | case "float32": 50 | model = fmt.Sprintf("// %s\n\tif in.%v != 0.0 {\n\t\tres.%s = in.%s\n\t}", field.Comment, camel, camel, camel) 51 | case "float64": 52 | model = fmt.Sprintf("// %s\n\tif in.%v != 0.0 {\n\t\tres.%s = in.%s\n\t}", field.Comment, camel, camel, camel) 53 | case "sql.NullTime": 54 | continue 55 | case "time.Time": 56 | continue 57 | default: 58 | continue 59 | } 60 | } 61 | datas = append(datas, model) 62 | } 63 | if tenantCount > 0 { 64 | tenantData = "if res.TenantId != in.TenantId {\n\t\treturn nil, errors.New(\"不是一个租户非法操作\")\n\t}" 65 | } 66 | 67 | camel := table.Name.ToCamel() 68 | 69 | if deletedCount > 0 { 70 | deletedAtData = fmt.Sprintf("// 判断该数据是否被删除\n\tif res.DeletedAt.Valid == true {\n\t\treturn nil, errors.New(\"%s该ID已被删除:\" + in.Id)\n\t}", camel) 71 | } 72 | data := strings.Join(datas, "\n\t") 73 | xmodelname := modelName.Lower() 74 | text, err := pathx.LoadTemplate(category, updateTemplateFile, "") 75 | if err != nil { 76 | return "", err 77 | } 78 | output, err := util.With("update"). 79 | Parse(text). 80 | Execute(map[string]interface{}{ 81 | "filename": camel, 82 | "xmodelname": xmodelname, 83 | "tenant": tenantData, 84 | "updateData": data, 85 | "deletedAtData": deletedAtData, 86 | }) 87 | if err != nil { 88 | return "", err 89 | } 90 | 91 | return output.String(), nil 92 | } 93 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module gozc 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/urfave/cli/v2 v2.3.0 7 | github.com/zeromicro/ddl-parser v1.0.4 8 | github.com/zeromicro/go-zero v1.3.5 9 | github.com/zeromicro/go-zero/tools/goctl v1.3.9 10 | ) 11 | 12 | require ( 13 | github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521184019-c5ad59b459ec // indirect 14 | github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect 15 | github.com/fatih/color v1.13.0 // indirect 16 | github.com/logrusorgru/aurora v2.0.3+incompatible // indirect 17 | github.com/mattn/go-colorable v0.1.12 // indirect 18 | github.com/mattn/go-isatty v0.0.14 // indirect 19 | github.com/pelletier/go-toml/v2 v2.0.2 // indirect 20 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 21 | github.com/spaolacci/murmur3 v1.1.0 // indirect 22 | go.opentelemetry.io/otel v1.8.0 // indirect 23 | go.opentelemetry.io/otel/trace v1.8.0 // indirect 24 | go.uber.org/automaxprocs v1.5.1 // indirect 25 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect 26 | gopkg.in/yaml.v2 v2.4.0 // indirect 27 | ) 28 | -------------------------------------------------------------------------------- /gozc.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "flag" 6 | "fmt" 7 | "github.com/urfave/cli/v2" 8 | "gozc/gen/api" 9 | "gozc/gen/http" 10 | "gozc/gen/rpc" 11 | "gozc/parser" 12 | "os" 13 | "strings" 14 | ) 15 | 16 | func main() { 17 | 18 | flag.Parse() 19 | 20 | local := []*cli.Command{ 21 | runCmd, 22 | } 23 | app := &cli.App{ 24 | Name: "gozc", 25 | Usage: "go-zero CRUD生成器", 26 | Version: "1.0", 27 | EnableBashCompletion: true, 28 | Commands: local, 29 | } 30 | app.Setup() 31 | 32 | os.Args = append(os.Args, "run", "--m=admin", "--sql=E:\\Gopath\\src\\gozc\\model\\sql\\sys_admin.sql") 33 | 34 | if err := app.Run(os.Args); err != nil { 35 | fmt.Println(err) 36 | return 37 | } 38 | 39 | } 40 | 41 | var runCmd = &cli.Command{ 42 | Name: "run", 43 | Usage: "Print worker info", 44 | Flags: []cli.Flag{ 45 | &cli.StringFlag{ 46 | Name: "sql", 47 | Usage: "sql文件路径", 48 | Value: "", 49 | }, 50 | &cli.StringFlag{ 51 | Name: "m", 52 | Usage: "模型名称", 53 | Value: "", 54 | }, 55 | }, 56 | 57 | Before: func(cctx *cli.Context) error { 58 | data := os.Getenv("GOZC_PATH") 59 | if data == "" { 60 | return errors.New("请先设置环境变量GOZC_PATH路径指向Tpl文件夹") 61 | } 62 | fmt.Println("GOZC_PATH路径:" + data) 63 | return nil 64 | }, 65 | Action: func(cctx *cli.Context) error { 66 | var srcPath string 67 | // 拿sql文件地址 68 | srcPath = cctx.String("sql") 69 | if srcPath == "" { 70 | return errors.New("请传入SQL文件路径地址--sql") 71 | } 72 | 73 | // 拿微服务名称 74 | modelName := cctx.String("m") 75 | if srcPath == "" { 76 | return errors.New("请传入模型名称--m") 77 | } 78 | if strings.Contains(srcPath, ".\\") { 79 | dir, _ := os.Getwd() 80 | println(dir) 81 | srcPath = strings.Replace(srcPath, ".\\", dir+"\\", -1) 82 | } 83 | if strings.Contains(srcPath, "./") { 84 | dir, _ := os.Getwd() 85 | println(dir) 86 | srcPath = strings.Replace(srcPath, "./", dir+"\\", -1) 87 | } 88 | 89 | fmt.Println(srcPath) 90 | 91 | // 讲sql文件 转换成tables 92 | tables, err := parser.Parse(srcPath) 93 | if err != nil { 94 | return err 95 | } 96 | 97 | // 生成API 98 | err = CreateApiData(tables, modelName, srcPath) 99 | if err != nil { 100 | return err 101 | } 102 | 103 | // 生成RPC 104 | err = CreateRpcData(tables, modelName, srcPath) 105 | if err != nil { 106 | return err 107 | } 108 | 109 | // 生成HTTP 110 | err = CreateHttpData(tables, modelName, srcPath) 111 | if err != nil { 112 | return err 113 | } 114 | return nil 115 | }, 116 | } 117 | 118 | // 去生成API里的代码 119 | func CreateApiData(tables []*parser.Table, modelName, srcPath string) error { 120 | // 生成API 121 | apiData := make(map[string]*api.CodeTuple) 122 | for _, e := range tables { 123 | Api, err := api.GenApiModel(*e, modelName, "api") 124 | if err != nil { 125 | return err 126 | } 127 | ApiInsert, err := api.GenApiModel(*e, modelName, "Insert") 128 | if err != nil { 129 | return err 130 | } 131 | ApiDelete, err := api.GenApiModel(*e, modelName, "delete") 132 | if err != nil { 133 | return err 134 | } 135 | ApiUpdate, err := api.GenApiModel(*e, modelName, "update") 136 | if err != nil { 137 | return err 138 | } 139 | ApiFindOne, err := api.GenApiModel(*e, modelName, "findOne") 140 | if err != nil { 141 | return err 142 | } 143 | ApiFindList, err := api.GenApiModel(*e, modelName, "findList") 144 | if err != nil { 145 | return err 146 | } 147 | apiData[e.Name.Source()] = &api.CodeTuple{ 148 | Api: Api, 149 | ApiInsert: ApiInsert, 150 | ApiDelete: ApiDelete, 151 | ApiUpdate: ApiUpdate, 152 | ApiFindOne: ApiFindOne, 153 | ApiFindList: ApiFindList, 154 | } 155 | } 156 | err := api.CreateFileApi(apiData, srcPath) 157 | return err 158 | } 159 | 160 | // 去生成RPC里的代码 161 | func CreateRpcData(tables []*parser.Table, modelName, srcPath string) error { 162 | // 生成Rpc 163 | rpcData := make(map[string]*rpc.CodeTuple) 164 | for _, e := range tables { 165 | Rpc, err := rpc.GenRpcModel(*e, modelName, "rpc") 166 | if err != nil { 167 | return err 168 | } 169 | RpcInsert, err := rpc.GenRpcModel(*e, modelName, "Insert") 170 | if err != nil { 171 | return err 172 | } 173 | RpcDelete, err := rpc.GenRpcModel(*e, modelName, "delete") 174 | if err != nil { 175 | return err 176 | } 177 | RpcUpdate, err := rpc.GenRpcModel(*e, modelName, "update") 178 | if err != nil { 179 | return err 180 | } 181 | RpcFindOne, err := rpc.GenRpcModel(*e, modelName, "findOne") 182 | if err != nil { 183 | return err 184 | } 185 | RpcFindList, err := rpc.GenRpcModel(*e, modelName, "findList") 186 | if err != nil { 187 | return err 188 | } 189 | rpcData[e.Name.Source()] = &rpc.CodeTuple{ 190 | Rpc: Rpc, 191 | RpcInsert: RpcInsert, 192 | RpcDelete: RpcDelete, 193 | RpcUpdate: RpcUpdate, 194 | RpcFindOne: RpcFindOne, 195 | RpcFindList: RpcFindList, 196 | } 197 | } 198 | err := rpc.CreateFileRpc(rpcData, srcPath) 199 | return err 200 | } 201 | 202 | // 去生成SwaggerAPI 规范的东西 203 | func CreateHttpData(tables []*parser.Table, modelName, srcPath string) error { 204 | // 生成Http 205 | HttpData := make(map[string]*http.CodeTuple) 206 | for _, e := range tables { 207 | Api, err := http.GenHttpModel(*e, modelName, "http-api") 208 | if err != nil { 209 | return err 210 | } 211 | HttpData[e.Name.Source()] = &http.CodeTuple{ 212 | Api: Api, 213 | } 214 | } 215 | err := http.CreateFileHttp(HttpData, srcPath) 216 | return err 217 | } 218 | -------------------------------------------------------------------------------- /image/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigbeer1/gozc/bbf1c7e029e9f90e8745897caa00e7e0b1fbc679/image/img.png -------------------------------------------------------------------------------- /model/sql/api/sysadmin.api: -------------------------------------------------------------------------------- 1 | syntax = "v1" 2 | 3 | 4 | type ( 5 | SysAdminAddRequest { 6 | Name string `json:"name,optional"` // 用户名 7 | NickName string `json:"nick_name,optional"` // 姓名 8 | Avatar string `json:"avatar,optional"` // 头像 9 | Password string `json:"password,optional"` // 密码 10 | Email string `json:"email,optional"` // 邮箱 11 | Telephone string `json:"telephone,optional"` // 手机号 12 | State int64 `json:"state,optional"` // 状态 13 | } 14 | 15 | SysAdminDelRequest { 16 | Id string `path:"id"` // 系统管理员ID 17 | } 18 | 19 | SysAdminUpRequest { 20 | Id string `json:"id"` // 系统管理员ID 21 | Name string `json:"name,optional"` // 用户名 22 | NickName string `json:"nick_name,optional"` // 姓名 23 | Avatar string `json:"avatar,optional"` // 头像 24 | Password string `json:"password,optional"` // 密码 25 | Email string `json:"email,optional"` // 邮箱 26 | Telephone string `json:"telephone,optional"` // 手机号 27 | State int64 `json:"state,optional"` // 状态 28 | } 29 | 30 | 31 | SysAdminListRequest { 32 | Current int64 `form:"current,default=1,optional"` // 页码 33 | PageSize int64 `form:"page_size,default=10,optional"` // 页数 34 | Name string `form:"name,optional"` // 用户名 35 | NickName string `form:"nick_name,optional"` // 姓名 36 | Avatar string `form:"avatar,optional"` // 头像 37 | Password string `form:"password,optional"` // 密码 38 | Email string `form:"email,optional"` // 邮箱 39 | Telephone string `form:"telephone,optional"` // 手机号 40 | State int64 `form:"state,default=99,optional"` // 状态 41 | } 42 | 43 | SysAdminInfoRequest { 44 | Id string `form:"id"` // 系统管理员ID 45 | } 46 | 47 | ) 48 | 49 | @server( 50 | //声明当前service下所有路由需要jwt鉴权,且会自动生成包含jwt逻辑的代码 51 | jwt: Auth 52 | group: sysAdmin 53 | ) 54 | 55 | service Admin { 56 | 57 | // 添加 58 | @handler SysAdminAdd 59 | post /admin/sysAdmin (SysAdminAddRequest) returns (Response) 60 | 61 | // 删除 62 | @handler SysAdminDel 63 | delete /admin/sysAdmin/:id (SysAdminDelRequest) returns (Response) 64 | 65 | // 更新 66 | @handler SysAdminUp 67 | put /admin/sysAdmin (SysAdminUpRequest) returns (Response) 68 | 69 | // 分页查询 70 | @handler SysAdminList 71 | get /admin/sysAdmin (SysAdminListRequest) returns (Response) 72 | 73 | // 查询详细信息 74 | @handler SysAdminInfo 75 | get /admin/sysAdminInfo (SysAdminInfoRequest) returns (Response) 76 | } -------------------------------------------------------------------------------- /model/sql/api/sysadminInfologic.go: -------------------------------------------------------------------------------- 1 | func (l *SysAdminInfoLogic) SysAdminInfo(req *types.SysAdminInfoRequest) (*types.Response, error) { 2 | 3 | res, err := l.svcCtx.AdminRpc.SysAdminFindOne(l.ctx, &adminclient.SysAdminFindOneReq{ 4 | Id: req.Id, // 系统管理员ID 5 | }) 6 | if err != nil { 7 | return nil, common.NewDefaultError(err.Error()) 8 | } 9 | 10 | var result SysAdminFindOneResp 11 | _ = copier.Copy(&result, res) 12 | 13 | return &types.Response{ 14 | Code: 0, 15 | Msg: msg.Success, 16 | Data: result, 17 | }, nil 18 | } 19 | 20 | 21 | type SysAdminFindOneResp struct { 22 | Id string `json:"id"` // 系统管理员ID, 23 | CreatedAt int64 `json:"created_at"` // 创建时间, 24 | UpdatedAt int64 `json:"updated_at"` // 更新时间, 25 | CreatedName string `json:"created_name"` // 创建人, 26 | UpdatedName string `json:"updated_name"` // 更新人, 27 | Name string `json:"name"` // 用户名, 28 | NickName string `json:"nick_name"` // 姓名, 29 | Avatar string `json:"avatar"` // 头像, 30 | Password string `json:"password"` // 密码, 31 | Email string `json:"email"` // 邮箱, 32 | Telephone string `json:"telephone"` // 手机号, 33 | State int64 `json:"state"` // 状态 34 | } 35 | 36 | -------------------------------------------------------------------------------- /model/sql/api/sysadminaddlogic.go: -------------------------------------------------------------------------------- 1 | func (l *SysAdminAddLogic) SysAdminAdd(req *types.SysAdminAddRequest) (*types.Response, error) { 2 | 3 | _, err := l.svcCtx.AdminRpc.SysAdminAdd(l.ctx, &adminclient.SysAdminAddReq{ 4 | CreatedName: tokenData.NickName, // 创建人 5 | Name: req.Name, // 用户名 6 | NickName: req.NickName, // 姓名 7 | Avatar: req.Avatar, // 头像 8 | Password: req.Password, // 密码 9 | Email: req.Email, // 邮箱 10 | Telephone: req.Telephone, // 手机号 11 | State: req.State, // 状态 12 | }) 13 | if err != nil { 14 | return nil, common.NewDefaultError(err.Error()) 15 | } 16 | return &types.Response{ 17 | Code: 0, 18 | Msg: msg.Success, 19 | Data: nil, 20 | }, nil 21 | } 22 | -------------------------------------------------------------------------------- /model/sql/api/sysadmindellogic.go: -------------------------------------------------------------------------------- 1 | func (l *SysAdminDelLogic) SysAdminDel(req *types.SysAdminDelRequest) (*types.Response, error) { 2 | // 用户登录信息 3 | 4 | _, err := l.svcCtx.AdminRpc.SysAdminDelete(l.ctx, &adminclient.SysAdminDeleteReq{ 5 | Id: req.Id, // 系统管理员ID 6 | DeletedName: tokenData.NickName, // 删除人 7 | }) 8 | if err != nil { 9 | return nil, common.NewDefaultError(err.Error()) 10 | } 11 | return &types.Response{ 12 | Code: 0, 13 | Msg: msg.Success, 14 | Data: nil, 15 | }, nil 16 | } 17 | -------------------------------------------------------------------------------- /model/sql/api/sysadminlistlogic.go: -------------------------------------------------------------------------------- 1 | func (l *SysAdminListLogic) SysAdminList(req *types.SysAdminListRequest) (*types.Response, error) { 2 | 3 | all, err := l.svcCtx.AdminRpc.SysAdminList(l.ctx, &adminclient.SysAdminListReq{ 4 | Current: req.Current, // 页码 5 | PageSize: req.PageSize, // 页数 6 | Name: req.Name, // 用户名 7 | NickName: req.NickName, // 姓名 8 | Avatar: req.Avatar, // 头像 9 | Password: req.Password, // 密码 10 | Email: req.Email, // 邮箱 11 | Telephone: req.Telephone, // 手机号 12 | State: req.State, // 状态 13 | }) 14 | if err != nil { 15 | return nil, common.NewDefaultError(err.Error()) 16 | } 17 | 18 | var result SysAdminListResp 19 | _ = copier.Copy(&result, all) 20 | 21 | return &types.Response{ 22 | Code: 0, 23 | Msg: msg.Success, 24 | Data: result, 25 | }, nil 26 | } 27 | 28 | 29 | type SysAdminListResp struct { 30 | Total int64 `json:"total"` 31 | List []*SysAdminDataList `json:"list"` 32 | } 33 | 34 | type SysAdminDataList struct { 35 | Id string `json:"id"` // 系统管理员ID, 36 | CreatedAt int64 `json:"created_at"` // 创建时间, 37 | UpdatedAt int64 `json:"updated_at"` // 更新时间, 38 | CreatedName string `json:"created_name"` // 创建人, 39 | UpdatedName string `json:"updated_name"` // 更新人, 40 | Name string `json:"name"` // 用户名, 41 | NickName string `json:"nick_name"` // 姓名, 42 | Avatar string `json:"avatar"` // 头像, 43 | Password string `json:"password"` // 密码, 44 | Email string `json:"email"` // 邮箱, 45 | Telephone string `json:"telephone"` // 手机号, 46 | State int64 `json:"state"` // 状态 47 | } 48 | 49 | -------------------------------------------------------------------------------- /model/sql/api/sysadminuplogic.go: -------------------------------------------------------------------------------- 1 | func (l *SysAdminUpLogic) SysAdminUp(req *types.SysAdminUpRequest) (*types.Response, error) { 2 | 3 | 4 | _, err := l.svcCtx.AdminRpc.SysAdminUpdate(l.ctx, &adminclient.SysAdminUpdateReq{ 5 | Id: req.Id, // 系统管理员ID 6 | UpdatedName: tokenData.NickName, // 更新人 7 | Name: req.Name, // 用户名 8 | NickName: req.NickName, // 姓名 9 | Avatar: req.Avatar, // 头像 10 | Password: req.Password, // 密码 11 | Email: req.Email, // 邮箱 12 | Telephone: req.Telephone, // 手机号 13 | State: req.State, // 状态 14 | }) 15 | if err != nil { 16 | return nil, common.NewDefaultError(err.Error()) 17 | } 18 | return &types.Response{ 19 | Code: 0, 20 | Msg: msg.Success, 21 | Data: nil, 22 | }, nil 23 | } 24 | -------------------------------------------------------------------------------- /model/sql/http/sysadmin.json: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.1", 3 | "info": { 4 | "title": "", 5 | "description": "", 6 | "version": "1.0.0" 7 | }, 8 | "tags": [ 9 | { 10 | "name": "sysAdmin" 11 | } 12 | ], 13 | "paths": { 14 | "/admin/sysAdmin/{id}": { 15 | "delete": { 16 | "summary": "删除sysAdmin", 17 | "x-apifox-folder": "sysAdmin", 18 | "x-apifox-status": "developing", 19 | "deprecated": false, 20 | "description": "", 21 | "tags": [ 22 | "sysAdmin" 23 | ], 24 | "parameters": [ 25 | { 26 | "name": "id", 27 | "in": "path", 28 | "description": "系统管理员ID", 29 | "required": true, 30 | "example": "", 31 | "schema": { 32 | "type": "string" 33 | } 34 | } 35 | ], 36 | "responses": { 37 | 38 | }, 39 | "x-run-in-apifox": "", 40 | "security": [ 41 | { 42 | "bearer": [] 43 | } 44 | ] 45 | } 46 | }, 47 | "/admin/sysAdminInfo": { 48 | "get": { 49 | "summary": "根据ID查询sysAdmin", 50 | "x-apifox-folder": "sysAdmin", 51 | "x-apifox-status": "developing", 52 | "deprecated": false, 53 | "description": "", 54 | "tags": [ 55 | "sysAdmin" 56 | ], 57 | "parameters": [ 58 | { 59 | "name": "id", 60 | "in": "query", 61 | "description": "系统管理员ID", 62 | "required": false, 63 | "example": "", 64 | "schema": { 65 | "type": "string" 66 | } 67 | } 68 | ], 69 | "responses": { 70 | 71 | }, 72 | "x-run-in-apifox": "", 73 | "security": [ 74 | { 75 | "bearer": [] 76 | } 77 | ] 78 | } 79 | }, 80 | "/admin/sysAdmin": { 81 | "post": { 82 | "summary": "添加sysAdmin", 83 | "x-apifox-folder": "sysAdmin", 84 | "x-apifox-status": "developing", 85 | "deprecated": false, 86 | "description": "", 87 | "tags": [ 88 | "sysAdmin" 89 | ], 90 | "requestBody": { 91 | "content": { 92 | "application/json": { 93 | "schema": { 94 | "type": "object", 95 | "properties": { 96 | "name": { 97 | "type": "string", 98 | "description": "用户名" 99 | }, 100 | "nick_name": { 101 | "type": "string", 102 | "description": "姓名" 103 | }, 104 | "avatar": { 105 | "type": "string", 106 | "description": "头像" 107 | }, 108 | "password": { 109 | "type": "string", 110 | "description": "密码" 111 | }, 112 | "email": { 113 | "type": "string", 114 | "description": "邮箱" 115 | }, 116 | "telephone": { 117 | "type": "string", 118 | "description": "手机号" 119 | }, 120 | "state": { 121 | "type": "integer", 122 | "description": "状态" 123 | } 124 | } 125 | } 126 | } 127 | } 128 | }, 129 | "responses": { 130 | 131 | }, 132 | "x-run-in-apifox": "", 133 | "security": [ 134 | { 135 | "bearer": [] 136 | } 137 | ] 138 | }, 139 | "get": { 140 | "summary": "分页查询sysAdmin", 141 | "x-apifox-folder": "sysAdmin", 142 | "x-apifox-status": "developing", 143 | "deprecated": false, 144 | "description": "", 145 | "tags": [ 146 | "sysAdmin" 147 | ], 148 | "parameters": [ 149 | { 150 | "name": "current", 151 | "in": "query", 152 | "description": "页码", 153 | "required": false, 154 | "schema": { 155 | "type": "integer" 156 | } 157 | }, 158 | { 159 | "name": "page_size", 160 | "in": "query", 161 | "description": "页数", 162 | "required": false, 163 | "schema": { 164 | "type": "integer" 165 | } 166 | }, 167 | { 168 | "name": "name", 169 | "in": "query", 170 | "description": "用户名", 171 | "required": false, 172 | "schema": { 173 | "type": "string" 174 | } 175 | }, 176 | { 177 | "name": "nick_name", 178 | "in": "query", 179 | "description": "姓名", 180 | "required": false, 181 | "schema": { 182 | "type": "string" 183 | } 184 | }, 185 | { 186 | "name": "avatar", 187 | "in": "query", 188 | "description": "头像", 189 | "required": false, 190 | "schema": { 191 | "type": "string" 192 | } 193 | }, 194 | { 195 | "name": "password", 196 | "in": "query", 197 | "description": "密码", 198 | "required": false, 199 | "schema": { 200 | "type": "string" 201 | } 202 | }, 203 | { 204 | "name": "email", 205 | "in": "query", 206 | "description": "邮箱", 207 | "required": false, 208 | "schema": { 209 | "type": "string" 210 | } 211 | }, 212 | { 213 | "name": "telephone", 214 | "in": "query", 215 | "description": "手机号", 216 | "required": false, 217 | "schema": { 218 | "type": "string" 219 | } 220 | }, 221 | { 222 | "name": "state", 223 | "in": "query", 224 | "description": "状态", 225 | "required": false, 226 | "schema": { 227 | "type": "integer" 228 | } 229 | } 230 | ], 231 | "responses": { 232 | 233 | }, 234 | "x-run-in-apifox": "", 235 | "security": [ 236 | { 237 | "bearer": [] 238 | } 239 | ] 240 | }, 241 | "put": { 242 | "summary": "修改sysAdmin", 243 | "x-apifox-folder": "sysAdmin", 244 | "x-apifox-status": "developing", 245 | "deprecated": false, 246 | "description": "", 247 | "tags": [ 248 | "sysAdmin" 249 | ], 250 | "requestBody": { 251 | "content": { 252 | "application/json": { 253 | "schema": { 254 | "type": "object", 255 | "properties": { 256 | "id": { 257 | "type": "string", 258 | "description": "系统管理员ID" 259 | }, 260 | "name": { 261 | "type": "string", 262 | "description": "用户名" 263 | }, 264 | "nick_name": { 265 | "type": "string", 266 | "description": "姓名" 267 | }, 268 | "avatar": { 269 | "type": "string", 270 | "description": "头像" 271 | }, 272 | "password": { 273 | "type": "string", 274 | "description": "密码" 275 | }, 276 | "email": { 277 | "type": "string", 278 | "description": "邮箱" 279 | }, 280 | "telephone": { 281 | "type": "string", 282 | "description": "手机号" 283 | }, 284 | "state": { 285 | "type": "integer", 286 | "description": "状态" 287 | } 288 | }, 289 | "required": [ 290 | "id" 291 | ] 292 | } 293 | } 294 | } 295 | }, 296 | "responses": { 297 | 298 | }, 299 | "x-run-in-apifox": "", 300 | "security": [ 301 | { 302 | "bearer": [] 303 | } 304 | ] 305 | } 306 | } 307 | }, 308 | "components": { 309 | "schemas": {} 310 | } 311 | } -------------------------------------------------------------------------------- /model/sql/rpc/sysadmin.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package adminclient; 4 | 5 | option go_package = "./adminclient"; 6 | 7 | //SysAdmin start------------------- 8 | 9 | // SysAdmin 添加 10 | message SysAdminAddReq{ 11 | string created_name = 1; // 创建人 12 | string name = 2; // 用户名 13 | string nick_name = 3; // 姓名 14 | string avatar = 4; // 头像 15 | string password = 5; // 密码 16 | string email = 6; // 邮箱 17 | string telephone = 7; // 手机号 18 | int64 state = 8; // 状态 19 | } 20 | 21 | // SysAdmin 删除 22 | message SysAdminDeleteReq{ 23 | string id = 1; // 系统管理员ID 24 | string deleted_name = 2; // 删除人 25 | } 26 | 27 | // SysAdmin 更新 28 | message SysAdminUpdateReq{ 29 | string id = 1; // 系统管理员ID 30 | string updated_name = 2; // 更新人 31 | string name = 3; // 用户名 32 | string nick_name = 4; // 姓名 33 | string avatar = 5; // 头像 34 | string password = 6; // 密码 35 | string email = 7; // 邮箱 36 | string telephone = 8; // 手机号 37 | int64 state = 9; // 状态 38 | } 39 | 40 | // SysAdmin 单个查询 41 | message SysAdminFindOneReq{ 42 | string id = 1; // 系统管理员ID 43 | } 44 | 45 | // SysAdmin 单个查询返回 46 | message SysAdminFindOneResp{ 47 | string id = 1; // 系统管理员ID 48 | int64 created_at = 2; // 创建时间 49 | int64 updated_at = 3; // 更新时间 50 | string created_name = 4; // 创建人 51 | string updated_name = 5; // 更新人 52 | string name = 6; // 用户名 53 | string nick_name = 7; // 姓名 54 | string avatar = 8; // 头像 55 | string password = 9; // 密码 56 | string email = 10; // 邮箱 57 | string telephone = 11; // 手机号 58 | int64 state = 12; // 状态 59 | } 60 | 61 | 62 | // SysAdmin 分页查询 63 | message SysAdminListReq{ 64 | int64 current = 1; // 页码 65 | int64 page_size = 2; // 页数 66 | string name = 3; // 用户名 67 | string nick_name = 4; // 姓名 68 | string avatar = 5; // 头像 69 | string password = 6; // 密码 70 | string email = 7; // 邮箱 71 | string telephone = 8; // 手机号 72 | int64 state = 9; // 状态 73 | } 74 | 75 | // SysAdmin 分页查询返回 76 | message SysAdminListResp{ 77 | int64 total = 1; // 总数 78 | repeated SysAdminListData list = 2; // 内容 79 | } 80 | 81 | // SysAdmin 列表信息 82 | message SysAdminListData{ 83 | string id = 1; // 系统管理员ID 84 | int64 created_at = 2; // 创建时间 85 | int64 updated_at = 3; // 更新时间 86 | string created_name = 4; // 创建人 87 | string updated_name = 5; // 更新人 88 | string name = 6; // 用户名 89 | string nick_name = 7; // 姓名 90 | string avatar = 8; // 头像 91 | string password = 9; // 密码 92 | string email = 10; // 邮箱 93 | string telephone = 11; // 手机号 94 | int64 state = 12; // 状态 95 | } 96 | 97 | //SysAdmin end--------------------- 98 | 99 | service Admin { 100 | 101 | rpc SysAdminAdd(SysAdminAddReq) returns(CommonResp); 102 | rpc SysAdminDelete(SysAdminDeleteReq) returns(CommonResp); 103 | rpc SysAdminUpdate(SysAdminUpdateReq) returns(CommonResp); 104 | rpc SysAdminFindOne(SysAdminFindOneReq) returns(SysAdminFindOneResp); 105 | rpc SysAdminList(SysAdminListReq) returns(SysAdminListResp); 106 | 107 | } -------------------------------------------------------------------------------- /model/sql/rpc/sysadminaddlogic.go: -------------------------------------------------------------------------------- 1 | func (l *SysAdminAddLogic) SysAdminAdd(in *adminclient.SysAdminAddReq) (*adminclient.CommonResp, error) { 2 | 3 | _, err := l.svcCtx.SysAdminModel.Insert(l.ctx,&model.SysAdmin{ 4 | Id: uuid.NewV4().String(), // ID 5 | CreatedAt: time.Now(), // 创建时间 6 | CreatedName: in.CreatedName, // 创建人 7 | Name: in.Name, // 用户名 8 | NickName: in.NickName, // 姓名 9 | Avatar: sql.NullString{String: in.Avatar, Valid: in.Avatar != ""}, // 头像 10 | Password: in.Password, // 密码 11 | Email: in.Email, // 邮箱 12 | Telephone: in.Telephone, // 手机号 13 | State: in.State, // 状态 14 | }) 15 | if err != nil { 16 | return nil, err 17 | } 18 | 19 | return &adminclient.CommonResp{}, nil 20 | } 21 | -------------------------------------------------------------------------------- /model/sql/rpc/sysadmindellogic.go: -------------------------------------------------------------------------------- 1 | func (l *SysAdminDeleteLogic) SysAdminDelete(in *adminclient.SysAdminDeleteReq) (*adminclient.CommonResp, error) { 2 | 3 | res, err := l.svcCtx.SysAdminModel.FindOne(l.ctx,in.Id) 4 | if err != nil { 5 | if errors.Is(err, sqlc.ErrNotFound) { 6 | return nil, fmt.Errorf("SysAdmin没有该ID:%v" ,in.Id) 7 | } 8 | return nil, err 9 | } 10 | 11 | // 判断该数据是否被删除 12 | if res.DeletedAt.Valid == true { 13 | return nil, fmt.Errorf("SysAdmin该ID已被删除:%v",in.Id) 14 | } 15 | 16 | 17 | res.DeletedAt.Time = time.Now() 18 | res.DeletedAt.Valid = true 19 | res.DeletedName.String = in.DeletedName 20 | res.DeletedName.Valid = true 21 | 22 | err = l.svcCtx.SysAdminModel.Update(l.ctx,res) 23 | if err != nil { 24 | return nil, err 25 | } 26 | 27 | return &adminclient.CommonResp{}, nil 28 | } -------------------------------------------------------------------------------- /model/sql/rpc/sysadminfindonelogic.go: -------------------------------------------------------------------------------- 1 | func (l *SysAdminFindOneLogic) SysAdminFindOne(in *adminclient.SysAdminFindOneReq) (*adminclient.SysAdminFindOneResp, error) { 2 | 3 | res, err := l.svcCtx.SysAdminModel.FindOne(l.ctx,in.Id) 4 | if err != nil { 5 | if errors.Is(err, sqlc.ErrNotFound) { 6 | return nil, fmt.Errorf("SysAdmin没有该ID:%v" ,in.Id) 7 | } 8 | return nil, err 9 | } 10 | 11 | // 判断该数据是否被删除 12 | if res.DeletedAt.Valid == true { 13 | return nil, fmt.Errorf("SysAdmin该ID已被删除:%v",in.Id) 14 | } 15 | 16 | 17 | return &adminclient.SysAdminFindOneResp{ 18 | Id: res.Id, //系统管理员ID 19 | CreatedAt: res.CreatedAt.UnixMilli(), //创建时间 20 | UpdatedAt: res.UpdatedAt.Time.UnixMilli(), //更新时间 21 | CreatedName: res.CreatedName, //创建人 22 | UpdatedName: res.UpdatedName.String, //更新人 23 | Name: res.Name, //用户名 24 | NickName: res.NickName, //姓名 25 | Avatar: res.Avatar.String, //头像 26 | Password: res.Password, //密码 27 | Email: res.Email, //邮箱 28 | Telephone: res.Telephone, //手机号 29 | State: res.State, //状态 30 | }, nil 31 | 32 | } -------------------------------------------------------------------------------- /model/sql/rpc/sysadminlistlogic.go: -------------------------------------------------------------------------------- 1 | func (l *SysAdminListLogic) SysAdminList(in *adminclient.SysAdminListReq) (*adminclient.SysAdminListResp, error) { 2 | 3 | whereBuilder := l.svcCtx.SysAdminModel.RowBuilder() 4 | 5 | whereBuilder = whereBuilder.Where("deleted_at is null") 6 | whereBuilder = whereBuilder.OrderBy("created_at DESC, id DESC") 7 | 8 | 9 | 10 | // 用户名 11 | if len(in.Name) > 0 { 12 | whereBuilder = whereBuilder.Where(squirrel.Like{ 13 | "name ": "%"+in.Name+"%", 14 | }) 15 | } 16 | // 姓名 17 | if len(in.NickName) > 0 { 18 | whereBuilder = whereBuilder.Where(squirrel.Like{ 19 | "nick_name ": "%"+in.NickName+"%", 20 | }) 21 | } 22 | // 头像 23 | if len(in.Avatar) > 0 { 24 | whereBuilder = whereBuilder.Where(squirrel.Like{ 25 | "avatar ": "%"+in.Avatar+"%", 26 | }) 27 | } 28 | // 密码 29 | if len(in.Password) > 0 { 30 | whereBuilder = whereBuilder.Where(squirrel.Like{ 31 | "password ": "%"+in.Password+"%", 32 | }) 33 | } 34 | // 邮箱 35 | if len(in.Email) > 0 { 36 | whereBuilder = whereBuilder.Where(squirrel.Like{ 37 | "email ": "%"+in.Email+"%", 38 | }) 39 | } 40 | // 手机号 41 | if len(in.Telephone) > 0 { 42 | whereBuilder = whereBuilder.Where(squirrel.Like{ 43 | "telephone ": "%"+in.Telephone+"%", 44 | }) 45 | } 46 | // 状态 47 | if in.State != 99 { 48 | whereBuilder = whereBuilder.Where(squirrel.Eq{ 49 | "state ": in.State, 50 | }) 51 | } 52 | 53 | all, err := l.svcCtx.SysAdminModel.FindList(l.ctx, whereBuilder, in.Current, in.PageSize) 54 | if err != nil { 55 | return nil, err 56 | } 57 | 58 | countBuilder := l.svcCtx.SysAdminModel.CountBuilder("id") 59 | 60 | countBuilder = countBuilder.Where("deleted_at is null") 61 | 62 | 63 | 64 | // 用户名 65 | if len(in.Name) > 0 { 66 | countBuilder = countBuilder.Where(squirrel.Like{ 67 | "name ": "%"+in.Name+"%", 68 | }) 69 | } 70 | // 姓名 71 | if len(in.NickName) > 0 { 72 | countBuilder = countBuilder.Where(squirrel.Like{ 73 | "nick_name ": "%"+in.NickName+"%", 74 | }) 75 | } 76 | // 头像 77 | if len(in.Avatar) > 0 { 78 | countBuilder = countBuilder.Where(squirrel.Like{ 79 | "avatar ": "%"+in.Avatar+"%", 80 | }) 81 | } 82 | // 密码 83 | if len(in.Password) > 0 { 84 | countBuilder = countBuilder.Where(squirrel.Like{ 85 | "password ": "%"+in.Password+"%", 86 | }) 87 | } 88 | // 邮箱 89 | if len(in.Email) > 0 { 90 | countBuilder = countBuilder.Where(squirrel.Like{ 91 | "email ": "%"+in.Email+"%", 92 | }) 93 | } 94 | // 手机号 95 | if len(in.Telephone) > 0 { 96 | countBuilder = countBuilder.Where(squirrel.Like{ 97 | "telephone ": "%"+in.Telephone+"%", 98 | }) 99 | } 100 | // 状态 101 | if in.State != 99 { 102 | countBuilder = countBuilder.Where(squirrel.Eq{ 103 | "state ": in.State, 104 | }) 105 | } 106 | count, err := l.svcCtx.SysAdminModel.FindCount(l.ctx, countBuilder) 107 | if err != nil { 108 | return nil, err 109 | } 110 | 111 | var list []*adminclient.SysAdminListData 112 | for _, item := range all { 113 | list = append(list, &adminclient.SysAdminListData{ 114 | Id: item.Id, //系统管理员ID 115 | CreatedAt: item.CreatedAt.UnixMilli(), //创建时间 116 | UpdatedAt: item.UpdatedAt.Time.UnixMilli(), //更新时间 117 | CreatedName: item.CreatedName, //创建人 118 | UpdatedName: item.UpdatedName.String, //更新人 119 | Name: item.Name, //用户名 120 | NickName: item.NickName, //姓名 121 | Avatar: item.Avatar.String, //头像 122 | Password: item.Password, //密码 123 | Email: item.Email, //邮箱 124 | Telephone: item.Telephone, //手机号 125 | State: item.State, //状态 126 | }) 127 | } 128 | 129 | return &adminclient.SysAdminListResp{ 130 | Total: count, 131 | List: list, 132 | }, nil 133 | } 134 | -------------------------------------------------------------------------------- /model/sql/rpc/sysadminuplogic.go: -------------------------------------------------------------------------------- 1 | func (l *SysAdminUpdateLogic) SysAdminUpdate(in *adminclient.SysAdminUpdateReq) (*adminclient.CommonResp, error) { 2 | 3 | res, err := l.svcCtx.SysAdminModel.FindOne(l.ctx,in.Id) 4 | if err != nil { 5 | if errors.Is(err, sqlc.ErrNotFound) { 6 | return nil,fmt.Errorf("SysAdmin没有该ID: %v" , in.Id) 7 | } 8 | return nil, err 9 | } 10 | 11 | // 判断该数据是否被删除 12 | if res.DeletedAt.Valid == true { 13 | return nil, errors.New("SysAdmin该ID已被删除:" + in.Id) 14 | } 15 | 16 | 17 | // 用户名 18 | if len(in.Name) > 0 { 19 | res.Name = in.Name 20 | } 21 | // 姓名 22 | if len(in.NickName) > 0 { 23 | res.NickName = in.NickName 24 | } 25 | // 头像 26 | if len(in.Avatar) > 0 { 27 | res.Avatar.String = in.Avatar 28 | res.Avatar.Valid = true 29 | } 30 | // 密码 31 | if len(in.Password) > 0 { 32 | res.Password = in.Password 33 | } 34 | // 邮箱 35 | if len(in.Email) > 0 { 36 | res.Email = in.Email 37 | } 38 | // 手机号 39 | if len(in.Telephone) > 0 { 40 | res.Telephone = in.Telephone 41 | } 42 | // 状态 43 | if in.State != 0 { 44 | res.State = in.State 45 | } 46 | 47 | res.UpdatedName.String = in.UpdatedName 48 | res.UpdatedName.Valid = true 49 | res.UpdatedAt.Time = time.Now() 50 | res.UpdatedAt.Valid = true 51 | 52 | err = l.svcCtx.SysAdminModel.Update(l.ctx,res) 53 | 54 | if err != nil { 55 | return nil, err 56 | } 57 | return &adminclient.CommonResp{}, nil 58 | 59 | } -------------------------------------------------------------------------------- /model/sql/sys_admin.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat Premium Data Transfer 3 | 4 | Source Server : 内部docker数据库 5 | Source Server Type : MySQL 6 | Source Server Version : 80028 7 | Source Host : localhost:33069 8 | Source Schema : twy_db 9 | 10 | Target Server Type : MySQL 11 | Target Server Version : 80028 12 | File Encoding : 65001 13 | 14 | Date: 28/07/2022 13:14:36 15 | */ 16 | 17 | SET NAMES utf8mb4; 18 | SET FOREIGN_KEY_CHECKS = 0; 19 | 20 | -- ---------------------------- 21 | -- Table structure for sys_admin 22 | -- ---------------------------- 23 | DROP TABLE IF EXISTS `sys_admin`; 24 | CREATE TABLE `sys_admin` ( 25 | `id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '系统管理员ID', 26 | `created_at` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '创建时间', 27 | `updated_at` timestamp(0) NULL DEFAULT NULL COMMENT '更新时间', 28 | `deleted_at` timestamp(0) NULL DEFAULT NULL COMMENT '删除时间', 29 | `created_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '创建人', 30 | `updated_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人', 31 | `deleted_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '删除人', 32 | `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名', 33 | `nick_name` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名', 34 | `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '头像', 35 | `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码', 36 | `email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '邮箱', 37 | `telephone` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '手机号', 38 | `state` tinyint(0) NOT NULL COMMENT '状态', 39 | PRIMARY KEY (`id`) USING BTREE 40 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 41 | 42 | SET FOREIGN_KEY_CHECKS = 1; 43 | -------------------------------------------------------------------------------- /parser/parser.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "fmt" 5 | "github.com/zeromicro/ddl-parser/console" 6 | "github.com/zeromicro/ddl-parser/parser" 7 | "gozc/converter" 8 | 9 | "github.com/zeromicro/go-zero/core/collection" 10 | "gozc/tools/stringx" 11 | "path/filepath" 12 | "strings" 13 | ) 14 | 15 | // Parse parses ddl into golang structure 16 | func Parse(filename string) ([]*Table, error) { 17 | p := parser.NewParser() 18 | tables, err := p.From(filename) 19 | if err != nil { 20 | return nil, err 21 | } 22 | 23 | nameOriginals := parseNameOriginal(tables) 24 | indexNameGen := func(column ...string) string { 25 | return strings.Join(column, "_") 26 | } 27 | 28 | prefix := filepath.Base(filename) 29 | var list []*Table 30 | for indexTable, e := range tables { 31 | var ( 32 | primaryColumn string 33 | primaryColumnSet = collection.NewSet() 34 | uniqueKeyMap = make(map[string][]string) 35 | normalKeyMap = make(map[string][]string) 36 | columns = e.Columns 37 | ) 38 | 39 | for _, column := range columns { 40 | if column.Constraint != nil { 41 | if column.Constraint.Primary { 42 | primaryColumnSet.AddStr(column.Name) 43 | } 44 | 45 | if column.Constraint.Unique { 46 | indexName := indexNameGen(column.Name, "unique") 47 | uniqueKeyMap[indexName] = []string{column.Name} 48 | } 49 | 50 | if column.Constraint.Key { 51 | indexName := indexNameGen(column.Name, "idx") 52 | uniqueKeyMap[indexName] = []string{column.Name} 53 | } 54 | } 55 | } 56 | 57 | for _, e := range e.Constraints { 58 | if len(e.ColumnPrimaryKey) > 1 { 59 | return nil, fmt.Errorf("%s: unexpected join primary key", prefix) 60 | } 61 | 62 | if len(e.ColumnPrimaryKey) == 1 { 63 | primaryColumn = e.ColumnPrimaryKey[0] 64 | primaryColumnSet.AddStr(e.ColumnPrimaryKey[0]) 65 | } 66 | 67 | if len(e.ColumnUniqueKey) > 0 { 68 | list := append([]string(nil), e.ColumnUniqueKey...) 69 | list = append(list, "unique") 70 | indexName := indexNameGen(list...) 71 | uniqueKeyMap[indexName] = e.ColumnUniqueKey 72 | } 73 | } 74 | 75 | if primaryColumnSet.Count() > 1 { 76 | return nil, fmt.Errorf("%s: unexpected join primary key", prefix) 77 | } 78 | 79 | primaryKey, fieldM, err := convertColumns(columns, primaryColumn) 80 | if err != nil { 81 | return nil, err 82 | } 83 | 84 | var fields []*Field 85 | // sort 86 | for indexColumn, c := range columns { 87 | field, ok := fieldM[c.Name] 88 | if ok { 89 | field.NameOriginal = nameOriginals[indexTable][indexColumn] 90 | fields = append(fields, field) 91 | } 92 | } 93 | 94 | var ( 95 | uniqueIndex = make(map[string][]*Field) 96 | normalIndex = make(map[string][]*Field) 97 | ) 98 | 99 | for indexName, each := range uniqueKeyMap { 100 | for _, columnName := range each { 101 | uniqueIndex[indexName] = append(uniqueIndex[indexName], fieldM[columnName]) 102 | } 103 | } 104 | 105 | for indexName, each := range normalKeyMap { 106 | for _, columnName := range each { 107 | normalIndex[indexName] = append(normalIndex[indexName], fieldM[columnName]) 108 | } 109 | } 110 | 111 | checkDuplicateUniqueIndex(uniqueIndex, e.Name) 112 | 113 | list = append(list, &Table{ 114 | Name: stringx.From(e.Name), 115 | PrimaryKey: primaryKey, 116 | UniqueIndex: uniqueIndex, 117 | Fields: fields, 118 | }) 119 | } 120 | 121 | return list, nil 122 | } 123 | 124 | func parseNameOriginal(ts []*parser.Table) (nameOriginals [][]string) { 125 | var columns []string 126 | 127 | for _, t := range ts { 128 | columns = []string{} 129 | for _, c := range t.Columns { 130 | columns = append(columns, c.Name) 131 | } 132 | nameOriginals = append(nameOriginals, columns) 133 | } 134 | return 135 | } 136 | 137 | type ( 138 | Table struct { 139 | Name stringx.String 140 | Db stringx.String 141 | PrimaryKey Primary 142 | UniqueIndex map[string][]*Field 143 | Fields []*Field 144 | } 145 | 146 | Primary struct { 147 | Field 148 | AutoIncrement bool 149 | } 150 | 151 | Field struct { 152 | NameOriginal string 153 | Name stringx.String 154 | DataType string 155 | Comment string 156 | SeqInIndex int 157 | OrdinalPosition int 158 | } 159 | ) 160 | 161 | func convertColumns(columns []*parser.Column, primaryColumn string) (Primary, map[string]*Field, error) { 162 | var ( 163 | primaryKey Primary 164 | fieldM = make(map[string]*Field) 165 | log = console.NewColorConsole() 166 | ) 167 | 168 | for _, column := range columns { 169 | if column == nil { 170 | continue 171 | } 172 | 173 | var ( 174 | comment string 175 | isDefaultNull bool 176 | ) 177 | 178 | if column.Constraint != nil { 179 | comment = column.Constraint.Comment 180 | isDefaultNull = !column.Constraint.NotNull 181 | if !column.Constraint.NotNull && column.Constraint.HasDefaultValue { 182 | isDefaultNull = false 183 | } 184 | 185 | if column.Name == primaryColumn { 186 | isDefaultNull = false 187 | } 188 | } 189 | 190 | dataType, err := converter.ConvertDataType(column.DataType.Type(), isDefaultNull, column.DataType.Unsigned()) 191 | if err != nil { 192 | return Primary{}, nil, err 193 | } 194 | 195 | if column.Constraint != nil { 196 | if column.Name == primaryColumn { 197 | if !column.Constraint.AutoIncrement && dataType == "int64" { 198 | log.Warning("[convertColumns]: The primary key %q is recommended to add constraint `AUTO_INCREMENT`", column.Name) 199 | } 200 | } else if column.Constraint.NotNull && !column.Constraint.HasDefaultValue { 201 | log.Warning("[convertColumns]: The column %q is recommended to add constraint `DEFAULT`", column.Name) 202 | } 203 | } 204 | 205 | var field Field 206 | field.Name = stringx.From(column.Name) 207 | field.DataType = dataType 208 | field.Comment = stringx.TrimNewLine(comment) 209 | 210 | if field.Name.Source() == primaryColumn { 211 | primaryKey = Primary{ 212 | Field: field, 213 | } 214 | if column.Constraint != nil { 215 | primaryKey.AutoIncrement = column.Constraint.AutoIncrement 216 | } 217 | } 218 | 219 | fieldM[field.Name.Source()] = &field 220 | } 221 | return primaryKey, fieldM, nil 222 | } 223 | 224 | func checkDuplicateUniqueIndex(uniqueIndex map[string][]*Field, tableName string) { 225 | log := console.NewColorConsole() 226 | uniqueSet := collection.NewSet() 227 | for k, i := range uniqueIndex { 228 | var list []string 229 | for _, e := range i { 230 | list = append(list, e.Name.Source()) 231 | } 232 | 233 | joinRet := strings.Join(list, ",") 234 | if uniqueSet.Contains(joinRet) { 235 | log.Warning("[checkDuplicateUniqueIndex]: table %s: duplicate unique index %s", tableName, joinRet) 236 | delete(uniqueIndex, k) 237 | continue 238 | } 239 | 240 | uniqueSet.AddStr(joinRet) 241 | } 242 | } 243 | 244 | const timeImport = "time.Time" 245 | 246 | func (t *Table) ContainsTime() bool { 247 | for _, item := range t.Fields { 248 | if item.DataType == timeImport { 249 | return true 250 | } 251 | } 252 | return false 253 | } 254 | -------------------------------------------------------------------------------- /tools/pathx/pathx.go: -------------------------------------------------------------------------------- 1 | package pathx 2 | 3 | import ( 4 | "errors" 5 | "io/ioutil" 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | // FileExists returns true if the specified file is exists. 11 | func FileExists(file string) bool { 12 | _, err := os.Stat(file) 13 | return err == nil 14 | } 15 | 16 | // LoadTemplate gets template content by the specified file. 17 | func LoadTemplate(category, file, builtin string) (string, error) { 18 | dir, err := GetTemplateDir(category) 19 | if err != nil { 20 | return "", err 21 | } 22 | 23 | file = filepath.Join(dir, file) 24 | if !FileExists(file) { 25 | return builtin, nil 26 | } 27 | 28 | content, err := ioutil.ReadFile(file) 29 | if err != nil { 30 | return "", err 31 | } 32 | 33 | return string(content), nil 34 | } 35 | 36 | var goctlHome string 37 | 38 | // GetTemplateDir returns the category path value in GoctlHome where could get it by GetGoctlHome. 39 | func GetTemplateDir(category string) (string, error) { 40 | env := os.Getenv("GOZC_PATH") 41 | if env == "" { 42 | return "", errors.New("请先设置环境变量GOZC_PATH路径指向Tpl文件夹") 43 | } 44 | 45 | return filepath.Join(env, category), nil 46 | } 47 | 48 | const ( 49 | NL = "\n" 50 | goctlDir = ".goctl" 51 | gitDir = ".git" 52 | autoCompleteDir = ".auto_complete" 53 | cacheDir = "cache" 54 | ) 55 | -------------------------------------------------------------------------------- /tools/stringx/stringx.go: -------------------------------------------------------------------------------- 1 | package stringx 2 | 3 | import ( 4 | "bytes" 5 | "strings" 6 | "unicode" 7 | ) 8 | 9 | var WhiteSpace = []rune{'\n', '\t', '\f', '\v', ' '} 10 | 11 | // String provides for converting the source text into other spell case,like lower,snake,camel 12 | type String struct { 13 | source string 14 | } 15 | 16 | // From converts the input text to String and returns it 17 | func From(data string) String { 18 | return String{source: data} 19 | } 20 | 21 | // IsEmptyOrSpace returns true if the length of the string value is 0 after call strings.TrimSpace, or else returns false 22 | func (s String) IsEmptyOrSpace() bool { 23 | if len(s.source) == 0 { 24 | return true 25 | } 26 | if strings.TrimSpace(s.source) == "" { 27 | return true 28 | } 29 | return false 30 | } 31 | 32 | // Lower calls the strings.ToLower 33 | func (s String) Lower() string { 34 | return strings.ToLower(s.source) 35 | } 36 | 37 | // Upper calls the strings.ToUpper 38 | func (s String) Upper() string { 39 | return strings.ToUpper(s.source) 40 | } 41 | 42 | // ReplaceAll calls the strings.ReplaceAll 43 | func (s String) ReplaceAll(old, new string) string { 44 | return strings.Replace(s.source, old, new, -1) 45 | } 46 | 47 | // Source returns the source string value 48 | func (s String) Source() string { 49 | return s.source 50 | } 51 | 52 | // Title calls the strings.Title 53 | func (s String) Title() string { 54 | if s.IsEmptyOrSpace() { 55 | return s.source 56 | } 57 | return strings.Title(s.source) 58 | } 59 | 60 | // ToCamel converts the input text into camel case 61 | func (s String) ToCamel() string { 62 | list := s.splitBy(func(r rune) bool { 63 | return r == '_' 64 | }, true) 65 | var target []string 66 | for _, item := range list { 67 | target = append(target, From(item).Title()) 68 | } 69 | return strings.Join(target, "") 70 | } 71 | 72 | // ToCamelWithStartLower converts the input text into camel case 73 | func (s String) ToCamelWithStartLower() string { 74 | list := s.splitBy(func(r rune) bool { 75 | return r == '_' 76 | }, true) 77 | var target []string 78 | for i, item := range list { 79 | if i != 0 { 80 | target = append(target, From(item).Title()) 81 | } else { 82 | target = append(target, item) 83 | } 84 | 85 | } 86 | return strings.Join(target, "") 87 | } 88 | 89 | // ToSnake converts the input text into snake case 90 | func (s String) ToSnake() string { 91 | list := s.splitBy(unicode.IsUpper, false) 92 | var target []string 93 | for _, item := range list { 94 | target = append(target, From(item).Lower()) 95 | } 96 | return strings.Join(target, "_") 97 | } 98 | 99 | // Untitle return the original string if rune is not letter at index 0 100 | func (s String) Untitle() string { 101 | if s.IsEmptyOrSpace() { 102 | return s.source 103 | } 104 | r := rune(s.source[0]) 105 | if !unicode.IsUpper(r) && !unicode.IsLower(r) { 106 | return s.source 107 | } 108 | return string(unicode.ToLower(r)) + s.source[1:] 109 | } 110 | 111 | // it will not ignore spaces 112 | func (s String) splitBy(fn func(r rune) bool, remove bool) []string { 113 | if s.IsEmptyOrSpace() { 114 | return nil 115 | } 116 | var list []string 117 | buffer := new(bytes.Buffer) 118 | for _, r := range s.source { 119 | if fn(r) { 120 | if buffer.Len() != 0 { 121 | list = append(list, buffer.String()) 122 | buffer.Reset() 123 | } 124 | if !remove { 125 | buffer.WriteRune(r) 126 | } 127 | continue 128 | } 129 | buffer.WriteRune(r) 130 | } 131 | if buffer.Len() != 0 { 132 | list = append(list, buffer.String()) 133 | } 134 | return list 135 | } 136 | 137 | func ContainsAny(s string, runes ...rune) bool { 138 | if len(runes) == 0 { 139 | return true 140 | } 141 | tmp := make(map[rune]struct{}, len(runes)) 142 | for _, r := range runes { 143 | tmp[r] = struct{}{} 144 | } 145 | 146 | for _, r := range s { 147 | if _, ok := tmp[r]; ok { 148 | return true 149 | } 150 | } 151 | return false 152 | } 153 | 154 | func ContainsWhiteSpace(s string) bool { 155 | return ContainsAny(s, WhiteSpace...) 156 | } 157 | 158 | // TrimNewLine trims \r and \n chars. 159 | func TrimNewLine(s string) string { 160 | return strings.NewReplacer("\r", "", "\n", "").Replace(s) 161 | } 162 | -------------------------------------------------------------------------------- /tpl/api/api.tpl: -------------------------------------------------------------------------------- 1 | syntax = "v1" 2 | 3 | 4 | type ( 5 | {{.filename}}AddRequest { 6 | {{.Add}} 7 | } 8 | 9 | {{.filename}}DelRequest { 10 | {{.Del}} 11 | } 12 | 13 | {{.filename}}UpRequest { 14 | {{.Up}} 15 | } 16 | 17 | 18 | {{.filename}}ListRequest { 19 | {{.List}} 20 | } 21 | 22 | {{.filename}}InfoRequest { 23 | {{.Info}} 24 | } 25 | 26 | ) 27 | 28 | @server( 29 | //声明当前service下所有路由需要jwt鉴权,且会自动生成包含jwt逻辑的代码 30 | jwt: Auth 31 | group: {{.xfilename}} 32 | ) 33 | 34 | service {{.Amodelname}} { 35 | 36 | // 添加 37 | @handler {{.filename}}Add 38 | post /{{.modelname}}/{{.xfilename}} ({{.filename}}AddRequest) returns (Response) 39 | 40 | // 删除 41 | @handler {{.filename}}Del 42 | delete /{{.modelname}}/{{.xfilename}}/:id ({{.filename}}DelRequest) returns (Response) 43 | 44 | // 更新 45 | @handler {{.filename}}Up 46 | put /{{.modelname}}/{{.xfilename}} ({{.filename}}UpRequest) returns (Response) 47 | 48 | // 分页查询 49 | @handler {{.filename}}List 50 | get /{{.modelname}}/{{.xfilename}} ({{.filename}}ListRequest) returns (Response) 51 | 52 | // 查询详细信息 53 | @handler {{.filename}}Info 54 | get /{{.modelname}}/{{.xfilename}}Info ({{.filename}}InfoRequest) returns (Response) 55 | } -------------------------------------------------------------------------------- /tpl/api/delete.tpl: -------------------------------------------------------------------------------- 1 | func (l *{{.filename}}DelLogic) {{.filename}}Del(req *types.{{.filename}}DelRequest) (*types.Response, error) { 2 | // 用户登录信息 3 | tokenData := jwtx.ParseToken(l.ctx) 4 | 5 | _, err := l.svcCtx.{{.modelname}}Rpc.{{.filename}}Delete(l.ctx, &{{.xmodelname}}client.{{.filename}}DeleteReq{ 6 | {{.data}} 7 | }) 8 | if err != nil { 9 | return nil, common.NewDefaultError(err.Error()) 10 | } 11 | return &types.Response{ 12 | Code: 0, 13 | Msg: msg.Success, 14 | Data: nil, 15 | }, nil 16 | } 17 | -------------------------------------------------------------------------------- /tpl/api/find-list.tpl: -------------------------------------------------------------------------------- 1 | func (l *{{.filename}}ListLogic) {{.filename}}List(req *types.{{.filename}}ListRequest) (*types.Response, error) { 2 | // 用户登录信息 3 | tokenData := jwtx.ParseToken(l.ctx) 4 | 5 | all, err := l.svcCtx.{{.modelname}}Rpc.{{.filename}}List(l.ctx, &{{.xmodelname}}client.{{.filename}}ListReq{ 6 | {{.data}} 7 | }) 8 | if err != nil { 9 | return nil, common.NewDefaultError(err.Error()) 10 | } 11 | 12 | var result {{.filename}}ListResp 13 | _ = copier.Copy(&result, all) 14 | 15 | return &types.Response{ 16 | Code: 0, 17 | Msg: msg.Success, 18 | Data: result, 19 | }, nil 20 | } 21 | 22 | 23 | type {{.filename}}ListResp struct { 24 | Total int64 `json:"total"` 25 | List []*{{.filename}}DataList `json:"list"` 26 | } 27 | 28 | type {{.filename}}DataList struct { 29 | {{.modeldata}} 30 | } 31 | 32 | -------------------------------------------------------------------------------- /tpl/api/find-one.tpl: -------------------------------------------------------------------------------- 1 | func (l *{{.filename}}InfoLogic) {{.filename}}Info(req *types.{{.filename}}InfoRequest) (*types.Response, error) { 2 | // 用户登录信息 3 | tokenData := jwtx.ParseToken(l.ctx) 4 | 5 | res, err := l.svcCtx.{{.modelname}}Rpc.{{.filename}}FindOne(l.ctx, &{{.xmodelname}}client.{{.filename}}FindOneReq{ 6 | {{.data}} 7 | }) 8 | if err != nil { 9 | return nil, common.NewDefaultError(err.Error()) 10 | } 11 | 12 | var result {{.filename}}FindOneResp 13 | _ = copier.Copy(&result, res) 14 | 15 | return &types.Response{ 16 | Code: 0, 17 | Msg: msg.Success, 18 | Data: result, 19 | }, nil 20 | } 21 | 22 | 23 | type {{.filename}}FindOneResp struct { 24 | {{.modeldata}} 25 | } 26 | 27 | -------------------------------------------------------------------------------- /tpl/api/insert.tpl: -------------------------------------------------------------------------------- 1 | func (l *{{.filename}}AddLogic) {{.filename}}Add(req *types.{{.filename}}AddRequest) (*types.Response, error) { 2 | // 用户登录信息 3 | tokenData := jwtx.ParseToken(l.ctx) 4 | 5 | _, err := l.svcCtx.{{.modelname}}Rpc.{{.filename}}Add(l.ctx, &{{.xmodelname}}client.{{.filename}}AddReq{ 6 | {{.data}} 7 | }) 8 | if err != nil { 9 | return nil, common.NewDefaultError(err.Error()) 10 | } 11 | return &types.Response{ 12 | Code: 0, 13 | Msg: msg.Success, 14 | Data: nil, 15 | }, nil 16 | } 17 | -------------------------------------------------------------------------------- /tpl/api/update.tpl: -------------------------------------------------------------------------------- 1 | func (l *{{.filename}}UpLogic) {{.filename}}Up(req *types.{{.filename}}UpRequest) (*types.Response, error) { 2 | // 用户登录信息 3 | tokenData := jwtx.ParseToken(l.ctx) 4 | 5 | _, err := l.svcCtx.{{.modelname}}Rpc.{{.filename}}Update(l.ctx, &{{.xmodelname}}client.{{.filename}}UpdateReq{ 6 | {{.data}} 7 | }) 8 | if err != nil { 9 | return nil, common.NewDefaultError(err.Error()) 10 | } 11 | return &types.Response{ 12 | Code: 0, 13 | Msg: msg.Success, 14 | Data: nil, 15 | }, nil 16 | } 17 | -------------------------------------------------------------------------------- /tpl/http/http-api.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "openapi": "3.0.1", 3 | "info": { 4 | "title": "", 5 | "description": "", 6 | "version": "1.0.0" 7 | }, 8 | "tags": [ 9 | { 10 | "name": "{{.xfilename}}" 11 | } 12 | ], 13 | "paths": { 14 | "/{{.modelname}}/{{.xfilename}}/{id}": { 15 | "delete": { 16 | "summary": "删除{{.xfilename}}", 17 | "x-apifox-folder": "{{.xfilename}}", 18 | "x-apifox-status": "developing", 19 | "deprecated": false, 20 | "description": "", 21 | "tags": [ 22 | "{{.xfilename}}" 23 | ], 24 | "parameters": [ 25 | { 26 | "name": "id", 27 | "in": "path", 28 | "description": "{{.idCommand}}", 29 | "required": true, 30 | "example": "", 31 | "schema": { 32 | "type": "{{.idType}}" 33 | } 34 | } 35 | ], 36 | "responses": { 37 | 38 | }, 39 | "x-run-in-apifox": "", 40 | "security": [ 41 | { 42 | "bearer": [] 43 | } 44 | ] 45 | } 46 | }, 47 | "/{{.modelname}}/{{.xfilename}}Info": { 48 | "get": { 49 | "summary": "根据ID查询{{.xfilename}}", 50 | "x-apifox-folder": "{{.xfilename}}", 51 | "x-apifox-status": "developing", 52 | "deprecated": false, 53 | "description": "", 54 | "tags": [ 55 | "{{.xfilename}}" 56 | ], 57 | "parameters": [ 58 | { 59 | "name": "id", 60 | "in": "query", 61 | "description": "{{.idCommand}}", 62 | "required": false, 63 | "example": "", 64 | "schema": { 65 | "type": "{{.idType}}" 66 | } 67 | } 68 | ], 69 | "responses": { 70 | 71 | }, 72 | "x-run-in-apifox": "", 73 | "security": [ 74 | { 75 | "bearer": [] 76 | } 77 | ] 78 | } 79 | }, 80 | "/{{.modelname}}/{{.xfilename}}": { 81 | "post": { 82 | "summary": "添加{{.xfilename}}", 83 | "x-apifox-folder": "{{.xfilename}}", 84 | "x-apifox-status": "developing", 85 | "deprecated": false, 86 | "description": "", 87 | "tags": [ 88 | "{{.xfilename}}" 89 | ], 90 | "requestBody": { 91 | "content": { 92 | "application/json": { 93 | "schema": { 94 | "type": "object", 95 | "properties": { 96 | {{.Add}} 97 | } 98 | } 99 | } 100 | } 101 | }, 102 | "responses": { 103 | 104 | }, 105 | "x-run-in-apifox": "", 106 | "security": [ 107 | { 108 | "bearer": [] 109 | } 110 | ] 111 | }, 112 | "get": { 113 | "summary": "分页查询{{.xfilename}}", 114 | "x-apifox-folder": "{{.xfilename}}", 115 | "x-apifox-status": "developing", 116 | "deprecated": false, 117 | "description": "", 118 | "tags": [ 119 | "{{.xfilename}}" 120 | ], 121 | "parameters": [ 122 | {{.Query}} 123 | ], 124 | "responses": { 125 | 126 | }, 127 | "x-run-in-apifox": "", 128 | "security": [ 129 | { 130 | "bearer": [] 131 | } 132 | ] 133 | }, 134 | "put": { 135 | "summary": "修改{{.xfilename}}", 136 | "x-apifox-folder": "{{.xfilename}}", 137 | "x-apifox-status": "developing", 138 | "deprecated": false, 139 | "description": "", 140 | "tags": [ 141 | "{{.xfilename}}" 142 | ], 143 | "requestBody": { 144 | "content": { 145 | "application/json": { 146 | "schema": { 147 | "type": "object", 148 | "properties": { 149 | {{.Update}} 150 | }, 151 | "required": [ 152 | "id" 153 | ] 154 | } 155 | } 156 | } 157 | }, 158 | "responses": { 159 | 160 | }, 161 | "x-run-in-apifox": "", 162 | "security": [ 163 | { 164 | "bearer": [] 165 | } 166 | ] 167 | } 168 | } 169 | }, 170 | "components": { 171 | "schemas": {} 172 | } 173 | } -------------------------------------------------------------------------------- /tpl/rpc/delete.tpl: -------------------------------------------------------------------------------- 1 | func (l *{{.filename}}DeleteLogic) {{.filename}}Delete(in *{{.xmodelname}}client.{{.filename}}DeleteReq) (*{{.xmodelname}}client.CommonResp, error) { 2 | 3 | res, err := l.svcCtx.{{.filename}}Model.FindOne(l.ctx,in.Id) 4 | if err != nil { 5 | if err == sqlc.ErrNotFound { 6 | return nil, errors.New("{{.filename}}没有该ID:" + in.Id) 7 | } 8 | return nil, err 9 | } 10 | 11 | {{.deletedAtData}} 12 | {{.tenant}} 13 | 14 | {{.del}} 15 | 16 | err = l.svcCtx.{{.filename}}Model.{{.delType}} 17 | if err != nil { 18 | return nil, err 19 | } 20 | 21 | return &{{.xmodelname}}client.CommonResp{}, nil 22 | } -------------------------------------------------------------------------------- /tpl/rpc/find-list.tpl: -------------------------------------------------------------------------------- 1 | func (l *{{.filename}}ListLogic) {{.filename}}List(in *{{.xmodelname}}client.{{.filename}}ListReq) (*{{.xmodelname}}client.{{.filename}}ListResp, error) { 2 | 3 | whereBuilder := l.svcCtx.{{.filename}}Model.RowBuilder() 4 | 5 | {{.listDeletedAt}} 6 | {{.listCreatedAt}} 7 | 8 | {{.listTenant}} 9 | 10 | {{.listData}} 11 | 12 | all, err := l.svcCtx.{{.filename}}Model.FindList(l.ctx, whereBuilder, in.Current, in.PageSize) 13 | if err != nil { 14 | return nil, err 15 | } 16 | 17 | countBuilder := l.svcCtx.{{.filename}}Model.CountBuilder("id") 18 | 19 | {{.countDeletedAt}} 20 | 21 | {{.countTenant}} 22 | 23 | {{.countData}} 24 | count, err := l.svcCtx.{{.filename}}Model.FindCount(l.ctx, countBuilder) 25 | if err != nil { 26 | return nil, err 27 | } 28 | 29 | var list []*{{.xmodelname}}client.{{.filename}}ListData 30 | for _, item := range all { 31 | list = append(list, &{{.xmodelname}}client.{{.filename}}ListData{ 32 | {{.findlistData}} 33 | }) 34 | } 35 | 36 | return &{{.xmodelname}}client.{{.filename}}ListResp{ 37 | Total: count, 38 | List: list, 39 | }, nil 40 | } 41 | -------------------------------------------------------------------------------- /tpl/rpc/find-one.tpl: -------------------------------------------------------------------------------- 1 | func (l *{{.filename}}FindOneLogic) {{.filename}}FindOne(in *{{.xmodelname}}client.{{.filename}}FindOneReq) (*{{.xmodelname}}client.{{.filename}}FindOneResp, error) { 2 | 3 | res, err := l.svcCtx.{{.filename}}Model.FindOne(l.ctx,in.Id) 4 | if err != nil { 5 | if err == sqlc.ErrNotFound { 6 | return nil, errors.New("{{.filename}}没有该ID:" + in.Id) 7 | } 8 | return nil, err 9 | } 10 | 11 | {{.deletedAtData}} 12 | {{.tenant}} 13 | 14 | return &{{.xmodelname}}client.{{.filename}}FindOneResp{ 15 | {{.findoneData}} 16 | }, nil 17 | 18 | } -------------------------------------------------------------------------------- /tpl/rpc/insert.tpl: -------------------------------------------------------------------------------- 1 | func (l *{{.filename}}AddLogic) {{.filename}}Add(in *{{.xmodelname}}client.{{.filename}}AddReq) (*{{.xmodelname}}client.CommonResp, error) { 2 | 3 | _, err := l.svcCtx.{{.filename}}Model.Insert(l.ctx,&model.{{.filename}}{ 4 | Id: uuid.NewV4().String(), // ID 5 | CreatedAt: time.Now(), // 创建时间 6 | {{.data}} 7 | }) 8 | if err != nil { 9 | return nil, err 10 | } 11 | 12 | return &{{.xmodelname}}client.CommonResp{}, nil 13 | } 14 | -------------------------------------------------------------------------------- /tpl/rpc/rpc.tpl: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package {{.modelname}}client; 4 | 5 | option go_package = "./{{.modelname}}client"; 6 | 7 | //{{.filename}} start------------------- 8 | 9 | // {{.filename}} 添加 10 | message {{.filename}}AddReq{ 11 | {{.Add}} 12 | } 13 | 14 | // {{.filename}} 删除 15 | message {{.filename}}DeleteReq{ 16 | {{.Del}} 17 | } 18 | 19 | // {{.filename}} 更新 20 | message {{.filename}}UpdateReq{ 21 | {{.Up}} 22 | } 23 | 24 | // {{.filename}} 单个查询 25 | message {{.filename}}FindOneReq{ 26 | {{.FindOne}} 27 | } 28 | 29 | // {{.filename}} 单个查询返回 30 | message {{.filename}}FindOneResp{ 31 | {{.FindOneResp}} 32 | } 33 | 34 | 35 | // {{.filename}} 分页查询 36 | message {{.filename}}ListReq{ 37 | {{.List}} 38 | } 39 | 40 | // {{.filename}} 分页查询返回 41 | message {{.filename}}ListResp{ 42 | {{.ListResp}} 43 | } 44 | 45 | // {{.filename}} 列表信息 46 | message {{.filename}}ListData{ 47 | {{.ListData}} 48 | } 49 | 50 | //{{.filename}} end--------------------- 51 | 52 | service {{.amodelname}} { 53 | 54 | rpc {{.filename}}Add({{.filename}}AddReq) returns(CommonResp); 55 | rpc {{.filename}}Delete({{.filename}}DeleteReq) returns(CommonResp); 56 | rpc {{.filename}}Update({{.filename}}UpdateReq) returns(CommonResp); 57 | rpc {{.filename}}FindOne({{.filename}}FindOneReq) returns({{.filename}}FindOneResp); 58 | rpc {{.filename}}List({{.filename}}ListReq) returns({{.filename}}ListResp); 59 | 60 | } -------------------------------------------------------------------------------- /tpl/rpc/update.tpl: -------------------------------------------------------------------------------- 1 | func (l *{{.filename}}UpdateLogic) {{.filename}}Update(in *{{.xmodelname}}client.{{.filename}}UpdateReq) (*{{.xmodelname}}client.CommonResp, error) { 2 | 3 | res, err := l.svcCtx.{{.filename}}Model.FindOne(l.ctx,in.Id) 4 | if err != nil { 5 | if err == sqlc.ErrNotFound { 6 | return nil, errors.New("{{.filename}}没有该ID:" + in.Id) 7 | } 8 | return nil, err 9 | } 10 | 11 | {{.deletedAtData}} 12 | {{.tenant}} 13 | 14 | {{.updateData}} 15 | 16 | res.UpdatedName.String = in.UpdatedName 17 | res.UpdatedName.Valid = true 18 | res.UpdatedAt.Time = time.Now() 19 | res.UpdatedAt.Valid = true 20 | 21 | err = l.svcCtx.{{.filename}}Model.Update(l.ctx,res) 22 | 23 | if err != nil { 24 | return nil, err 25 | } 26 | return &{{.xmodelname}}client.CommonResp{}, nil 27 | 28 | } --------------------------------------------------------------------------------