Skip to content

Commit

Permalink
feat: add new template
Browse files Browse the repository at this point in the history
  • Loading branch information
qinains committed Dec 26, 2020
1 parent 41b0fa7 commit 7173f1b
Show file tree
Hide file tree
Showing 28 changed files with 1,181 additions and 7 deletions.
45 changes: 38 additions & 7 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,40 @@
# codegen是什么
codegen是一款根据sql生成项目代码工具
codegen是一款根据sql生成项目代码的工具

## 使用
### 直接使用
```
git clone https://github.com/qinains/codegen.git
cd codegen
cp configs/configs-example.json configs/configs.json
# 编辑 configs/configs.json 中的数据库配置等信息
go run main.go
# 在 dist/ 文件夹中生成对应文件
```

### 在项目中使用
```
go get -u github.com/qinains/codegen
# 在项目中创建如 codegen/ 的文件夹,结构如下
# project
# └── codegen
# ├── configs/configs.json
# └── template
# └── default
# ├── api
# ├── ...
# ...
cd project/codegen
codegen
# 在 dist/ 文件夹中生成对应文件
```

## 功能特点
1. 可对项目文件夹进行配置
2. 可编写模板

## 配置
配置文件位于configs/configs.json中,其中
配置文件位于 configs/configs.json 文件中,其中
```
ModuleName 模块名,比如 example、github.com/qinains/example
TemplateDir 模板目录,比如 tamplate
Expand All @@ -19,10 +47,13 @@ BreakerWords 注释断开词,取断点前的字符串,如:创建时
InitialismWords 通用字,将转化为大写,比如 id -> ID, ip -> IP
```

