Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #45

Merged
merged 5 commits into from
Jun 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion assets/templates/index/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ <h4 class="text-gray"><i class="linecons-tag" style="margin-right: 7px;" id="{{
<div class="row">
{{ range .SiteList }}
<div class="col-sm-3">
<div class="xe-widget xe-conversations box2 label-info" onclick="window.open('{{ .Url }}', '_blank')"
<div class="xe-widget xe-conversations box2 label-info" onclick="window.open('{{ .URL }}', '_blank')"
data-toggle="tooltip" data-placement="bottom" title="" data-original-title="{{ .Description }}">
<div class="xe-comment-entry">
<a class="xe-user-img">
Expand Down
91 changes: 91 additions & 0 deletions cmd/gormgen/generate_table.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package gormgen

import (
"github.com/ch3nnn/webstack-go/internal/repository/mysql"
"github.com/ch3nnn/webstack-go/internal/repository/mysql/model"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/gorm"
)

// Method 根据动态 sql 生成 orm
type Method interface {
// GetParentIdsByGroupParentId
// SELECT GROUP_CONCAT(a.parent_id) AS parent_ids from (SELECT parent_id FROM category GROUP BY parent_id) as a
GetParentIdsByGroupParentId() (gen.M, error)
}

func GenerateTable(tables []string) {

g := gen.NewGenerator(gen.Config{
OutPath: "./internal/repository/mysql/query",
Mode: gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface, // generate mode
})

// reuse your gorm db
repo, _ := mysql.New()
g.UseDB(repo.GetDbW())

// 自定义字段的数据类型
// 统一数字类型为int64,兼容protobuf (columnType gorm.ColumnType) (dataType string)
dataMap := map[string]func(columnType gorm.ColumnType) (dataType string){
"tinyint": func(columnType gorm.ColumnType) (dataType string) { return "int64" },
"smallint": func(columnType gorm.ColumnType) (dataType string) { return "int64" },
"mediumint": func(columnType gorm.ColumnType) (dataType string) { return "int64" },
"bigint": func(columnType gorm.ColumnType) (dataType string) { return "int64" },
"int": func(columnType gorm.ColumnType) (dataType string) { return "int64" },
"integer": func(columnType gorm.ColumnType) (dataType string) { return "int64" },
}
// 要先于`ApplyBasic`执行
g.WithDataTypeMap(dataMap)

// 将非默认字段名的字段定义为自动时间戳和软删除字段;
// 自动时间戳默认字段名为:`updated_at`、`created_at, 表字段数据类型为: INT 或 DATETIME
// 软删除默认字段名为:`deleted_at`, 表字段数据类型为: DATETIME
//autoUpdateTimeField := gen.FieldGORMTag("update_time", func(tag field.GormTag) field.GormTag {return })
//autoCreateTimeField := gen.FieldGORMTag("create_time", "column:create_time;type:int unsigned;autoCreateTime")

// 模型自定义选项组
//fieldOpts := []gen.ModelOpt{autoCreateTimeField, autoUpdateTimeField}

// 分类
category := g.GenerateModel("category")
g.ApplyInterface(func(Method) {}, model.Category{})
// 网址
site := g.GenerateModel("site", gen.FieldRelate(field.BelongsTo, "Category", category, &field.RelateConfig{
GORMTag: map[string]string{"foreignKey": "CategoryID"},
}),
)
// 菜单
menu := g.GenerateModel("menu")
// 菜单动作
menuAction := g.GenerateModel("menu_action")
// 管理员菜单栏表
adminMenu := g.GenerateModel("admin_menu")
// 管理员表
admin := g.GenerateModel("admin")
// 定时任务表
cronTask := g.GenerateModel("cron_task")
// 已授权接口地址表
authorizedApi := g.GenerateModel("authorized_api")
// 已授权的调用方表
authorized := g.GenerateModel("authorized")
// 自定义表结构生成
for _, table := range tables {
g.ApplyBasic(g.GenerateModel(table))
}

// 创建全部模型文件, 并覆盖前面创建的同名模型
//allModel := g.GenerateAllTable(fieldOpts...)

// Generate basic type-safe DAO API for struct `model.User` following conventions
g.ApplyBasic(site, menu, menuAction, adminMenu, admin, cronTask, authorizedApi, authorized)
//g.ApplyBasic(allModel)

// Generate the code
g.Execute()
}

//func main() {
// GenerateTable(nil)
//}
106 changes: 106 additions & 0 deletions cmd/handlergen/generate_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package handlergen

import (
"fmt"
"github.com/xinliangnote/go-gin-api/pkg/errors"
"go/token"
"io/ioutil"
"os"
"strings"
"unicode"

"github.com/dave/dst"
"github.com/dave/dst/decorator"
)

func Lcfirst(str string) string {
for i, v := range str {
return string(unicode.ToLower(v)) + str[i+1:]
}
return ""
}

