From 9edb835e5555679c6221d5adc0fe718ddd39438a Mon Sep 17 00:00:00 2001 From: dabai <975446398@qq.com> Date: Mon, 6 Jun 2022 18:39:11 +0800 Subject: [PATCH 01/10] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9Ecurd=E5=B7=A5?= =?UTF-8?q?=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/database.yaml | 8 + console/commands/curd.go | 338 +++++++++++++++++++++++++++++++ console/commands/z_inject_gen.go | 9 + go.mod | 34 +++- 4 files changed, 385 insertions(+), 4 deletions(-) create mode 100644 config/database.yaml create mode 100644 console/commands/curd.go diff --git a/config/database.yaml b/config/database.yaml new file mode 100644 index 0000000..f27206d --- /dev/null +++ b/config/database.yaml @@ -0,0 +1,8 @@ +connections: + mysql: + driver: mysql + host: env("DB_HOST") + port: env("DB_PORT") + database: env("DB_DATABASE") + username: env("DB_USERNAME") + password: env("DB_PASSWORD") \ No newline at end of file diff --git a/console/commands/curd.go b/console/commands/curd.go new file mode 100644 index 0000000..4937df6 --- /dev/null +++ b/console/commands/curd.go @@ -0,0 +1,338 @@ +package commands + +import ( + "fmt" + "github.com/ctfang/command" + "github.com/go-home-admin/toolset/app/entity/mysql" + "log" + "os" + "reflect" + "strings" + _ "strings" +) + +// CurdCommand @Bean +type CurdCommand struct{} + +func (CurdCommand) Configure() command.Configure { + return command.Configure{ + Name: "make:curd", + Description: "生成curd基础代码, 默认使用交互输入, 便捷调用 ", + Input: command.Argument{ + Option: []command.ArgParam{ + { + Name: "go_out", + Description: "生成文件到指定目录", + }, + { + Name: "table_name", + Description: "表名", + }, + { + Name: "db_name", + Description: "数据库类型", + }, + { + Name: "explain", + Description: "说明", + }, + }, + }, + } +} + +func (CurdCommand) Execute(input command.Input) { + root := getRootPath() + tableName := input.GetOption("table_name") + if tableName == "" { + log.Printf("请输入表名") + return + } + out := input.GetOption("go_out") + if out == "" { + log.Printf("请输入保存到目录地址") + return + } + outUrl := root + "/app/http/admin/" + out + "/" + tableName + _, err := os.Stat(outUrl) + if os.IsNotExist(err) { + err = os.MkdirAll(outUrl, 0766) + if err != nil { + log.Printf(err.Error()) + return + } + } + protoUrl := root + "/protobuf/admin/" + out + "/" + tableName + _, err = os.Stat(protoUrl) + if os.IsNotExist(err) { + err = os.MkdirAll(protoUrl, 0766) + if err != nil { + log.Printf(err.Error()) + return + } + } + index := strings.Index(tableName, "_") + contName := "" + if index >= 0 { + other := tableName[index+1:] + contName = strings.ToUpper(tableName[:1]) + tableName[1:index] + strings.ToUpper(other[:1]) + other[1:] + } else { + contName = strings.ToUpper(tableName) + } + // 获取表结构 + var tb mysql.ActionLogs + tableColumn := reflect.TypeOf(tb) + for i := 0; i < tableColumn.NumField(); i++ { + fmt.Printf("name: %v \n", tableColumn.Field(i).Name) + fmt.Printf("key: %v \n\n", tableColumn.Field(i).Type) + } + module := getModModule() + //controller + buildController(input, outUrl, module, contName) + //del + buildDel(input, outUrl, module, "del", contName) + //get + buildGet(input, outUrl, module, "get", contName) + //post + buildPost(input, outUrl, module, "post", contName) + //put + buildPut(input, outUrl, module, "put", contName) + //proto + buildProto(input, protoUrl, module, contName) +} + +func buildController(input command.Input, outUrl string, module string, contName string) { + cont := outUrl + "/" + input.GetOption("table_name") + "_controller.go" + str := "package " + input.GetOption("table_name") + pack := module + "/app/entity/" + input.GetOption("db_name") + str += "\n\nimport (\n \"" + pack + "\"\n)" + str += "\n\n// " + input.GetOption("explain") + str += "\ntype Controller struct {" + str += "\n orm *" + input.GetOption("db_name") + "." + contName + " `inject:\"\"`" + str += "\n}" + err := os.WriteFile(cont, []byte(str), 0766) + if err != nil { + log.Printf(err.Error()) + return + } +} + +func buildHead(table_name string, module string) string { + str := "package " + table_name + tm := []string{ + "github.com/gin-gonic/gin", + module + "/app/common", + module + "/app/providers", + module + "/generate/proto/admin/" + table_name, + } + str += "\n\nimport (" + for _, v := range tm { + str += "\n \"" + v + "\"" + } + str += "\n)" + return str +} + +func buildDel(input command.Input, outUrl string, module string, name string, contName string) { + cont := outUrl + "/del_action.go" + str := buildHead(input.GetOption("table_name"), module) + str += "\n\n// Del 删除数据 - " + input.GetOption("explain") + str += "\nfunc (receiver *Controller) Del(req *" + input.GetOption("go_out") + "." + contName + "PutRequest, ctx *auth.Context) (*" + + input.GetOption("go_out") + "." + contName + "PutRequest, error) {" + str += "\n id := common.GetParamId(ctx)" + str += "\n receiver.orm.Delete(id)" + str += "\n return &" + input.GetOption("go_out") + "." + contName + "PutRequest{" + str += "\n Tip: \"OK\"," + str += "\n }, nil" + str += "\n}" + str += handleValue(name, input.GetOption("go_out"), contName) + err := os.WriteFile(cont, []byte(str), 0766) + if err != nil { + log.Printf(err.Error()) + return + } +} + +func buildGet(input command.Input, outUrl string, module string, name string, contName string) { + cont := outUrl + "/get_action.go" + str := buildHead(input.GetOption("table_name"), module) + str += "\n\n// Get 列表查询 - " + input.GetOption("explain") + str += fmt.Sprintf(` +func (receiver *Controller) Get(req *%v.%vGetRequest, ctx *auth.Context) (*%v.%vGetRequest, error) { + list, total := receiver.orm.GetPaginate(req.Page, req.Limit) + responseList := make([]*%v.%vInfo, 0) + for _, cp := range list { + responseList = append(responseList, &%v.%vInfo{}) + } + return &%v.%vGetResponse{ + List: responseList, + Total: uint32(total), + }, nil +} +`, + input.GetOption("go_out"), + contName, + input.GetOption("go_out"), + contName, + input.GetOption("table_name"), + contName, + input.GetOption("table_name"), + contName, + input.GetOption("go_out"), + contName, + ) + str += handleValue(name, input.GetOption("go_out"), contName) + err := os.WriteFile(cont, []byte(str), 0766) + if err != nil { + log.Printf(err.Error()) + return + } +} + +func buildPost(input command.Input, outUrl string, module string, name string, contName string) { + cont := outUrl + "/post_action.go" + str := buildHead(input.GetOption("table_name"), module) + str += "\n\n// Post 创建新数据 - " + input.GetOption("explain") + str += "\nfunc (receiver *Controller) Post(req *" + input.GetOption("go_out") + "." + contName + "PostRequest, ctx *auth.Context) (*" + + input.GetOption("go_out") + "." + contName + "PostRequest, error) {" + str += "\n id := int32(common.GetParamId(ctx))" + str += "\n has := receiver.orm.WhereId(id).First()" + str += "\n if has == nil {" + str += "\n return nil, nil" + str += "\n }" + split := strings.Split(input.GetOption("table_name"), "_") + dbFunc := "" + for _, t := range split { + dbFunc += strings.ToUpper(t[:1]) + t[1:] + } + str += "\n data := " + input.GetOption("db_name") + "." + dbFunc + "{}" + str += "\n res := receiver.orm.Create(&data)" + str += "\n return &" + input.GetOption("go_out") + "." + contName + "PostResponse{}, res.Error" + str += "\n}" + str += handleValue(name, input.GetOption("go_out"), contName) + err := os.WriteFile(cont, []byte(str), 0766) + if err != nil { + log.Printf(err.Error()) + return + } +} + +func buildPut(input command.Input, outUrl string, module string, name string, contName string) { + cont := outUrl + "/put_action.go" + str := buildHead(input.GetOption("table_name"), module) + str += "\n\n// Put 更新数据 - " + input.GetOption("explain") + str += "\nfunc (receiver *Controller) Put(req *" + input.GetOption("go_out") + "." + contName + "PostRequest, ctx *auth.Context) (*" + + input.GetOption("go_out") + "." + contName + "PostRequest, error) {" + str += "\n id := int32(common.GetParamId(ctx))" + str += "\n has := receiver.orm.WhereId(id).First()" + str += "\n if has == nil {" + str += "\n return nil, nil" + str += "\n }" + split := strings.Split(input.GetOption("table_name"), "_") + dbFunc := "" + for _, t := range split { + dbFunc += strings.ToUpper(t[:1]) + t[1:] + } + str += "\n receiver.orm.WhereId(id).Updates(&" + input.GetOption("db_name") + "." + dbFunc + "{})" + str += "\n return &" + input.GetOption("go_out") + "." + contName + "PutResponse{}, nil" + str += "\n}" + str += handleValue(name, input.GetOption("go_out"), contName) + err := os.WriteFile(cont, []byte(str), 0766) + if err != nil { + log.Printf(err.Error()) + return + } +} + +func handleValue(name string, module string, contName string) string { + name = strings.ToUpper(name[:1]) + name[1:] + str := fmt.Sprintf(` +//GinHandle%v gin原始路由处理`, name) + str += fmt.Sprintf(` +func (receiver *Controller) GinHandle%v(ctx *gin.Context) { + req := &%v.%v%vRequest{} + err := ctx.ShouleBind(req) + if err != nil { + providers.ErrorRequest(ctx, err) + return + } + resp, err := receiver.%v(req, auth.NewContext(ctx)) + if err != nil { + providers.ErrorResponse(ctx, err) + return + } + providers.SuccessResponse(ctx, resp) +} +`, + name, + module, + contName, + name, + name, + ) + return str +} + +func buildProto(input command.Input, protoUrl string, module string, contName string) { + cont := protoUrl + "/" + input.GetOption("table_name") + ".proto" + str := "// @Tag(\"form\");" + str += "\nsyntax = \"proto3\";" + str += "\n\npackage " + input.GetOption("table_name") + ";" + str += "\n\nimport \"http_config.proto\";" + str += "\n\noption go_package = \"" + module + "/generate/proto/admin/" + input.GetOption("go_out") + "\";" + str += "\n// " + input.GetOption("explain") + "资源控制器" + str += "\nservice " + contName + "{" + str += "\n // 需要登录" + str += "\n option (http.RouteGroup) = \"login\";" + str += "\n // " + input.GetOption("explain") + "列表" + str += "\n rpc Get(" + contName + "GetRequest) returns (" + contName + "GetResponse){" + str += "\n option (http.Get) = \"/" + input.GetOption("go_out") + "/" + input.GetOption("table_name") + "\";" + str += "\n }" + str += "\n // " + input.GetOption("explain") + "创建" + str += "\n rpc Post(" + contName + "PostRequest) returns (" + contName + "PostResponse){" + str += "\n option (http.Post) = \"/" + input.GetOption("go_out") + "/" + input.GetOption("table_name") + "\";" + str += "\n }" + str += "\n // " + input.GetOption("explain") + "更新" + str += "\n rpc Put(" + contName + "PutRequest) returns (" + contName + "PutResponse){" + str += "\n option (http.Put) = \"/" + input.GetOption("go_out") + "/" + input.GetOption("table_name") + "/:id\";" + str += "\n }" + str += "\n // " + input.GetOption("explain") + "删除" + str += "\n rpc Del(" + contName + "PutRequest) returns (" + contName + "PutResponse){" + str += "\n option (http.Get) = \"/" + input.GetOption("go_out") + "/" + input.GetOption("table_name") + "/:id\";" + str += "\n }" + str += "\n}" + str += "\nmessage " + contName + "GetRequest {" + str += "\n // 列表第几页,默认1" + str += "\n uint32 page = 1;" + str += "\n // 每页多少条数据" + str += "\n uint32 limit = 2;" + str += "\n}" + str += "\nmessage " + contName + "GetResponse {" + str += "\n // 数据列表" + str += "\n repeated " + contName + "Info list = 1;" + str += "\n // 符合条件总数量,计算多少页" + str += "\n uint32 total = 2;" + str += "\n}" + str += "\nmessage " + contName + "PostRequest {" + str += "\n" + str += "\n}" + str += "\nmessage " + contName + "PostResponse {" + str += "\n // 提示语" + str += "\n string tip = 1;" + str += "\n}" + str += "\nmessage " + contName + "PutRequest {" + str += "\n" + str += "\n}" + str += "\nmessage " + contName + "PutResponse {" + str += "\n // 提示语" + str += "\n string tip = 1;" + str += "\n}" + str += "\nmessage " + contName + "Info{" + str += "\n" + str += "\n}" + err := os.WriteFile(cont, []byte(str), 0766) + if err != nil { + log.Printf(err.Error()) + return + } +} diff --git a/console/commands/z_inject_gen.go b/console/commands/z_inject_gen.go index 8ac0109..8b2493b 100644 --- a/console/commands/z_inject_gen.go +++ b/console/commands/z_inject_gen.go @@ -6,6 +6,7 @@ import ( ) var _BeanCommandSingle *BeanCommand +var _CurdCommandSingle *CurdCommand var _DevCommandSingle *DevCommand var _JsSingle *Js var _OrmCommandSingle *OrmCommand @@ -16,6 +17,7 @@ var _SwaggerCommandSingle *SwaggerCommand func GetAllProvider() []interface{} { return []interface{}{ NewBeanCommand(), + NewCurdCommand(), NewDevCommand(), NewJs(), NewOrmCommand(), @@ -32,6 +34,13 @@ func NewBeanCommand() *BeanCommand { } return _BeanCommandSingle } +func NewCurdCommand() *CurdCommand { + if _CurdCommandSingle == nil { + _CurdCommandSingle = &CurdCommand{} + providers.AfterProvider(_CurdCommandSingle, "") + } + return _CurdCommandSingle +} func NewDevCommand() *DevCommand { if _DevCommandSingle == nil { _DevCommandSingle = &DevCommand{} diff --git a/go.mod b/go.mod index 84d4538..7e46f6f 100644 --- a/go.mod +++ b/go.mod @@ -4,15 +4,41 @@ go 1.16 require ( github.com/ctfang/command v1.0.0 - github.com/gin-gonic/gin v1.8.0 // indirect github.com/go-home-admin/home v0.0.3 - github.com/go-playground/validator/v10 v10.11.0 // indirect github.com/go-sql-driver/mysql v1.6.0 github.com/joho/godotenv v1.4.0 github.com/lib/pq v1.10.6 + github.com/sirupsen/logrus v1.8.1 + gopkg.in/yaml.v2 v2.4.0 + gorm.io/gorm v1.23.5 +) + +require ( + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-gonic/gin v1.8.0 // indirect + github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-playground/validator/v10 v10.11.0 // indirect + github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/goccy/go-json v0.9.7 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/kr/pretty v0.3.0 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/rogpeppe/go-internal v1.8.1 // indirect + github.com/ugorji/go/codec v1.2.7 // indirect golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect - gopkg.in/yaml.v2 v2.4.0 + golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect + golang.org/x/text v0.3.7 // indirect + google.golang.org/protobuf v1.28.0 // indirect gorm.io/driver/mysql v1.3.4 // indirect - gorm.io/gorm v1.23.5 // indirect ) From d915c0855b6a626a4cee69f508ad7c612b8ace35 Mon Sep 17 00:00:00 2001 From: aliang Date: Tue, 7 Jun 2022 15:08:56 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E8=A1=A8=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- console/commands/curd.go | 86 ++++++++++++++++++++++++++++++--- console/commands/orm/mysql.go | 4 ++ console/commands/pgorm/pgsql.go | 4 ++ 3 files changed, 88 insertions(+), 6 deletions(-) diff --git a/console/commands/curd.go b/console/commands/curd.go index 4937df6..07500cd 100644 --- a/console/commands/curd.go +++ b/console/commands/curd.go @@ -1,9 +1,14 @@ package commands import ( + "database/sql" "fmt" "github.com/ctfang/command" "github.com/go-home-admin/toolset/app/entity/mysql" + "github.com/go-home-admin/toolset/console/commands/orm" + "github.com/go-home-admin/toolset/console/commands/pgorm" + "github.com/go-home-admin/toolset/parser" + "gopkg.in/yaml.v2" "log" "os" "reflect" @@ -14,23 +19,35 @@ import ( // CurdCommand @Bean type CurdCommand struct{} +type TableColumn struct { + Name string + GoType string +} + func (CurdCommand) Configure() command.Configure { return command.Configure{ Name: "make:curd", Description: "生成curd基础代码, 默认使用交互输入, 便捷调用 ", Input: command.Argument{ - Option: []command.ArgParam{ + Argument: []command.ArgParam{ { - Name: "go_out", - Description: "生成文件到指定目录", + Name: "conn_name", + Description: "连接名", }, { Name: "table_name", Description: "表名", }, + }, + Option: []command.ArgParam{ { - Name: "db_name", - Description: "数据库类型", + Name: "config", + Description: "配置文件", + Default: "@root/config/database.yaml", + }, + { + Name: "go_out", + Description: "生成文件到指定目录", }, { Name: "explain", @@ -43,11 +60,28 @@ func (CurdCommand) Configure() command.Configure { func (CurdCommand) Execute(input command.Input) { root := getRootPath() - tableName := input.GetOption("table_name") + configFile := input.GetOption("config") + configFile = strings.Replace(configFile, "@root", root, 1) + configContext, _ := os.ReadFile(configFile) + configContext = SetEnv(configContext) + m := make(map[string]interface{}) + err := yaml.Unmarshal(configContext, &m) + if err != nil { + panic(err) + } + connections := m["connections"].(map[interface{}]interface{}) + connName := input.GetArgument("conn_name") + if _, ok := connections[connName]; !ok { + panic("没有找不到对应数据库连接") + } + tableName := input.GetArgument("table_name") if tableName == "" { log.Printf("请输入表名") return } + config := connections[connName].(map[interface{}]interface{}) + TableColumns := GetTableColumn(config, tableName) + out := input.GetOption("go_out") if out == "" { log.Printf("请输入保存到目录地址") @@ -336,3 +370,43 @@ func buildProto(input command.Input, protoUrl string, module string, contName st return } } + +func GetTableColumn(config map[interface{}]interface{}, tableName string) []TableColumn { + rows := &sql.Rows{} + switch config["driver"] { + case "mysql": + rows, _ = orm.NewDb(config).GetDB().Query(` +SELECT COLUMN_NAME, DATA_TYPE, +FROM information_schema.COLUMNS +WHERE table_schema = DATABASE () AND table_name = $1 +ORDER BY ORDINAL_POSITION ASC`, tableName) + case "pgsql": + rows, _ = pgorm.NewDb(config).GetDB().Query(` +SELECT column_name, udt_name +FROM information_schema.columns +WHERE table_schema = 'public' and table_name = $1 +`, tableName) + default: + panic("没有[" + config["driver"].(string) + "]的驱动") + } + defer rows.Close() + var tableColumns []TableColumn + for rows.Next() { + var name, dataType string + _ = rows.Scan( + &name, + &dataType, + ) + switch config["driver"] { + case "mysql": + dataType = orm.TypeForMysqlToGo[dataType] + case "pgsql": + dataType = pgorm.PgTypeToGoType(dataType, name) + } + tableColumns = append(tableColumns, TableColumn{ + Name: parser.StringToHump(name), + GoType: dataType, + }) + } + return tableColumns +} diff --git a/console/commands/orm/mysql.go b/console/commands/orm/mysql.go index e1414ec..fc9d68c 100644 --- a/console/commands/orm/mysql.go +++ b/console/commands/orm/mysql.go @@ -336,6 +336,10 @@ type DB struct { db *sql.DB } +func (d *DB) GetDB() *sql.DB { + return d.db +} + func (d *DB) tableColumns() map[string][]tableColumn { var sqlStr = `SELECT TABLE_CATALOG, diff --git a/console/commands/pgorm/pgsql.go b/console/commands/pgorm/pgsql.go index 71fec3d..d86675e 100644 --- a/console/commands/pgorm/pgsql.go +++ b/console/commands/pgorm/pgsql.go @@ -321,6 +321,10 @@ type DB struct { db *sql.DB } +func (d *DB) GetDB() *sql.DB { + return d.db +} + func (d *DB) tableColumns() map[string][]tableColumn { var sqlStr = "SELECT tablename FROM pg_tables WHERE schemaname = 'public'" From c442e630e761ab9ddd4372d2a3b5195a96e4c2f3 Mon Sep 17 00:00:00 2001 From: aliang Date: Tue, 7 Jun 2022 15:46:15 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E8=A1=A8=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- console/commands/curd.go | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/console/commands/curd.go b/console/commands/curd.go index 07500cd..97b370d 100644 --- a/console/commands/curd.go +++ b/console/commands/curd.go @@ -20,8 +20,9 @@ import ( type CurdCommand struct{} type TableColumn struct { - Name string - GoType string + Name string + GoType string + Comment string } func (CurdCommand) Configure() command.Configure { @@ -376,15 +377,17 @@ func GetTableColumn(config map[interface{}]interface{}, tableName string) []Tabl switch config["driver"] { case "mysql": rows, _ = orm.NewDb(config).GetDB().Query(` -SELECT COLUMN_NAME, DATA_TYPE, +SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE table_schema = DATABASE () AND table_name = $1 ORDER BY ORDINAL_POSITION ASC`, tableName) case "pgsql": rows, _ = pgorm.NewDb(config).GetDB().Query(` -SELECT column_name, udt_name -FROM information_schema.columns -WHERE table_schema = 'public' and table_name = $1 +SELECT i.column_name, i.udt_name, col_description(a.attrelid,a.attnum) as comment +FROM information_schema.columns as i +LEFT JOIN pg_class as c on c.relname = i.table_name +LEFT JOIN pg_attribute as a on a.attrelid = c.oid and a.attname = i.column_name +WHERE table_schema = 'public' and i.table_name = $1; `, tableName) default: panic("没有[" + config["driver"].(string) + "]的驱动") @@ -392,11 +395,18 @@ WHERE table_schema = 'public' and table_name = $1 defer rows.Close() var tableColumns []TableColumn for rows.Next() { - var name, dataType string + var name, dataType, comment string + var _comment *string _ = rows.Scan( &name, &dataType, + &_comment, ) + if _comment == nil { + comment = "" + } else { + comment = *_comment + } switch config["driver"] { case "mysql": dataType = orm.TypeForMysqlToGo[dataType] @@ -404,8 +414,9 @@ WHERE table_schema = 'public' and table_name = $1 dataType = pgorm.PgTypeToGoType(dataType, name) } tableColumns = append(tableColumns, TableColumn{ - Name: parser.StringToHump(name), - GoType: dataType, + Name: parser.StringToHump(name), + GoType: dataType, + Comment: comment, }) } return tableColumns From e7c5fd5e2fb7808d76d610082793718123d54607 Mon Sep 17 00:00:00 2001 From: dabai <975446398@qq.com> Date: Tue, 7 Jun 2022 17:13:51 +0800 Subject: [PATCH 04/10] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9Ecurd=E5=B7=A5?= =?UTF-8?q?=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- console/commands/curd.go | 41 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/console/commands/curd.go b/console/commands/curd.go index 97b370d..6423dee 100644 --- a/console/commands/curd.go +++ b/console/commands/curd.go @@ -4,16 +4,14 @@ import ( "database/sql" "fmt" "github.com/ctfang/command" - "github.com/go-home-admin/toolset/app/entity/mysql" "github.com/go-home-admin/toolset/console/commands/orm" "github.com/go-home-admin/toolset/console/commands/pgorm" "github.com/go-home-admin/toolset/parser" "gopkg.in/yaml.v2" "log" "os" - "reflect" + "strconv" "strings" - _ "strings" ) // CurdCommand @Bean @@ -61,19 +59,21 @@ func (CurdCommand) Configure() command.Configure { func (CurdCommand) Execute(input command.Input) { root := getRootPath() - configFile := input.GetOption("config") - configFile = strings.Replace(configFile, "@root", root, 1) - configContext, _ := os.ReadFile(configFile) - configContext = SetEnv(configContext) + file := input.GetOption("config") + file = strings.Replace(file, "@root", root, 1) + fileContext, _ := os.ReadFile(file) + fileContext = SetEnv(fileContext) m := make(map[string]interface{}) - err := yaml.Unmarshal(configContext, &m) + err := yaml.Unmarshal(fileContext, &m) if err != nil { - panic(err) + log.Printf("配置解析错误:%v", err) + return } connections := m["connections"].(map[interface{}]interface{}) connName := input.GetArgument("conn_name") if _, ok := connections[connName]; !ok { - panic("没有找不到对应数据库连接") + log.Printf("没有找不到对应数据库连接") + return } tableName := input.GetArgument("table_name") if tableName == "" { @@ -82,14 +82,13 @@ func (CurdCommand) Execute(input command.Input) { } config := connections[connName].(map[interface{}]interface{}) TableColumns := GetTableColumn(config, tableName) - out := input.GetOption("go_out") if out == "" { log.Printf("请输入保存到目录地址") return } outUrl := root + "/app/http/admin/" + out + "/" + tableName - _, err := os.Stat(outUrl) + _, err = os.Stat(outUrl) if os.IsNotExist(err) { err = os.MkdirAll(outUrl, 0766) if err != nil { @@ -114,13 +113,6 @@ func (CurdCommand) Execute(input command.Input) { } else { contName = strings.ToUpper(tableName) } - // 获取表结构 - var tb mysql.ActionLogs - tableColumn := reflect.TypeOf(tb) - for i := 0; i < tableColumn.NumField(); i++ { - fmt.Printf("name: %v \n", tableColumn.Field(i).Name) - fmt.Printf("key: %v \n\n", tableColumn.Field(i).Type) - } module := getModModule() //controller buildController(input, outUrl, module, contName) @@ -133,7 +125,7 @@ func (CurdCommand) Execute(input command.Input) { //put buildPut(input, outUrl, module, "put", contName) //proto - buildProto(input, protoUrl, module, contName) + buildProto(input, protoUrl, module, contName, TableColumns) } func buildController(input command.Input, outUrl string, module string, contName string) { @@ -308,7 +300,7 @@ func (receiver *Controller) GinHandle%v(ctx *gin.Context) { return str } -func buildProto(input command.Input, protoUrl string, module string, contName string) { +func buildProto(input command.Input, protoUrl string, module string, contName string, column []TableColumn) { cont := protoUrl + "/" + input.GetOption("table_name") + ".proto" str := "// @Tag(\"form\");" str += "\nsyntax = \"proto3\";" @@ -349,7 +341,6 @@ func buildProto(input command.Input, protoUrl string, module string, contName st str += "\n uint32 total = 2;" str += "\n}" str += "\nmessage " + contName + "PostRequest {" - str += "\n" str += "\n}" str += "\nmessage " + contName + "PostResponse {" str += "\n // 提示语" @@ -357,13 +348,17 @@ func buildProto(input command.Input, protoUrl string, module string, contName st str += "\n}" str += "\nmessage " + contName + "PutRequest {" str += "\n" + str += "\n" str += "\n}" str += "\nmessage " + contName + "PutResponse {" str += "\n // 提示语" str += "\n string tip = 1;" str += "\n}" str += "\nmessage " + contName + "Info{" - str += "\n" + for i, v := range column { + str += "\n // " + v.Comment + str += "\n " + v.GoType + " " + v.Name + " = " + strconv.Itoa(i) + ";" + } str += "\n}" err := os.WriteFile(cont, []byte(str), 0766) if err != nil { From 35b8b5086bd6f87687b8fce93c2f3b25daf113be Mon Sep 17 00:00:00 2001 From: aliang Date: Tue, 7 Jun 2022 18:24:00 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E8=A1=A8=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- console/commands/curd.go | 5 +++-- console/commands/orm/mysql.go | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/console/commands/curd.go b/console/commands/curd.go index 6423dee..2c709b3 100644 --- a/console/commands/curd.go +++ b/console/commands/curd.go @@ -374,10 +374,11 @@ func GetTableColumn(config map[interface{}]interface{}, tableName string) []Tabl rows, _ = orm.NewDb(config).GetDB().Query(` SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT FROM information_schema.COLUMNS -WHERE table_schema = DATABASE () AND table_name = $1 +WHERE table_schema = DATABASE () AND table_name = ? ORDER BY ORDINAL_POSITION ASC`, tableName) case "pgsql": - rows, _ = pgorm.NewDb(config).GetDB().Query(` + db := pgorm.NewDb(config) + rows, _ = db.GetDB().Query(` SELECT i.column_name, i.udt_name, col_description(a.attrelid,a.attnum) as comment FROM information_schema.columns as i LEFT JOIN pg_class as c on c.relname = i.table_name diff --git a/console/commands/orm/mysql.go b/console/commands/orm/mysql.go index fc9d68c..3672bdf 100644 --- a/console/commands/orm/mysql.go +++ b/console/commands/orm/mysql.go @@ -552,7 +552,7 @@ var typeForMysqlToGo = map[string]string{ func NewDb(conf map[interface{}]interface{}) *DB { config := services.NewConfig(conf) db, err := sql.Open("mysql", fmt.Sprintf( - "%s:%s@tcp(%s)/%s", + "%s:%s@tcp(%s)/%s?interpolateParams=true", config.GetString("username", "root"), config.GetString("password", "123456"), config.GetString("host", "localhost:"+config.GetString("port", "3306")), From 1c82775f20ba8be55de5ca0251f0ac2daf15b94a Mon Sep 17 00:00:00 2001 From: aliang Date: Wed, 8 Jun 2022 14:57:36 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E8=8E=B7=E5=8F=96env=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- console/commands/curd.go | 15 ++++++++++++--- console/commands/orm.go | 11 ++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/console/commands/curd.go b/console/commands/curd.go index 2c709b3..f703c17 100644 --- a/console/commands/curd.go +++ b/console/commands/curd.go @@ -7,6 +7,7 @@ import ( "github.com/go-home-admin/toolset/console/commands/orm" "github.com/go-home-admin/toolset/console/commands/pgorm" "github.com/go-home-admin/toolset/parser" + "github.com/joho/godotenv" "gopkg.in/yaml.v2" "log" "os" @@ -59,12 +60,16 @@ func (CurdCommand) Configure() command.Configure { func (CurdCommand) Execute(input command.Input) { root := getRootPath() + err := godotenv.Load(root + "/.env") + if err != nil { + fmt.Println(root + "/.env" + "文件不存在, 无法加载环境变量") + } file := input.GetOption("config") file = strings.Replace(file, "@root", root, 1) fileContext, _ := os.ReadFile(file) fileContext = SetEnv(fileContext) m := make(map[string]interface{}) - err := yaml.Unmarshal(fileContext, &m) + err = yaml.Unmarshal(fileContext, &m) if err != nil { log.Printf("配置解析错误:%v", err) return @@ -369,16 +374,17 @@ func buildProto(input command.Input, protoUrl string, module string, contName st func GetTableColumn(config map[interface{}]interface{}, tableName string) []TableColumn { rows := &sql.Rows{} + var err error switch config["driver"] { case "mysql": - rows, _ = orm.NewDb(config).GetDB().Query(` + rows, err = orm.NewDb(config).GetDB().Query(` SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE table_schema = DATABASE () AND table_name = ? ORDER BY ORDINAL_POSITION ASC`, tableName) case "pgsql": db := pgorm.NewDb(config) - rows, _ = db.GetDB().Query(` + rows, err = db.GetDB().Query(` SELECT i.column_name, i.udt_name, col_description(a.attrelid,a.attnum) as comment FROM information_schema.columns as i LEFT JOIN pg_class as c on c.relname = i.table_name @@ -389,6 +395,9 @@ WHERE table_schema = 'public' and i.table_name = $1; panic("没有[" + config["driver"].(string) + "]的驱动") } defer rows.Close() + if err != nil { + panic("数据库连接失败或没有找到对应的表") + } var tableColumns []TableColumn for rows.Next() { var name, dataType, comment string diff --git a/console/commands/orm.go b/console/commands/orm.go index 083fa22..23bcf05 100644 --- a/console/commands/orm.go +++ b/console/commands/orm.go @@ -90,13 +90,14 @@ func SetEnv(fileContext []byte) []byte { } nS := arr2[1] st, et := GetBrackets(nS, '"', '"') - key := nS[st : et+1] + key := strings.Trim(nS[st:et+1], "\"") nS = nS[et+1:] st, et = GetBrackets(nS, '"', '"') - val := nS[st : et+1] - key = strings.Trim(key, "\"") - val = strings.Trim(val, "\"") - + var val string + if et > 0 { + val = nS[st : et+1] + val = strings.Trim(val, "\"") + } envVal := os.Getenv(key) if envVal != "" { val = envVal From 8bc39dfe8214b4315ab56dba0fd2a232d63c6b61 Mon Sep 17 00:00:00 2001 From: baichou Date: Mon, 20 Jun 2022 18:09:29 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E8=A1=A5=E5=85=85=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- console/commands/curd.go | 84 +++++++++++++++++++++++++++++++++------- console/commands/orm.go | 9 +++-- go.mod | 27 +------------ go.sum | 4 +- 4 files changed, 79 insertions(+), 45 deletions(-) diff --git a/console/commands/curd.go b/console/commands/curd.go index f703c17..3500ba1 100644 --- a/console/commands/curd.go +++ b/console/commands/curd.go @@ -29,7 +29,7 @@ func (CurdCommand) Configure() command.Configure { Name: "make:curd", Description: "生成curd基础代码, 默认使用交互输入, 便捷调用 ", Input: command.Argument{ - Argument: []command.ArgParam{ + Option: []command.ArgParam{ { Name: "conn_name", Description: "连接名", @@ -38,8 +38,6 @@ func (CurdCommand) Configure() command.Configure { Name: "table_name", Description: "表名", }, - }, - Option: []command.ArgParam{ { Name: "config", Description: "配置文件", @@ -51,7 +49,10 @@ func (CurdCommand) Configure() command.Configure { }, { Name: "explain", - Description: "说明", + Description: "生成的注释, 默认为表注释", + Call: func(val string, c *command.Console) (string, bool) { + return "", true + }, }, }, }, @@ -75,16 +76,8 @@ func (CurdCommand) Execute(input command.Input) { return } connections := m["connections"].(map[interface{}]interface{}) - connName := input.GetArgument("conn_name") - if _, ok := connections[connName]; !ok { - log.Printf("没有找不到对应数据库连接") - return - } - tableName := input.GetArgument("table_name") - if tableName == "" { - log.Printf("请输入表名") - return - } + connName := getConnName(input.GetOption("conn_name"), connections) + tableName := getTableName(input.GetOption("table_name"), connections[connName]) config := connections[connName].(map[interface{}]interface{}) TableColumns := GetTableColumn(config, tableName) out := input.GetOption("go_out") @@ -133,6 +126,69 @@ func (CurdCommand) Execute(input command.Input) { buildProto(input, protoUrl, module, contName, TableColumns) } +// 获取连接名称 +func getConnName(connName string, connections map[interface{}]interface{}) string { + if connName == "" { + var got int + gotName := make(map[int]string) + fmt.Printf("请选中以下连接数据库配置\n") + for name, m := range connections { + conf := m.(map[interface{}]interface{}) + driver := conf["driver"] + if driver == "mysql" || driver == "pgsql" { + got++ + gotName[got] = name.(string) + fmt.Printf("%v: %v\n", got, name) + } + } + if len(gotName) == 1 { + got = 1 + fmt.Printf("只有一个数据库, 已经自动选中: 1\n") + } else { + fmt.Printf("请输入数字: ") + fmt.Scan(&got) + } + connName = gotName[got] + } + + if _, ok := connections[connName]; !ok { + panic("没有找不到对应数据库连接") + } + + return connName +} + +func getTableName(tableName string, m interface{}) string { + conf := m.(map[interface{}]interface{}) + if tableName == "" { + fmt.Printf("未指定表, 可以使用以下的表生成\n") + tables := make(map[int]string) + switch conf["driver"] { + case "mysql": + db := orm.NewDb(conf) + rows, _ := db.GetDB().Query("SELECT A.TABLE_NAME as name FROM INFORMATION_SCHEMA.COLUMNS A WHERE A.TABLE_SCHEMA = ? GROUP BY TABLE_NAME", conf["database"].(string)) + defer rows.Close() + i := 0 + for rows.Next() { + i++ + var name string + rows.Scan(&name) + tables[i] = name + fmt.Printf("%v: %v\n", i, name) + } + case "pgsql": + + } + + fmt.Printf("请输入数字: ") + var got int + fmt.Scan(&got) + tableName = tables[got] + } + + return tableName +} + func buildController(input command.Input, outUrl string, module string, contName string) { cont := outUrl + "/" + input.GetOption("table_name") + "_controller.go" str := "package " + input.GetOption("table_name") diff --git a/console/commands/orm.go b/console/commands/orm.go index 23bcf05..7a581ec 100644 --- a/console/commands/orm.go +++ b/console/commands/orm.go @@ -8,6 +8,7 @@ import ( "github.com/go-home-admin/toolset/console/commands/pgorm" "github.com/joho/godotenv" "gopkg.in/yaml.v2" + "log" "os" "os/exec" "strings" @@ -52,10 +53,10 @@ func (OrmCommand) Execute(input command.Input) { fileContext = SetEnv(fileContext) m := make(map[string]interface{}) err = yaml.Unmarshal(fileContext, &m) - //if err != nil { - // panic(err) - //} - + if err != nil { + log.Printf("配置解析错误:%v", err) + return + } connections := m["connections"].(map[interface{}]interface{}) for s, confT := range connections { conf := confT.(map[interface{}]interface{}) diff --git a/go.mod b/go.mod index 7e46f6f..11ed586 100644 --- a/go.mod +++ b/go.mod @@ -3,42 +3,19 @@ module github.com/go-home-admin/toolset go 1.16 require ( - github.com/ctfang/command v1.0.0 + github.com/ctfang/command v1.0.1 github.com/go-home-admin/home v0.0.3 github.com/go-sql-driver/mysql v1.6.0 github.com/joho/godotenv v1.4.0 github.com/lib/pq v1.10.6 - github.com/sirupsen/logrus v1.8.1 gopkg.in/yaml.v2 v2.4.0 - gorm.io/gorm v1.23.5 + gorm.io/gorm v1.23.5 // indirect ) require ( - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-gonic/gin v1.8.0 // indirect - github.com/go-playground/locales v0.14.0 // indirect - github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.11.0 // indirect - github.com/go-redis/redis/v8 v8.11.5 // indirect - github.com/goccy/go-json v0.9.7 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.5 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/kr/pretty v0.3.0 // indirect - github.com/kr/text v0.2.0 // indirect - github.com/leodido/go-urn v1.2.1 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.0.1 // indirect - github.com/rogpeppe/go-internal v1.8.1 // indirect - github.com/ugorji/go/codec v1.2.7 // indirect golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect - golang.org/x/text v0.3.7 // indirect - google.golang.org/protobuf v1.28.0 // indirect gorm.io/driver/mysql v1.3.4 // indirect ) diff --git a/go.sum b/go.sum index fcb39d0..9a45499 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/ctfang/command v1.0.0 h1:CurDflG0o7GntcRWWzbFlKdR3CMZUF/627Rv/Ii8HNE= -github.com/ctfang/command v1.0.0/go.mod h1:iWJcUCwZReswQ7T5IaRE6ZvGzZ/m9v53Z1na20JttV8= +github.com/ctfang/command v1.0.1 h1:e3GA3c68h153zs/AtTslY1+HpXMzrGkUqA8R4Qj9dtg= +github.com/ctfang/command v1.0.1/go.mod h1:iWJcUCwZReswQ7T5IaRE6ZvGzZ/m9v53Z1na20JttV8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From d216997a4d45fe82cb722c1afbe10de952d8f750 Mon Sep 17 00:00:00 2001 From: baichou Date: Mon, 20 Jun 2022 18:47:46 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E4=B8=BB=E9=94=AE=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- console/commands/orm/mysql.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/console/commands/orm/mysql.go b/console/commands/orm/mysql.go index 3672bdf..e8d71d3 100644 --- a/console/commands/orm/mysql.go +++ b/console/commands/orm/mysql.go @@ -411,7 +411,7 @@ ORDER BY } col.ColumnName = parser.StringToHump(col.COLUMN_NAME) - col.GoType = typeForMysqlToGo[col.DATA_TYPE] + col.GoType = TypeForMysqlToGo[col.DATA_TYPE] if _, ok := tableColumns[col.TABLE_NAME]; !ok { tableColumns[col.TABLE_NAME] = []tableColumn{} @@ -510,7 +510,7 @@ type tableColumnIndex struct { NON_UNIQUE string } -var typeForMysqlToGo = map[string]string{ +var TypeForMysqlToGo = map[string]string{ "int": "int64", "integer": "int64", "tinyint": "int32", From babb07f2303f35d3fc758fabc337736258aed81a Mon Sep 17 00:00:00 2001 From: baichou Date: Tue, 21 Jun 2022 10:38:09 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- console/commands/curd.go | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/console/commands/curd.go b/console/commands/curd.go index 3500ba1..cc7da2b 100644 --- a/console/commands/curd.go +++ b/console/commands/curd.go @@ -44,8 +44,9 @@ func (CurdCommand) Configure() command.Configure { Default: "@root/config/database.yaml", }, { - Name: "go_out", - Description: "生成文件到指定目录", + Name: "module", + Description: "模块名称, 默认: admin", + Default: "admin", }, { Name: "explain", @@ -78,14 +79,12 @@ func (CurdCommand) Execute(input command.Input) { connections := m["connections"].(map[interface{}]interface{}) connName := getConnName(input.GetOption("conn_name"), connections) tableName := getTableName(input.GetOption("table_name"), connections[connName]) + config := connections[connName].(map[interface{}]interface{}) TableColumns := GetTableColumn(config, tableName) - out := input.GetOption("go_out") - if out == "" { - log.Printf("请输入保存到目录地址") - return - } - outUrl := root + "/app/http/admin/" + out + "/" + tableName + + module := input.GetOption("module") + outUrl := root + "/app/http/" + module + "/" + tableName _, err = os.Stat(outUrl) if os.IsNotExist(err) { err = os.MkdirAll(outUrl, 0766) @@ -94,7 +93,7 @@ func (CurdCommand) Execute(input command.Input) { return } } - protoUrl := root + "/protobuf/admin/" + out + "/" + tableName + protoUrl := root + "/protobuf/" + module + "/" + tableName _, err = os.Stat(protoUrl) if os.IsNotExist(err) { err = os.MkdirAll(protoUrl, 0766) @@ -111,19 +110,19 @@ func (CurdCommand) Execute(input command.Input) { } else { contName = strings.ToUpper(tableName) } - module := getModModule() + goMod := getModModule() //controller - buildController(input, outUrl, module, contName) + buildController(input, outUrl, goMod, contName) //del - buildDel(input, outUrl, module, "del", contName) + buildDel(input, outUrl, goMod, "del", contName) //get - buildGet(input, outUrl, module, "get", contName) + buildGet(input, outUrl, goMod, "get", contName) //post - buildPost(input, outUrl, module, "post", contName) + buildPost(input, outUrl, goMod, "post", contName) //put - buildPut(input, outUrl, module, "put", contName) + buildPut(input, outUrl, goMod, "put", contName) //proto - buildProto(input, protoUrl, module, contName, TableColumns) + buildProto(input, protoUrl, goMod, contName, TableColumns) } // 获取连接名称 From d5b0ead1e389dcc0981b4f1693edbc7c7c421221 Mon Sep 17 00:00:00 2001 From: dabai <975446398@qq.com> Date: Mon, 15 Aug 2022 14:21:10 +0800 Subject: [PATCH 10/10] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- console/commands/curd.go | 196 ++++++++++++++++++++++----------------- 1 file changed, 113 insertions(+), 83 deletions(-) diff --git a/console/commands/curd.go b/console/commands/curd.go index cc7da2b..91b121c 100644 --- a/console/commands/curd.go +++ b/console/commands/curd.go @@ -24,6 +24,16 @@ type TableColumn struct { Comment string } +type Param struct { + CoonName string + TableName string + Module string + Explain string + DbName string +} + +var param Param + func (CurdCommand) Configure() command.Configure { return command.Configure{ Name: "make:curd", @@ -77,14 +87,14 @@ func (CurdCommand) Execute(input command.Input) { return } connections := m["connections"].(map[interface{}]interface{}) - connName := getConnName(input.GetOption("conn_name"), connections) - tableName := getTableName(input.GetOption("table_name"), connections[connName]) + param.CoonName = getConnName(input.GetOption("conn_name"), connections) + param.TableName = getTableName(input.GetOption("table_name"), connections[param.CoonName]) - config := connections[connName].(map[interface{}]interface{}) - TableColumns := GetTableColumn(config, tableName) + config := connections[param.CoonName].(map[interface{}]interface{}) + TableColumns := GetTableColumn(config, param.TableName) module := input.GetOption("module") - outUrl := root + "/app/http/" + module + "/" + tableName + outUrl := root + "/app/http/" + module + "/" + param.TableName _, err = os.Stat(outUrl) if os.IsNotExist(err) { err = os.MkdirAll(outUrl, 0766) @@ -93,7 +103,7 @@ func (CurdCommand) Execute(input command.Input) { return } } - protoUrl := root + "/protobuf/" + module + "/" + tableName + protoUrl := root + "/protobuf/" + module + "/" + param.TableName _, err = os.Stat(protoUrl) if os.IsNotExist(err) { err = os.MkdirAll(protoUrl, 0766) @@ -102,27 +112,27 @@ func (CurdCommand) Execute(input command.Input) { return } } - index := strings.Index(tableName, "_") + index := strings.Index(param.TableName, "_") contName := "" if index >= 0 { - other := tableName[index+1:] - contName = strings.ToUpper(tableName[:1]) + tableName[1:index] + strings.ToUpper(other[:1]) + other[1:] + other := param.TableName[index+1:] + contName = strings.ToUpper(param.TableName[:1]) + param.TableName[1:index] + strings.ToUpper(other[:1]) + other[1:] } else { - contName = strings.ToUpper(tableName) + contName = strings.ToUpper(param.TableName) } goMod := getModModule() //controller - buildController(input, outUrl, goMod, contName) + buildController(param, outUrl, goMod, contName) //del - buildDel(input, outUrl, goMod, "del", contName) + buildDel(param, outUrl, goMod, "del", contName) //get - buildGet(input, outUrl, goMod, "get", contName) + buildGet(param, outUrl, goMod, "get", contName, TableColumns) //post - buildPost(input, outUrl, goMod, "post", contName) + buildPost(param, outUrl, goMod, "post", contName, TableColumns) //put - buildPut(input, outUrl, goMod, "put", contName) + buildPut(param, outUrl, goMod, "put", contName, TableColumns) //proto - buildProto(input, protoUrl, goMod, contName, TableColumns) + buildProto(param, protoUrl, goMod, contName, TableColumns) } // 获取连接名称 @@ -188,15 +198,11 @@ func getTableName(tableName string, m interface{}) string { return tableName } -func buildController(input command.Input, outUrl string, module string, contName string) { - cont := outUrl + "/" + input.GetOption("table_name") + "_controller.go" - str := "package " + input.GetOption("table_name") - pack := module + "/app/entity/" + input.GetOption("db_name") - str += "\n\nimport (\n \"" + pack + "\"\n)" - str += "\n\n// " + input.GetOption("explain") - str += "\ntype Controller struct {" - str += "\n orm *" + input.GetOption("db_name") + "." + contName + " `inject:\"\"`" - str += "\n}" +func buildController(param Param, outUrl string, module string, contName string) { + cont := outUrl + "/" + param.TableName + "_controller.go" + str := "package " + param.TableName + str += "\n\n// " + param.Explain + str += "\ntype Controller struct {}" err := os.WriteFile(cont, []byte(str), 0766) if err != nil { log.Printf(err.Error()) @@ -204,13 +210,15 @@ func buildController(input command.Input, outUrl string, module string, contName } } -func buildHead(table_name string, module string) string { - str := "package " + table_name +func buildHead(tableName string, module string, name string) string { + str := "package " + tableName tm := []string{ "github.com/gin-gonic/gin", - module + "/app/common", + module + "/app/common/auth", + module + "/app/entity/" + param.CoonName, module + "/app/providers", - module + "/generate/proto/admin/" + table_name, + module + "/generate/proto/admin", + module + "/home/app/http", } str += "\n\nimport (" for _, v := range tm { @@ -220,19 +228,19 @@ func buildHead(table_name string, module string) string { return str } -func buildDel(input command.Input, outUrl string, module string, name string, contName string) { +func buildDel(param Param, outUrl string, module string, name string, contName string) { cont := outUrl + "/del_action.go" - str := buildHead(input.GetOption("table_name"), module) - str += "\n\n// Del 删除数据 - " + input.GetOption("explain") - str += "\nfunc (receiver *Controller) Del(req *" + input.GetOption("go_out") + "." + contName + "PutRequest, ctx *auth.Context) (*" + - input.GetOption("go_out") + "." + contName + "PutRequest, error) {" - str += "\n id := common.GetParamId(ctx)" - str += "\n receiver.orm.Delete(id)" - str += "\n return &" + input.GetOption("go_out") + "." + contName + "PutRequest{" + str := buildHead(param.TableName, module, name) + str += "\n\n// Del 删除数据 - " + param.Explain + str += "\nfunc (receiver *Controller) Del(req *admin" + "." + contName + "PutRequest, ctx *auth.Context) (*admin" + "." + contName + "PutRequest, error) {" + str += "\n id := ctx.GetId()" + str += "\n err := " + param.CoonName + ".NewOrm" + contName + ".Delete(id)" + str += "\n return &admin" + "." + contName + "PutRequest{" str += "\n Tip: \"OK\"," - str += "\n }, nil" + str += "\n }, err.Error" str += "\n}" - str += handleValue(name, input.GetOption("go_out"), contName) + str += "\n" + str += handleValue(name, "admin", contName) err := os.WriteFile(cont, []byte(str), 0766) if err != nil { log.Printf(err.Error()) @@ -240,16 +248,23 @@ func buildDel(input command.Input, outUrl string, module string, name string, co } } -func buildGet(input command.Input, outUrl string, module string, name string, contName string) { +func buildGet(param Param, outUrl string, module string, name string, contName string, column []TableColumn) { cont := outUrl + "/get_action.go" - str := buildHead(input.GetOption("table_name"), module) - str += "\n\n// Get 列表查询 - " + input.GetOption("explain") + str := buildHead(param.TableName, module, name) + str += "\n\n// Get 列表查询 - " + param.Explain + co := "" + for _, v := range column { + co += fmt.Sprintf(` + %v: cp.%v,`, + v.Name, v.Name) + } str += fmt.Sprintf(` -func (receiver *Controller) Get(req *%v.%vGetRequest, ctx *auth.Context) (*%v.%vGetRequest, error) { - list, total := receiver.orm.GetPaginate(req.Page, req.Limit) +func (receiver *Controller) Get(req *%v.%vGetRequest, ctx *auth.Context) (*%v.%vGetResponse, error) { + list, total := %v.NewOrm%v().Paginate(int(req.Page), int(req.Limit)) responseList := make([]*%v.%vInfo, 0) for _, cp := range list { - responseList = append(responseList, &%v.%vInfo{}) + responseList = append(responseList, &%v.%vInfo{%v + }) } return &%v.%vGetResponse{ List: responseList, @@ -257,18 +272,21 @@ func (receiver *Controller) Get(req *%v.%vGetRequest, ctx *auth.Context) (*%v.%v }, nil } `, - input.GetOption("go_out"), + "admin", contName, - input.GetOption("go_out"), + "admin", contName, - input.GetOption("table_name"), + param.CoonName, contName, - input.GetOption("table_name"), + "admin", contName, - input.GetOption("go_out"), + "admin", + contName, + co, + "admin", contName, ) - str += handleValue(name, input.GetOption("go_out"), contName) + str += handleValue(name, "admin", contName) err := os.WriteFile(cont, []byte(str), 0766) if err != nil { log.Printf(err.Error()) @@ -276,27 +294,30 @@ func (receiver *Controller) Get(req *%v.%vGetRequest, ctx *auth.Context) (*%v.%v } } -func buildPost(input command.Input, outUrl string, module string, name string, contName string) { +func buildPost(param Param, outUrl string, module string, name string, contName string, column []TableColumn) { cont := outUrl + "/post_action.go" - str := buildHead(input.GetOption("table_name"), module) - str += "\n\n// Post 创建新数据 - " + input.GetOption("explain") - str += "\nfunc (receiver *Controller) Post(req *" + input.GetOption("go_out") + "." + contName + "PostRequest, ctx *auth.Context) (*" + - input.GetOption("go_out") + "." + contName + "PostRequest, error) {" + str := buildHead(param.TableName, module, name) + str += "\n\n// Post 创建新数据 - " + param.Explain + str += "\nfunc (receiver *Controller) Post(req *admin" + "." + contName + "PostRequest, ctx *auth.Context) (*admin" + "." + contName + "PostResponse, error) {" str += "\n id := int32(common.GetParamId(ctx))" str += "\n has := receiver.orm.WhereId(id).First()" str += "\n if has == nil {" str += "\n return nil, nil" str += "\n }" - split := strings.Split(input.GetOption("table_name"), "_") + split := strings.Split(param.TableName, "_") dbFunc := "" for _, t := range split { dbFunc += strings.ToUpper(t[:1]) + t[1:] } - str += "\n data := " + input.GetOption("db_name") + "." + dbFunc + "{}" + str += "\n data := " + param.CoonName + "." + dbFunc + "{" + for _, v := range column { + str += "\n " + v.Name + ": " + "cp." + v.Name + "," + } + str += "\n }" str += "\n res := receiver.orm.Create(&data)" - str += "\n return &" + input.GetOption("go_out") + "." + contName + "PostResponse{}, res.Error" + str += "\n return &admin" + "." + contName + "PostResponse{}, res.Error" str += "\n}" - str += handleValue(name, input.GetOption("go_out"), contName) + str += handleValue(name, "admin", contName) err := os.WriteFile(cont, []byte(str), 0766) if err != nil { log.Printf(err.Error()) @@ -304,26 +325,29 @@ func buildPost(input command.Input, outUrl string, module string, name string, c } } -func buildPut(input command.Input, outUrl string, module string, name string, contName string) { +func buildPut(param Param, outUrl string, module string, name string, contName string, column []TableColumn) { cont := outUrl + "/put_action.go" - str := buildHead(input.GetOption("table_name"), module) - str += "\n\n// Put 更新数据 - " + input.GetOption("explain") - str += "\nfunc (receiver *Controller) Put(req *" + input.GetOption("go_out") + "." + contName + "PostRequest, ctx *auth.Context) (*" + - input.GetOption("go_out") + "." + contName + "PostRequest, error) {" + str := buildHead(param.TableName, module, name) + str += "\n\n// Put 更新数据 - " + param.Explain + str += "\nfunc (receiver *Controller) Put(req *admin" + "." + contName + "PostRequest, ctx *auth.Context) (*admin" + "." + contName + "PostRequest, error) {" str += "\n id := int32(common.GetParamId(ctx))" str += "\n has := receiver.orm.WhereId(id).First()" str += "\n if has == nil {" str += "\n return nil, nil" str += "\n }" - split := strings.Split(input.GetOption("table_name"), "_") + split := strings.Split(param.TableName, "_") dbFunc := "" for _, t := range split { dbFunc += strings.ToUpper(t[:1]) + t[1:] } - str += "\n receiver.orm.WhereId(id).Updates(&" + input.GetOption("db_name") + "." + dbFunc + "{})" - str += "\n return &" + input.GetOption("go_out") + "." + contName + "PutResponse{}, nil" + str += "\n err := receiver.orm.WhereId(id).Updates(&" + param.CoonName + "." + dbFunc + "{" + for _, v := range column { + str += "\n " + v.Name + ": " + "cp." + v.Name + "," + } + str += "})" + str += "\n return &admin" + "." + contName + "PutResponse{}, err.Error" str += "\n}" - str += handleValue(name, input.GetOption("go_out"), contName) + str += handleValue(name, "admin", contName) err := os.WriteFile(cont, []byte(str), 0766) if err != nil { log.Printf(err.Error()) @@ -339,15 +363,18 @@ func handleValue(name string, module string, contName string) string { func (receiver *Controller) GinHandle%v(ctx *gin.Context) { req := &%v.%v%vRequest{} err := ctx.ShouleBind(req) + if err != nil { providers.ErrorRequest(ctx, err) return } + resp, err := receiver.%v(req, auth.NewContext(ctx)) if err != nil { providers.ErrorResponse(ctx, err) return } + providers.SuccessResponse(ctx, resp) } `, @@ -360,32 +387,32 @@ func (receiver *Controller) GinHandle%v(ctx *gin.Context) { return str } -func buildProto(input command.Input, protoUrl string, module string, contName string, column []TableColumn) { - cont := protoUrl + "/" + input.GetOption("table_name") + ".proto" +func buildProto(param Param, protoUrl string, module string, contName string, column []TableColumn) { + cont := protoUrl + "/" + param.TableName + ".proto" str := "// @Tag(\"form\");" str += "\nsyntax = \"proto3\";" - str += "\n\npackage " + input.GetOption("table_name") + ";" + str += "\n\npackage " + param.TableName + ";" str += "\n\nimport \"http_config.proto\";" - str += "\n\noption go_package = \"" + module + "/generate/proto/admin/" + input.GetOption("go_out") + "\";" - str += "\n// " + input.GetOption("explain") + "资源控制器" + str += "\n\noption go_package = \"" + module + "/generate/proto/admin\"" + ";" + str += "\n// " + param.Explain + "资源控制器" str += "\nservice " + contName + "{" str += "\n // 需要登录" str += "\n option (http.RouteGroup) = \"login\";" - str += "\n // " + input.GetOption("explain") + "列表" + str += "\n // " + param.Explain + "列表" str += "\n rpc Get(" + contName + "GetRequest) returns (" + contName + "GetResponse){" - str += "\n option (http.Get) = \"/" + input.GetOption("go_out") + "/" + input.GetOption("table_name") + "\";" + str += "\n option (http.Get) = \"/admin" + "/" + param.TableName + "\";" str += "\n }" - str += "\n // " + input.GetOption("explain") + "创建" + str += "\n // " + param.Explain + "创建" str += "\n rpc Post(" + contName + "PostRequest) returns (" + contName + "PostResponse){" - str += "\n option (http.Post) = \"/" + input.GetOption("go_out") + "/" + input.GetOption("table_name") + "\";" + str += "\n option (http.Post) = \"/admin" + "/" + param.TableName + "\";" str += "\n }" - str += "\n // " + input.GetOption("explain") + "更新" + str += "\n // " + param.Explain + "更新" str += "\n rpc Put(" + contName + "PutRequest) returns (" + contName + "PutResponse){" - str += "\n option (http.Put) = \"/" + input.GetOption("go_out") + "/" + input.GetOption("table_name") + "/:id\";" + str += "\n option (http.Put) = \"/admin" + "/" + param.TableName + "/:id\";" str += "\n }" - str += "\n // " + input.GetOption("explain") + "删除" + str += "\n // " + param.Explain + "删除" str += "\n rpc Del(" + contName + "PutRequest) returns (" + contName + "PutResponse){" - str += "\n option (http.Get) = \"/" + input.GetOption("go_out") + "/" + input.GetOption("table_name") + "/:id\";" + str += "\n option (http.Get) = \"/admin" + "/" + param.TableName + "/:id\";" str += "\n }" str += "\n}" str += "\nmessage " + contName + "GetRequest {" @@ -417,7 +444,10 @@ func buildProto(input command.Input, protoUrl string, module string, contName st str += "\nmessage " + contName + "Info{" for i, v := range column { str += "\n // " + v.Comment - str += "\n " + v.GoType + " " + v.Name + " = " + strconv.Itoa(i) + ";" + if v.GoType == "database.Time" { + v.GoType = "string" + } + str += "\n " + v.GoType + " " + v.Name + " = " + strconv.Itoa(i+1) + ";" } str += "\n}" err := os.WriteFile(cont, []byte(str), 0766)