██████╗ ██╗███╗ ██╗ ███████╗██████╗ █████╗ ███╗ ███╗███████╗██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗
██╔════╝ ██║████╗ ██║ ██╔════╝██╔══██╗██╔══██╗████╗ ████║██╔════╝██║ ██║██╔═══██╗██╔══██╗██║ ██╔╝
██║ ███╗██║██╔██╗ ██║█████╗█████╗ ██████╔╝███████║██╔████╔██║█████╗ ██║ █╗ ██║██║ ██║██████╔╝█████╔╝
██║ ██║██║██║╚██╗██║╚════╝██╔══╝ ██╔══██╗██╔══██║██║╚██╔╝██║██╔══╝ ██║███╗██║██║ ██║██╔══██╗██╔═██╗
╚██████╔╝██║██║ ╚████║ ██║ ██║ ██║██║ ██║██║ ╚═╝ ██║███████╗╚███╔███╔╝╚██████╔╝██║ ██║██║ ██╗
╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
├── Dockerfile
├── LICENSE
├── Makefile # makefile
├── README.md
├── app # 模块存放目录
│ ├── amqp # 消息队列
│ ├── controller # 控制器
│ └── service # 服务层
├── bootstrap # 初始化程序加载服务
├── cmd # command命令
│ ├── admin.go # 生成admin后台账号
│ ├── controller.go # 生成controller控制器
│ ├── migrate.go # 生成migrate数据库迁移
│ ├── model.go # 生成model数据模型
│ ├── service.go # 生成服务层
├── config
│ ├── config.go # yaml配置文件映射成结构体
│ ├── white_list.go # 白名单
│ └── yaml # yaml配置文件目录
├── global # 全局变量和全局方法
├── go.mod
├── go.sum
├── main.go
├── middleware # 中间件
├── migrations # 迁移文件
├── models # 模型
├── pkg # 自定义的常用服务,JWT,助手函数等
│ ├── auth # jwt
│ ├── lib # 日志服务,数据库服务,redis服务等
│ ├── paginator # 分页器
│ ├── response # http请求返回的状态和格式化
│ ├── util # 助手函数
│ └── validator # 参数验证器
├── router # 路由配置
├── runtime # 运行时产生的文件 如日志等
├── types # 所有自定义的结构体
- 支持 jwt Authorization token验证组件
- 支持 cors 接口跨域组件
- 支持 gorm 数据库操作组件
- 支持 gorm-model 自主实现的基于gorm生成的映射数据表的model结构体
- 支持 logrus 日志收集组件
- 支持 go-redis redis连接组件
- 支持 migrate 数据库迁移组件
- 支持 controller、service 命令行方式生成代码工具
- 支持 go-websocket 基于 gorilla/websocket 实现的即时通讯组件(单个客户端,多个客户端,群组,广播推送等)
- 支持 go-rabbitmq 消息队列组件 基于rabbitmq官方 amqp 组件封装实现的消费者和生产者
- 支持 casbin rbac权限 集成于中间件中 casbin_auth.go
- 支持 requestId 中间件 实现了方便链路追踪日志记录中间件 requestid_auth.go
- 支持 viper yaml、json、toml等配置文件解析组件
- 支持 validator 数据字段验证器组件,同时支持中文
- 支持 snowflake 生成雪花算法全局唯一ID
- 实现 ip白名单配置 集成于中间件中 ip_auth.go
- 实现 ticker 定时器组件
- 实现 基于gorm的 pagination 分页构造器组件
- 实现 code 统一定义的返回码,exception 统一错误返回处理组件
注意启动前需要将 mysql服务和redis服务开启,并配置config.dev.yaml文件(默认读取dev环境)中的mysql和redis配置
go mod tidy
go run main.go
# 查看 main.go的参数
go run main.go --help
{
"status": 200,
"errcode": 0,
"requestid": "9ac7f4f2-1271-4f87-8df7-599a478af9cb",
"message": "Pong!",
"data": ""
}
go install github.com/cosmtrek/air@latest
命令行敲入:air 即可执行热更新 代码编辑即更新
此步骤针对于backend接口进行权限访问
go run main.go migrate -s=all
# 具体参数查看help
go run main.go migrate -help
此接口会创建一个基于casbin的超级管理员权限
# 查看make命令行
make help
# 基础打包,生成可执行文件(根据当前系统)
make build
# 打包windows
make windows
# 打包darwin
make darwin
# 打包linux
make linux
在releases中查看打包的文件
引用包
import "github.com/MQEnergy/gin-framework/pkg/paginator"
var memberList = make([]models.GinAdmin, 0)
paginator, err := paginator.NewBuilder().
WithDB(global.DB).
WithModel(models.GinAdmin{}).
WithField([]string{"password", "salt", "updated_at", "_omit"}).
WithCondition("id = ?", 1).
Pagination(memberList, 1, 10)
return paginator, err
定义接收struct
type BaseUser models.GinUser
type GinUserInfo models.GinUserInfo
// UserList 获取关联列表
type UserList struct {
BaseUser
GinUserInfo `gorm:"foreignKey:user_id" json:"user_info"`
}
用法一:
var userList = make([]user.UserList, 0)
pagination, err := paginator.NewBuilder().
WithDB(global.DB).
WithModel(models.GinUser{}).
WithFields(models.GinUser{}, models.GinUserTbName, []string{"password", "salt", "_omit"}).
WithFields(models.GinUserInfo{}, models.GinUserInfoTbName, []string{"id", "user_id", "role_ids"}).
WithJoins("left", []paginator.OnJoins{{
LeftTableField: paginator.JoinTableField{Table: models.GinUserTbName, Field: "id"},
RightTableField: paginator.JoinTableField{Table: models.GinUserInfoTbName, Field: "user_id"},
}}).
Pagination(&userList, requestParams.Page, global.Cfg.Server.DefaultPageSize)
return pagination, err
用法二:
var userList = make([]user.UserList, 0)
multiFields := []paginator.SelectTableField{
{Model: models.GinUser{}, Table: models.GinUserTbName, Field: []string{"password", "salt", "_omit"}},
{Model: models.GinUserInfo{}, Table: models.GinUserInfoTbName, Field: []string{"user_id", "role_ids"}},
}
pagination, err := paginator.NewBuilder().
WithDB(global.DB).
WithModel(models.GinUser{}).
WithMultiFields(multiFields).
WithJoins("left", []paginator.OnJoins{{
LeftTableField: paginator.JoinTableField{Table: models.GinUserTbName, Field: "id"},
RightTableField: paginator.JoinTableField{Table: models.GinUserInfoTbName, Field: "user_id"},
}}).
Pagination(&userList, requestParams.Page, global.Cfg.Server.DefaultPageSize)
return pagination, err
注意:
与joins查询方式定义的struct有些许差别,preload方式定义struct名称必须与model当前表的struct名称一致,
且关联表的struct名称不能跟model对于的struct名称一样 例如:定义的`UserInfo` 写法如下
定义接收struct
type BaseUser models.GinUser
type GinUserInfo models.GinUserInfo
type GinUser struct {
BaseUser
UserInfo GinUserInfo `gorm:"foreignKey:user_id" json:"user_info"`
}
用法如下:
var userList = make([]user.GinUser, 0)
pagination, err := paginator.NewBuilder().
WithDB(global.DB).
WithModel(models.GinUser{}).
WithPreload("UserInfo").
Pagination(&userList, requestParams.Page, global.Cfg.Server.DefaultPageSize)
return pagination, err
此写法不建议使用WithFields、WithField查询字段,建议直接定义接收struct规定的查询字段即可
访问地址:http://127.0.0.1:9527/user/index?page=1 返回数据格式如下:
{
"status": 200,
"errcode": 0,
"requestid": "9ac7f4f2-1271-4f87-8df7-599a478af9cb",
"message": "请求成功",
"data": {
"list": [],
"current_page": 1,
"total": 2,
"last_page": 1,
"per_page": 10
}
}
1)用法如下 获取用户列表:
entities/user/gin_user.go
app/controller/backend/user.go
app/service/backend/user.go
router/routes/common.go
查看使用
WithDB(db *gorm.DB) *PageBuilder
传入全局global.DB
WithModel(model interface{}) *PageBuilder
传入查询主表model 例如:models.GinAdmin 参数不能传结构体取地址方式 如:&models.GinAdmin
WithField(fields []string) *PageBuilder
fields 最后一个参数默认为_select(可不传),如传_omit为过滤前面传输的字段。
注意:
- _select / _omit 必须在最后
- WithModel 参数不能传结构体取地址 例如:&models.GinAdmin 必须 models.GinAdmin 不然 _omit 参数失效
- 此注意事项适用于
WithFields
方法、WithMultiFields
方法
用法如下:
// 表示过滤前面字段
WithField([]string{"created_at", "updated_at", "_omit"})
// 表示查询前面的字段
WithField([]string{"created_at", "updated_at", "_select"})
WithField([]string{"created_at", "updated_at"})
WithFields(model interface{}, table string, fields []string) *PageBuilder
fields 最后一个参数默认为_select(可不传),如传_omit为过滤前面传输的字段。
用法如下:
// 表示过滤前面字段
WithFields(models.GinUser{}, models.GinUserTbName, []string{"password", "salt", "_omit"})
// 表示查询前面的字段
WithFields(models.GinUserInfo{}, models.GinUserInfoTbName, []string{"id", "user_id", "role_ids", "_select"})
WithFields(models.GinUserInfo{}, models.GinUserInfoTbName, []string{"id", "user_id", "role_ids"})
WithMultiFields(fields []SelectTableField) *PageBuilder
用法如下:
WithMultiFields([]paginator.SelectTableField{
{Model: models.GinUser{}, Table: models.GinUserTbName, Field: []string{"password", "salt", "_omit"}},
{Model: models.GinUserInfo{}, Table: models.GinUserInfoTbName, Field: []string{"id", "user_id", "role_ids"}},
})
WithPreloads(querys []string) *PageBuilder
用法如下:
WithPreloads([]string{"UserInfo", "UserRecord"})
WithPreload(query string, args ...interface{}) *PageBuilder
用法如下:
WithPreload("UserInfo", "user_id = ?", "1")
WithCondition(query interface{}, args ...interface{}) *PageBuilder
传入查询条件 支持gorm中where条件中的查询方式(非struct方式) query, args参数参照gorm的where条件传入方式
WithJoins(joinType string, joinFields []OnJoins) *PageBuilder
joinType:join类型 可传入:left、right、inner,joinFields结构体: LeftTableField:如:主表.ID RightTableField:如:关联表.主表ID
用法如下:
WithJoins("left", []paginator.OnJoins{{
LeftTableField: paginator.JoinTableField{Table: models.GinUserTbName, Field: "id"},
RightTableField: paginator.JoinTableField{Table: models.GinUserInfoTbName, Field: "user_id"},
}})
Pagination(dst interface{}, currentPage, pageSize int) (Page, error)
dst 传入接收数据的struct结构体 注意:必须是应用方式传递 如:&userList, model,currentPage 为当前页码,pageSize为每页查询数量
NewDB() *gorm.DB
用此方法之后的链式操作下pagination里面的方法均不可用,后面跟gorm原生方法即可
用法如下:
NewDB().Where("id = ?", id).First(&userList)
paginator.CurrentPage
paginator.List
paginator.Total
paginator.LastPage
paginator.PerPage
UploadFile(path string, r *gin.Context) (*FileHeader, error)
默认存储在项目中upload目录,如果没有会自动创建 path:upload目录模块目录 如:user 则目录是:upload/user/{yyyy-mm-dd}/...
用法如下:
app/controller/backend/attachment.go
pkg/util/upload.go
router/routes/common.go
配置yaml配置文件中的amqp参数
测试案例
go run command/test/consumer.go
测试案例
go run command/test/producer.go
运行 go run main.go --help 可查看到以下命令集
COMMANDS:
migrate Create a migration command
account Create a new admin account
model Create a new model class
controller Create a new controller class
service Create a new service class
help, h Shows a list of commands or help for one command
查看使用
# 安装migrate cli工具
curl -L https://github.com/golang-migrate/migrate/releases/download/$version/migrate.$platform-amd64.tar.gz | tar xvz
# MacOS安装
brew install golang-migrate
# Window 使用scoop安装 https://scoop.sh/
scoop install migrate
# 创建迁移文件语法例如:
migrate create -ext sql -dir migrations -seq create_users_table
# 第一种方式执行迁移
# 执行迁移操作:
migrate -database 'mysql://root:123456@tcp(127.0.0.1:3306)/gin_framework' -path ./migrations up
# 执行回滚操作:
migrate -database 'mysql://root:123456@tcp(127.0.0.1:3306)/gin_framework' -path ./migrations down
# 第二种方式执行迁移
# 查看help命令
go run main.go migrate --help
# 格式如下:
go run main.go migrate -s {step} -e {env}
# env: dev, test, prod与config.*.yaml文件保持一致 默认是dev
# step:执行的迁移文件数量(回滚的文件数量)例如:1,2,3... 如果执行所有传 all
# 执行所有迁移操作:
go run main.go migrate -s all
# 执行部分迁移操作:
# 如:go run main.go migrate -s 1
# 执行回滚操作:
# 如:go run main.go migrate -s -1
# 执行生成所有model
go run main.go model -tb=all {env}
# 具体参数查看help
go run main.go model -help
go run main.go controller -c={controller名称} -m={module名称}
# 例如:go run main.go controller -c=admin -m=backend
# 具体参数查看help
go run main.go controller -help
go run main.go service -s={service名称} -m={module名称}
# module名称是app/controller目录下的模块名称
# 例如:go run main.go service -s=admin -m=backend
# 具体参数查看help
go run main.go service -help
go run main.go account -c={账号名称} -p={密码}
# 具体参数查看help
go run main.go account -help