func GenerateHandler(handlerName string) (err error) {
fs := token.NewFileSet()
filePath := fmt.Sprintf("./internal/api/%s", handlerName)
parsedFile, err := decorator.ParseFile(fs, filePath+"/handler.go", nil, 0)
if err != nil {
return errors.New(fmt.Sprintf("parsing package: %s: %s\n", filePath, err))
}

files, _ := ioutil.ReadDir(filePath)
if len(files) > 1 {
return errors.New(fmt.Sprintf("请先确保 %s 目录中,有且仅有 handler.go 一个文件。", filePath))
}

dst.Inspect(parsedFile, func(n dst.Node) bool {
decl, ok := n.(*dst.GenDecl)
if !ok || decl.Tok != token.TYPE {
return true
}

for _, spec := range decl.Specs {
typeSpec, _ok := spec.(*dst.TypeSpec)
if !_ok {
continue
}

var interfaceType *dst.InterfaceType
if interfaceType, ok = typeSpec.Type.(*dst.InterfaceType); !ok {
continue
}

for _, v := range interfaceType.Methods.List {
if len(v.Names) > 0 {
if v.Names[0].String() == "i" {
continue
}

filepath := "./internal/api/" + handlerName
filename := fmt.Sprintf("%s/func_%s.go", filepath, strings.ToLower(v.Names[0].String()))
funcFile, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0766)
if err != nil {
fmt.Printf("create and open func file error %v\n", err.Error())
continue
}

if funcFile == nil {
fmt.Printf("func file is nil \n")
continue
}

fmt.Println(" └── file : ", filename)

funcContent := fmt.Sprintf("package %s\n\n", handlerName)
funcContent += "import (\n"
funcContent += `"github.com/xinliangnote/go-gin-api/internal/pkg/core"`
funcContent += "\n)\n\n"
funcContent += fmt.Sprintf("\n\ntype %sRequest struct {}\n\n", Lcfirst(v.Names[0].String()))
funcContent += fmt.Sprintf("type %sResponse struct {}\n\n", Lcfirst(v.Names[0].String()))

// 首行注释
funcContent += fmt.Sprintf("%s\n", v.Decorations().Start.All()[0])

nameArr := strings.Split(v.Decorations().Start.All()[0], v.Names[0].String())
funcContent += fmt.Sprintf("// @Summary%s \n", nameArr[1])
funcContent += fmt.Sprintf("// @Description%s \n", nameArr[1])
// Tags
funcContent += fmt.Sprintf("%s \n", v.Decorations().Start.All()[1])
funcContent += fmt.Sprintf("// @Accept application/x-www-form-urlencoded \n")
funcContent += fmt.Sprintf("// @Produce json \n")
funcContent += fmt.Sprintf("// @Param Request body %sRequest true \"请求信息\" \n", Lcfirst(v.Names[0].String()))
funcContent += fmt.Sprintf("// @Success 200 {object} %sResponse \n", Lcfirst(v.Names[0].String()))
funcContent += fmt.Sprintf("// @Failure 400 {object} code.Failure \n")
// Router
funcContent += fmt.Sprintf("%s \n", v.Decorations().Start.All()[2])
funcContent += fmt.Sprintf("func (h *handler) %s() core.HandlerFunc { \n return func(ctx core.Context) {\n\n}}", v.Names[0].String())

funcFile.WriteString(funcContent)
funcFile.Close()
}
}
}
return true
})
return
}
15 changes: 10 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ require (
github.com/gocolly/colly v1.2.0
github.com/gorilla/websocket v1.4.2
github.com/jakecoffman/cron v0.0.0-20190106200828-7e2009c226a5
github.com/jinzhu/gorm v1.9.16
github.com/mat/besticon v0.0.0-20230308222644-ee1fe52e97c1
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.11.1
Expand All @@ -29,8 +30,10 @@ require (
go.uber.org/multierr v1.7.0
go.uber.org/zap v1.19.1
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11
gorm.io/driver/mysql v1.2.0
gorm.io/gorm v1.22.3
golang.org/x/tools v0.7.0
gorm.io/driver/mysql v1.4.4
gorm.io/gen v0.3.22
gorm.io/gorm v1.24.2
)

require (
Expand All @@ -54,15 +57,15 @@ require (
github.com/go-openapi/jsonreference v0.19.5 // indirect
github.com/go-openapi/spec v0.20.3 // indirect
github.com/go-openapi/swag v0.19.14 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/goccy/go-json v0.10.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/hashicorp/golang-lru v0.5.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.2 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kennygrant/sanitize v1.2.4 // indirect
Expand Down Expand Up @@ -99,7 +102,6 @@ require (
golang.org/x/net v0.8.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/tools v0.7.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
Expand All @@ -108,4 +110,7 @@ require (
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c // indirect
gorm.io/hints v1.1.0 // indirect
gorm.io/plugin/dbresolver v1.3.0 // indirect
)
Loading