From 5054d08daa592bd0809afe56ba7c5546d5302783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E9=BB=84?= <1520752231@qq.com> Date: Tue, 6 Apr 2021 16:35:41 +0800 Subject: [PATCH] new service --- .gitignore | 3 + go.mod | 32 ++++++++ main.go | 15 ++++ modelgen/cmd.go | 1 + modelgen/gen.go | 29 +++++++ servicegen/cmd.go | 25 ++++++ servicegen/gen.go | 183 ++++++++++++++++++++++++++++++++++++++++++ servicegen/tmpl.go | 26 ++++++ servicegen/tmpl/api.tmpl | 18 +++++ servicegen/tmpl/api_pre.tmpl | 54 +++++++++++++ servicegen/tmpl/api_task.tmpl | 18 +++++ servicegen/tmpl/api_test.tmpl | 31 +++++++ servicegen/tmpl/db_model.tmpl | 91 +++++++++++++++++++++ servicegen/tmpl/external.tmpl | 1 + servicegen/tmpl/options.tmpl | 3 + 15 files changed, 530 insertions(+) create mode 100644 .gitignore create mode 100644 go.mod create mode 100644 main.go create mode 100644 modelgen/cmd.go create mode 100644 modelgen/gen.go create mode 100644 servicegen/cmd.go create mode 100644 servicegen/gen.go create mode 100644 servicegen/tmpl.go create mode 100644 servicegen/tmpl/api.tmpl create mode 100644 servicegen/tmpl/api_pre.tmpl create mode 100644 servicegen/tmpl/api_task.tmpl create mode 100644 servicegen/tmpl/api_test.tmpl create mode 100644 servicegen/tmpl/db_model.tmpl create mode 100644 servicegen/tmpl/external.tmpl create mode 100644 servicegen/tmpl/options.tmpl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3429c5c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +*.log +*.exe diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..47cac51 --- /dev/null +++ b/go.mod @@ -0,0 +1,32 @@ +module demo + +go 1.14 + +require ( + git.ouxuan.net/hasaki-service/hasaki-sdk v0.0.0-20210302071131-cb2b8d8c4800 + github.com/360EntSecGroup-Skylar/excelize/v2 v2.3.2 // indirect + github.com/apache/thrift v0.12.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/golang/protobuf v1.4.3 // indirect + github.com/golang/snappy v0.0.3 // indirect + github.com/jinzhu/gorm v1.9.16 // indirect + github.com/magiconair/properties v1.8.5 // indirect + github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/openzipkin/zipkin-go v0.1.6 // indirect + github.com/pelletier/go-toml v1.9.0 // indirect + github.com/spf13/afero v1.6.0 // indirect + github.com/spf13/cast v1.3.1 // indirect + github.com/spf13/cobra v1.1.3 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/viper v1.7.1 // indirect + github.com/tal-tech/go-zero v1.1.4 + github.com/xuri/efp v0.0.0-20210128032744-13be4fd5dcb5 // indirect + golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect + golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect + golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect + golang.org/x/text v0.3.6 // indirect + gopkg.in/ini.v1 v1.62.0 // indirect + xorm.io/builder v0.3.9 // indirect + xorm.io/xorm v1.0.7 // indirect +) diff --git a/main.go b/main.go new file mode 100644 index 0000000..be03a6f --- /dev/null +++ b/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "demo/servicegen" + "github.com/spf13/cobra" +) + +func main() { + rootCmd := cobra.Command{Use: "hskctl"} + rootCmd.AddCommand(servicegen.Command()) + err := rootCmd.Execute() + if err != nil { + panic(err) + } +} diff --git a/modelgen/cmd.go b/modelgen/cmd.go new file mode 100644 index 0000000..045bc87 --- /dev/null +++ b/modelgen/cmd.go @@ -0,0 +1 @@ +package modelgen diff --git a/modelgen/gen.go b/modelgen/gen.go new file mode 100644 index 0000000..779f5e4 --- /dev/null +++ b/modelgen/gen.go @@ -0,0 +1,29 @@ +package modelgen + +import ( + "git.ouxuan.net/hasaki-service/hasaki-sdk/hskdb" + "time" + "xorm.io/xorm" +) + +type Model struct { + Id int `json:"id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt time.Time `json:"deleted_at"` +} + +type Context struct { + session *xorm.Session + instance interface{} +} + +type UserModel struct { +} + +func (u *UserModel) Objects() *Context { + return &Context{ + session: hskdb.GetXormAuto().NewSession(), + instance: u, + } +} diff --git a/servicegen/cmd.go b/servicegen/cmd.go new file mode 100644 index 0000000..08ea0a1 --- /dev/null +++ b/servicegen/cmd.go @@ -0,0 +1,25 @@ +package servicegen + +import ( + "github.com/spf13/cobra" + "log" +) + +func Command() *cobra.Command { + newCmd := &cobra.Command{ + Use: "new [string to new]", + Short: "create service for hasaki", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + err := Gen(args[0]) + if err != nil { + log.Printf("Error: %+v\n", err) + } + }, + } + serviceCmd := &cobra.Command{ + Use: "service", + Short: "service command"} + serviceCmd.AddCommand(newCmd) + return serviceCmd +} diff --git a/servicegen/gen.go b/servicegen/gen.go new file mode 100644 index 0000000..129e38c --- /dev/null +++ b/servicegen/gen.go @@ -0,0 +1,183 @@ +package servicegen + +import ( + "os" + "path/filepath" + "text/template" +) + +/* 生成整个项目结构 +- hasaki-service-app + - hasaki-app + - api.go + - api_pre.go + - api_test.go + - api_task.go + - db_model.go + - handler.go + - initialize.go + - hasaki-app-options + - options.go + - hasaki-app-external + - external.go +*/ +func Gen(name string) error { + err := genService(name) + if err != nil { + return err + } + err = genApp(name) + if err != nil { + return err + } + err = genOptions(name) + if err != nil { + return err + } + err = genExternal(name) + if err != nil { + return err + } + return nil +} + +func genService(appName string) error { + rootDir, err := getRootDir(appName) + if err != nil { + return err + } + + err = os.Mkdir(rootDir, os.ModeDir) + if err != nil { + return err + } + + return nil +} + +func genApp(appName string) error { + appDir, err := getAppDir(appName) + if err != nil { + return err + } + + err = os.Mkdir(appDir, os.ModeDir) + if err != nil { + return err + } + + // api.go + err = parseTmpl(apiTmpl, filepath.Join(appDir, "api.go"), appName) + if err != nil { + return err + } + + // api_pre.go + err = parseTmpl(apiPreTmpl, filepath.Join(appDir, "api_pre.go"), appName) + if err != nil { + return err + } + + // api_task.go + err = parseTmpl(apiTaskTmpl, filepath.Join(appDir, "api_task.go"), appName) + if err != nil { + return err + } + + // api_test.go + err = parseTmpl(apiTestTmpl, filepath.Join(appDir, "api_test.go"), appName) + if err != nil { + return err + } + + err = parseTmpl(dbModelTmpl, filepath.Join(appDir, "db_model.go"), appName) + if err != nil { + return err + } + + return nil +} + +func genOptions(appName string) error { + optionsDir, err := getOptionsDir(appName) + if err != nil { + return err + } + err = os.Mkdir(optionsDir, os.ModeDir) + if err != nil { + return err + } + err = parseTmpl(optionsTmpl, filepath.Join(optionsDir, "options.go"), appName) + if err != nil { + return err + } + return nil +} + +func genExternal(appName string) error { + externalDir, err := getExternal(appName) + if err != nil { + return err + } + err = os.Mkdir(externalDir, os.ModeDir) + if err != nil { + return err + } + err = parseTmpl(externalTmpl, filepath.Join(externalDir, "extenral.go"), appName) + if err != nil { + return err + } + return nil +} + +func getRootDir(appName string) (string, error) { + rootDir := "hasaki-service-" + appName + pwd, err := os.Getwd() + if err != nil { + return "", err + } + path := filepath.Join(pwd, rootDir) + return path, nil +} + +func getAppDir(appName string) (string, error) { + appDir := "hasaki_" + appName + rootDir, err := getRootDir(appName) + if err != nil { + return "", err + } + path := filepath.Join(rootDir, appDir) + return path, nil +} + +func getOptionsDir(appName string) (string, error) { + optionsDir := "hasaki_" + appName + "_options" + rootDir, err := getRootDir(appName) + if err != nil { + return "", err + } + path := filepath.Join(rootDir, optionsDir) + return path, nil +} + +func getExternal(appName string) (string, error) { + externalDir := "hasaki_" + appName + "_external" + rootDir, err := getRootDir(appName) + if err != nil { + return "", err + } + path := filepath.Join(rootDir, externalDir) + return path, nil +} + +func parseTmpl(tmpl *template.Template, file string, appName string) error { + f, err := os.Create(file) + if err != nil { + return err + } + err = tmpl.Execute(f, map[string]interface{}{"app_name": appName}) + if err != nil { + return err + } + return nil +} diff --git a/servicegen/tmpl.go b/servicegen/tmpl.go new file mode 100644 index 0000000..580a0ab --- /dev/null +++ b/servicegen/tmpl.go @@ -0,0 +1,26 @@ +package servicegen + +import ( + "path/filepath" + "text/template" +) + +var ( + apiTmpl *template.Template + apiPreTmpl *template.Template + apiTaskTmpl *template.Template + apiTestTmpl *template.Template + dbModelTmpl *template.Template + optionsTmpl *template.Template + externalTmpl *template.Template +) + +func init() { + apiTmpl = template.Must(template.ParseFiles(filepath.Join("servicegen/tmpl/api.tmpl"))) + apiPreTmpl = template.Must(template.ParseFiles("servicegen/tmpl/api_pre.tmpl")) + apiTaskTmpl = template.Must(template.ParseFiles("servicegen/tmpl/api_task.tmpl")) + apiTestTmpl = template.Must(template.ParseFiles("servicegen/tmpl/api_test.tmpl")) + dbModelTmpl = template.Must(template.ParseFiles("servicegen/tmpl/db_model.tmpl")) + optionsTmpl = template.Must(template.ParseFiles("servicegen/tmpl/external.tmpl")) + externalTmpl = template.Must(template.ParseFiles("servicegen/tmpl/options.tmpl")) +} diff --git a/servicegen/tmpl/api.tmpl b/servicegen/tmpl/api.tmpl new file mode 100644 index 0000000..4888f8d --- /dev/null +++ b/servicegen/tmpl/api.tmpl @@ -0,0 +1,18 @@ +package hasaki_{{.app_name}} + +import "git.ouxuan.net/hasaki-service/hasaki-sdk/hskdb" + +func InitDb(config interface{}) (err error) { + if config == nil { + err = hskdb.XormSync2() + if err != nil { + return + } + } else { //分库 + err = hskdb.XormSync2(config) + if err != nil { + return + } + } + return +} diff --git a/servicegen/tmpl/api_pre.tmpl b/servicegen/tmpl/api_pre.tmpl new file mode 100644 index 0000000..d11edce --- /dev/null +++ b/servicegen/tmpl/api_pre.tmpl @@ -0,0 +1,54 @@ +package hasaki_{{.app_name}} + +import ( + "git.ouxuan.net/hasaki-service/hasaki-sdk/hskdb" + "git.ouxuan.net/hasaki-service/hasaki-service-{{.app_name}}/hasaki_{{.app_name}}_options" + "xorm.io/xorm" +) + +type Api struct { + db *xorm.Engine + config interface{} + session *xorm.Session +} + +func NewApi(dbs ...*xorm.Engine) *Api { + var db *xorm.Engine + if len(dbs) > 0 { + db = dbs[0] + } else { + db = hskdb.GetXormAuto() + } + return &Api{ + db: db, + session: db.NewSession(), + } +} + +func (api *Api) SetSession(s *xorm.Session) { + api.session = s +} + +func (api *Api) NewSession() *xorm.Session { + return api.session +} + +func GetApi(ctx interface{}) *Api { + config := hasaki_value_card_options.GetMysqlConfig(ctx) + if config == nil { + api := NewApi(hskdb.GetXormAuto()) + return api + } else { + api := NewApi(hskdb.GetXormAuto(config)) + api.config = config + return api + } +} + +func (api *Api) InitDb() (err error) { + return InitDb(api.config) +} + +func InitDbByConfig(config interface{}) (err error) { + return InitDb(config) +} \ No newline at end of file diff --git a/servicegen/tmpl/api_task.tmpl b/servicegen/tmpl/api_task.tmpl new file mode 100644 index 0000000..443e303 --- /dev/null +++ b/servicegen/tmpl/api_task.tmpl @@ -0,0 +1,18 @@ +package hasaki_{{.app_name}} + +import ( + "errors" + "fmt" + "git.ouxuan.net/hasaki-service/hasaki-service-ticker-task/hasaki_ticker_task" + "time" +) + +const TestTaskType = "test_task_type" + +func TestTask(item *hasaki_ticker_task.TickerTaskItem) error { + if item == nil || item.Data == nil { + return errors.New("数据异常") + } + // TODO: do some task... + return nil +} diff --git a/servicegen/tmpl/api_test.tmpl b/servicegen/tmpl/api_test.tmpl new file mode 100644 index 0000000..9d966a7 --- /dev/null +++ b/servicegen/tmpl/api_test.tmpl @@ -0,0 +1,31 @@ +package hasaki_{{.app_name}} + +import ( + "fmt" + "log" + "testing" + + "git.ouxuan.net/hasaki-service/hasaki-sdk/hskconfig" + "git.ouxuan.net/hasaki-service/hasaki-sdk/hskdb" +) + +var branch interface{} = "branch_brand_63" + +var api *Api + +func init() { + + hskconfig.NotFlag() + hskconfig.SetGolbalConfigFileName("E:\test.json") + + hskdb.IsAsyncToXormSync2 = false + api = NewApi(hskdb.GetXormAuto(branch)) + err := InitDbByConfig(branch) + if err != nil { + log.Fatalln(err) + } +} + +func TestNewApi(t *testing.T) { + // TODO: some test case... +} \ No newline at end of file diff --git a/servicegen/tmpl/db_model.tmpl b/servicegen/tmpl/db_model.tmpl new file mode 100644 index 0000000..62ff902 --- /dev/null +++ b/servicegen/tmpl/db_model.tmpl @@ -0,0 +1,91 @@ +package hasaki_{{.app_name}} + +import ( + "errors" + "git.ouxuan.net/hasaki-service/hasaki-sdk/hsktime" + "strconv" + "xorm.io/xorm" +) + +type Model struct { + Id int `json:"id" xorm:"not null pk autoincr INT(11)"` + CreatedAt hsktime.Time `json:"created_at" xorm:"created comment('创建时间')"` + UpdatedAt hsktime.Time `json:"updated_at" xorm:"updated comment('更新时间')"` + DeletedAt hsktime.Time `json:"-" xorm:"deleted comment('是否删除') TIMESTAMP INDEX"` + session *xorm.Session `xorm:"-"` + instance interface{} `xorm:"-"` +} + +func (m *Model) checkInstance() error { + if m.instance == nil { + return errors.New("instance 未实例化") + } + return nil +} + +func (m *Model) SetInstance(instance interface{}) { + m.instance = instance +} + +// 增删改查 +func (m *Model) Save(cols ...string) (int64, error) { + err := m.checkInstance() + if err != nil { + return 0, err + } + if m.Id > 0 { + if len(cols) > 0 { + return m.session.Cols(cols...).Update(m.instance) + } else { + return m.session.AllCols().Update(m.session) + } + } else { + return m.session.InsertOne(m.instance) + } +} + +func (m *Model) Del() (int64, error) { + err := m.checkInstance() + if err != nil { + return 0, err + } + return m.session.ID(m.Id).Delete(m.instance) +} + +func (m *Model) Get() (bool, error) { + err := m.checkInstance() + if err != nil { + return false, err + } + return m.session.Unscoped().Get(m.instance) +} + +//分页 cond["page"] 第几页 cond["page_size"] 多少条 +func Page(cond map[string]string, s *xorm.Session) *xorm.Session { + if cond["page_size"] != "" { + size, _ := strconv.Atoi(cond["page_size"]) + page, _ := strconv.Atoi(cond["page"]) + if page <= 0 { + page = 0 + } else { + page = page - 1 + } + s = s.Limit(size, page*size) + } + return s +} + +func Like(col, key string, s *xorm.Session) *xorm.Session { + if key != "" { + s = s.Where(col+" like ?", "%"+key+"%") + } + return s +} + + +func JsonContains(col, key string, s *xorm.Session) *xorm.Session { + if key != "" { + s = s.Where(`JSON_CONTAINS(` + col + `, '` + key + `', '$')`) + } + return s +} \ No newline at end of file diff --git a/servicegen/tmpl/external.tmpl b/servicegen/tmpl/external.tmpl new file mode 100644 index 0000000..c29727f --- /dev/null +++ b/servicegen/tmpl/external.tmpl @@ -0,0 +1 @@ +package hasaki_{{.app_name}}_external diff --git a/servicegen/tmpl/options.tmpl b/servicegen/tmpl/options.tmpl new file mode 100644 index 0000000..2af9a10 --- /dev/null +++ b/servicegen/tmpl/options.tmpl @@ -0,0 +1,3 @@ +package hasaki_{{.app_name}}_options + +var GetMysqlConfig = func(interface{}) interface{} { return nil }