## 模板引擎说明
参考[https://golang.google.cn/pkg/text/template/](https://golang.google.cn/pkg/text/template/)
## 模板编写
默认模板位于 template/default/ 文件夹中,可通过配置文件中的"TemplateDir"配置项修改为其他值

### 模板引擎说明
参考 [https://golang.google.cn/pkg/text/template/](https://golang.google.cn/pkg/text/template/)

## 可用变量
### 可用变量
```
.moduleName 模块名
.table 表
Expand All @@ -46,10 +77,10 @@ InitialismWords 通用字,将转化为大写,比如 id -> ID, ip -> IP
[].table 以上定义的"表"数组
```

## 文件夹编写说明
### 文件夹编写说明
因为Windows系统文件名中不能包含`|`字符,当遇到使用过滤器文件名的情况,用`__vertical_bar__`代替`|`

## 可使用过滤器和函数
### 可使用过滤器和函数
字符串过滤器
```
Upper 都转大写 如:user_id -> USER_ID
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{{define "dataType" -}}
{{if or (Contains .dataType "bigint") (eq .columnName "id") -}}int64
{{- else if Contains .dataType "tinyint"}}int8
{{- else if Contains .dataType "int"}}int
{{- else if Contains .dataType "varchar"}}string
{{- else if Contains .dataType "decimal"}}{{if IsGE .numericPrecision 18}}float64{{else}}float32{{end}}
{{- else if Contains .dataType "text"}}string
{{- end}}
{{- end -}}
package do

// {{.table.tableName | Pascal}} {{.table.tableComment}}
type {{.table.tableName | Pascal}} struct {
{{- range $k,$v := .table.columns}}
{{$v.columnName | Pascal}} {{template "dataType" $v}} `gorm:"type:{{$v.columnType | Upper}};
{{- if eq $v.columnKey "PRI"}}primaryKey;
{{- else if eq $v.columnKey "UNI"}}uniqueIndex;
{{- else if eq $v.columnKey "MUL"}}index;
{{- end -}}
{{- if eq $v.extra "auto_increment"}}autoIncrement;{{end -}}
{{- if eq $v.isNullable "NO"}}not null;{{end -}}
{{- if eq $v.columnName "create_time"}}autoCreateTime:milli;
{{- else if eq $v.columnName "update_time"}}autoUpdateTime:milli;
{{- else if IsNotNil $v.columnDefault}}default:{{$v.columnDefault}};
{{- end -}}
comment:{{$v.columnComment}}"` // {{$v.columnComment}}{{end}}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{{define "dataType" -}}
{{if Contains .dataType "bigint" -}}int64
{{- else if Contains .dataType "tinyint"}}int8
{{- else if Contains .dataType "int"}}int
{{- else if Contains .dataType "varchar"}}string
{{- else if Contains .dataType "decimal"}}{{if IsGE .numericPrecision 18}}float64{{else}}float32{{end}}
{{- else if Contains .dataType "text"}}string
{{- end}}
{{- end -}}
package dto

import "{{$.moduleName}}/pkg/util"


// {{.table.tableName | Pascal}}Form 表单:{{.table.tableComment}}
type {{.table.tableName | Pascal}}Form struct {
util.Request
Sort string // 排序: ID,ID desc,Sort,Sort desc
{{- range $k,$v := .table.columns -}}
{{- if or (Contains $v.columnName "id") (Contains $v.columnName "status")}}
{{$v.columnName | Pascal}} {{template "dataType" $v}} // {{$v.columnComment}}
{{$v.columnName | Pascal}}List []{{template "dataType" $v}} // {{$v.columnComment | Breaker}}列表
{{- else if Contains $v.columnName "_time"}}
{{$v.columnName | Pascal}} []{{template "dataType" $v}} // {{$v.columnComment}}
{{- else if Contains $v.columnName "sort" -}}
{{- else}}
{{$v.columnName | Pascal}} {{template "dataType" $v}} // {{$v.columnComment}}
{{- end -}}
{{end}}
}
27 changes: 27 additions & 0 deletions template/default/api/pkg/router/router.go.gohtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package router

import (
"github.com/gin-gonic/gin"
"{{$.moduleName}}/pkg/config"
{{range $k0,$table := .tables}}
"{{$.moduleName}}/pkg/web"
{{- end}}
)

func NewRouter(router *gin.Engine, config *base.Config) {
router.StaticFile("favicon.ico", "./favicon.ico")
router.StaticFile("/", "./index.html")
for k, v := range config.Static {
router.StaticFile(k, v)
}
router.Static("/static", "./static")
router.Static(config.File.WebRelativePath, config.File.WebUploadRoot) //文件访问
{{range $k0,$table := .tables}}
router.POST("{{$table.tableName | Dash}}/create-{{$table.tableName | Dash}}", {{$table.tableName | LowerAll}}.Create{{$table.tableName | Pascal}}) // 创建{{$table.tableComment | Breaker}}
router.POST("{{$table.tableName | Dash}}/delete-{{$table.tableName | Dash}}", {{$table.tableName | LowerAll}}.Delete{{$table.tableName | Pascal}}) // 删除{{$table.tableComment | Breaker}}
router.POST("{{$table.tableName | Dash}}/update-{{$table.tableName | Dash}}", {{$table.tableName | LowerAll}}.Update{{$table.tableName | Pascal}}) // 更新{{$table.tableComment | Breaker}}
router.POST("{{$table.tableName | Dash}}/find-{{$table.tableName | Dash}}", {{$table.tableName | LowerAll}}.Find{{$table.tableName | Pascal}}) // {{$table.tableComment | Breaker}}详情
router.POST("{{$table.tableName | Dash}}/find-{{$table.tableName | Dash}}-list", {{$table.tableName | LowerAll}}.Find{{$table.tableName | Pascal}}List) // {{$table.tableComment | Breaker}}列表
{{end}}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package service

import (
"{{$.moduleName}}/pkg/config"
"{{$.moduleName}}/pkg/do"
"{{$.moduleName}}/pkg/dto"
)

// Create{{.table.tableName | Pascal}} 创建{{.table.tableComment | Breaker}}
func Create{{.table.tableName | Pascal}}({{.table.tableName | Camel}} *do.{{.table.tableName | Pascal}}) error {
result := config.DB.Create(&{{.table.tableName | Camel}})
return result.Error
}

// Delete{{.table.tableName | Pascal}} 删除{{.table.tableComment | Breaker}}
func Delete{{.table.tableName | Pascal}}(IDList []int64) (int64, error) {
result := config.DB.Delete(&do.{{.table.tableName | Pascal}}{}, IDList)
return result.RowsAffected, result.Error
}

// Update{{.table.tableName | Pascal}} 更新{{.table.tableComment | Breaker}}
func Update{{.table.tableName | Pascal}}({{.table.tableName | Camel}} *do.{{.table.tableName | Pascal}}) (int64, error) {
result := config.DB.Save(&{{.table.tableName | Camel}})
return result.RowsAffected, result.Error
}

// Find{{.table.tableName | Pascal}} {{.table.tableComment | Breaker}}详情
func Find{{.table.tableName | Pascal}}(ID int64) (do.{{.table.tableName | Pascal}}, error) {
var {{.table.tableName | Camel}} do.{{.table.tableName | Pascal}}
result := config.DB.First(&{{.table.tableName | Camel}}, ID)
return {{.table.tableName | Camel}}, result.Error
}

// Find{{.table.tableName | Pascal}}List {{.table.tableComment | Breaker}}列表
func Find{{.table.tableName | Pascal}}List({{.table.tableName | Camel}}Form dto.{{.table.tableName | Pascal}}Form) ({{.table.tableName | Camel}}List []*do.{{.table.tableName | Pascal}}, total int64, err error) {
switch {{$.table.tableName | Camel}}Form.Sort {
default:
{{$.table.tableName | Camel}}Form.Sort = "{{$.table.tableName}}.id desc"
{{range $k,$v := .table.columns -}}
case "{{$v.columnName | Pascal}}":
{{$.table.tableName | Camel}}Form.Sort = "{{$.table.tableName}}.{{$v.columnName}}"
case "{{$v.columnName | Pascal}} desc":
{{$.table.tableName | Camel}}Form.Sort = "{{$.table.tableName}}.{{$v.columnName}} desc"
{{end -}}
}
sql := config.DB.Offset({{.table.tableName | Camel}}Form.Offset()).Limit({{.table.tableName | Camel}}Form.Size).Order({{.table.tableName | Camel}}Form.Sort)

{{- range $k,$v := .table.columns -}}
{{- if or (Contains $v.columnName "id") (Contains $v.columnName "status")}}
if {{$.table.tableName | Camel}}Form.{{$v.columnName | Pascal}} {{if IsStringDataType $v.dataType}}!= ""{{else}}> 0{{end}} {
sql = sql.Where("{{$.table.tableName}}.{{$v.columnName}} = ?", {{$.table.tableName | Camel}}Form.{{$v.columnName | Pascal}})
}
if len({{$.table.tableName | Camel}}Form.{{$v.columnName | Pascal}}List) > 1 {
sql = sql.Where("{{$.table.tableName}}.{{$v.columnName}} in (?)", {{$.table.tableName | Camel}}Form.{{$v.columnName | Pascal}}List)
}
{{- else if Contains $v.columnName "_time"}}
if len({{$.table.tableName | Camel}}Form.{{$v.columnName | Pascal}}) > 1 {
sql = sql.Where("{{$.table.tableName}}.{{$v.columnName}} > ? and {{$.table.tableName}}.{{$v.columnName}} <= ? ", {{$.table.tableName | Camel}}Form.{{$v.columnName | Pascal}}[0], {{$.table.tableName | Camel}}Form.{{$v.columnName | Pascal}}[1])
}
{{- else if IsStringDataType $v.dataType}}
if {{$.table.tableName | Camel}}Form.{{$v.columnName | Pascal}} != "" {
sql = sql.Where("{{$.table.tableName}}.{{$v.columnName}} like ?", "%"+{{$.table.tableName | Camel}}Form.{{$v.columnName | Pascal}}+"%")
}
{{- else if Contains $v.columnName "sort" -}}
{{- else }}
if {{$.table.tableName | Camel}}Form.{{$v.columnName | Pascal}} >0 {
sql = sql.Where("{{$.table.tableName}}.{{$v.columnName}} = ?", {{$.table.tableName | Camel}}Form.{{$v.columnName | Pascal}})
}
{{- end -}}
{{end}}

result := sql.Find(&{{.table.tableName | Camel}}List).Offset(-1).Limit(-1).Count(&total)
err = result.Error
return
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package web

import (
"github.com/gin-gonic/gin"
"{{$.moduleName}}/pkg/do"
"{{$.moduleName}}/pkg/dto"
"{{$.moduleName}}/pkg/service"
"{{$.moduleName}}/pkg/util"
"strings"
)

// Create{{.table.tableName | Pascal}} 创建{{.table.tableComment | Breaker}}
// @Summary 创建{{.table.tableComment | Breaker}}
// @Tags {{.table.tableComment | Breaker}}
// @Accept json
// @Produce json
// @Param X-Token header string true "Token信息" default(abc123)
// @Param json body do.{{.table.tableName | Pascal}} true "{{.table.tableComment | Breaker}}"
// @Success 200 {object} util.Response{Data=do.{{.table.tableName | Pascal}}} "{{.table.tableComment | Breaker}}"
// @Failure 400
// @Security ApiKeyAuth
// @Security OAuth2Implicit[admin, user]
// @Router /{{.table.tableName | Dash}}/create-{{.table.tableName | Dash}} [post]
func Create{{.table.tableName | Pascal}}(c *gin.Context) {
var {{.table.tableName | Camel}} *do.{{.table.tableName | Pascal}}
if err := c.ShouldBind(&{{.table.tableName | Camel}}); err != nil {
// todo 优化输出
util.ErrorForm(c, err.Error())
return
}

if err := service.Create{{.table.tableName | Pascal}}({{.table.tableName | Camel}}); err != nil {
if strings.Contains(err.Error(), "Duplicate entry") {
util.ErrorBusiness(c, "{{.table.tableComment | Breaker}}已经存在")
return
}
util.ErrorForm(c, err.Error())
return
}
util.OK(c, "", {{.table.tableName | Camel}})
}

// Delete{{.table.tableName | Pascal}} 删除{{.table.tableComment | Breaker}}
// @Summary 删除{{.table.tableComment | Breaker}}
// @Tags {{.table.tableComment | Breaker}}
// @Accept json
// @Produce json
// @Param X-Token header string true "Token信息" default(abc123)
// @Param json body dto.{{.table.tableName | Pascal}}Form true "ID列表" example {"IDList[]": [1,2]}
// @Success 200 {object} util.Response "通用返回,Code==20000表示删除成功"
// @Failure 400
// @Security ApiKeyAuth
// @Security OAuth2Implicit[admin, user]
// @Router /{{.table.tableName | Dash}}/delete-{{.table.tableName | Dash}} [post]
func Delete{{.table.tableName | Pascal}}(c *gin.Context) {
var {{.table.tableName | Camel}}Form dto.{{.table.tableName | Pascal}}Form
if err := c.ShouldBind(&{{.table.tableName | Camel}}Form); err != nil {
// todo 优化输出
util.ErrorForm(c, err.Error())
return
}

if _, err := service.Delete{{.table.tableName | Pascal}}({{.table.tableName | Camel}}Form.IDList); err != nil {
util.ErrorForm(c, err.Error())
return
}
util.OK(c, "", nil)
}

// Update{{.table.tableName | Pascal}} 更新{{.table.tableComment | Breaker}}
// @Summary 更新{{.table.tableComment | Breaker}}
// @Tags {{.table.tableComment | Breaker}}
// @Accept json
// @Produce json
// @Param X-Token header string true "Token信息" default(abc123)
// @Param json body do.{{.table.tableName | Pascal}} true "{{.table.tableComment | Breaker}}"
// @Success 200 {object} util.Response{Data=do.{{.table.tableName | Pascal}}} "{{.table.tableComment | Breaker}}"
// @Failure 400
// @Security ApiKeyAuth
// @Security OAuth2Implicit[admin, user]
// @Router /{{.table.tableName | Dash}}/update-{{.table.tableName | Dash}} [post]
func Update{{.table.tableName | Pascal}}(c *gin.Context) {
var {{.table.tableName | Camel}} *do.{{.table.tableName | Pascal}}
if err := c.ShouldBind(&{{.table.tableName | Camel}}); err != nil {
// todo 优化输出
util.ErrorForm(c, err.Error())
return
}

if _, err := service.Update{{.table.tableName | Pascal}}({{.table.tableName | Camel}}); err != nil {
util.ErrorForm(c, err.Error())
return
}
util.OK(c, "", {{.table.tableName | Camel}})
}

// Find{{.table.tableName | Pascal}} {{.table.tableComment | Breaker}}详情
// @Summary {{.table.tableComment | Breaker}}详情
// @Tags {{.table.tableComment | Breaker}}
// @Accept json
// @Produce json
// @Param X-Token header string true "Token信息" default(abc123)
// @Param json body do.{{.table.tableName | Pascal}} true "{{.table.tableComment | Breaker}}ID,比如{ID:1}"
// @Success 200 {object} util.Response{Data=do.{{.table.tableName | Pascal}}} "通用返回"
// @Failure 400
// @Security ApiKeyAuth
// @Security OAuth2Implicit[admin, user]
// @Router /{{.table.tableName | Dash}}/find-{{.table.tableName | Dash}} [post]
func Find{{.table.tableName | Pascal}}(c *gin.Context) {
var {{.table.tableName | Camel}} do.{{.table.tableName | Pascal}}
if err := c.ShouldBind(&{{.table.tableName | Camel}}); err != nil {
util.ErrorForm(c, err.Error())
return
}

{{.table.tableName | Camel}}, err := service.Find{{.table.tableName | Pascal}}({{.table.tableName | Camel}}.ID)
if err != nil {
util.ErrorBusiness(c, err.Error())
return
}
util.OK(c, "", {{.table.tableName | Camel}})
}

// Find{{.table.tableName | Pascal}}List {{.table.tableComment | Breaker}}列表
// @Summary {{.table.tableComment | Breaker}}列表
// @Tags {{.table.tableComment | Breaker}}
// @Accept json
// @Produce json
// @Param X-Token header string true "Token信息" default(abc123)
// @Param json body dto.{{.table.tableName | Pascal}}Form true "{{.table.tableComment | Breaker}}表单"
// @Success 200 {object} util.Response{Data=util.List{Items=[]do.{{.table.tableName | Pascal}}}} "{{.table.tableComment | Breaker}}"
// @Failure 400
// @Security ApiKeyAuth
// @Security OAuth2Implicit[admin, user]
// @Router /{{.table.tableName | Dash}}/find-{{.table.tableName | Dash}}-list [post]
func Find{{.table.tableName | Pascal}}List(c *gin.Context) {
var {{.table.tableName | Camel}}Form dto.{{.table.tableName | Pascal}}Form
if err := c.ShouldBind(&{{.table.tableName | Camel}}Form); err != nil {
// todo 优化输出
util.ErrorForm(c, err.Error())
return
}

{{.table.tableName | Camel}}List, total, err := service.Find{{.table.tableName | Pascal}}List({{.table.tableName | Camel}}Form)
if err != nil {
util.ErrorBusiness(c, err.Error())
return
}
util.OK(c, "", util.List{Total: total, Items: {{.table.tableName | Camel}}List})
}
Loading

0 comments on commit 7173f1b

Please sign in to comment.