ワンクリックで
go-gin-skill
Go Gin Web Framework - 基于 Gin 的企业级 Go Web 框架,提供分层架构、DAO 链式调用、代码生成、定时任务、队列、事件系统等开箱即用能力
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Go Gin Web Framework - 基于 Gin 的企业级 Go Web 框架,提供分层架构、DAO 链式调用、代码生成、定时任务、队列、事件系统等开箱即用能力
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | go-gin-skill |
| description | Go Gin Web Framework - 基于 Gin 的企业级 Go Web 框架,提供分层架构、DAO 链式调用、代码生成、定时任务、队列、事件系统等开箱即用能力 |
| author | auto-generated by repo2skill |
| platform | github |
| source | git@github.com:fanqingxuan/go-gin.git |
| tags | ["go","gin","web-framework","gorm","redis","cron","queue","dao","code-generation"] |
| version | 1.0.0 |
| generated | "2026-03-04T00:00:00.000Z" |
基于 Gin 的企业级 Go Web 应用框架,封装了自定义 HTTP 引擎、GoFrame 风格的 DAO 链式调用、代码生成工具、定时任务、异步队列、事件系统等功能模块,提供清晰的分层架构和开发规范。
# 1. 克隆项目
git clone git@github.com:fanqingxuan/go-gin.git
cd go-gin
# 2. 安装依赖
go mod tidy
# 3. 配置环境变量
cp .env.example .env # 编辑 .env 配置数据库/Redis等
# 4. 运行数据库迁移
go run cmd/migrate/main.go -f .env
# 5. 启动 API 服务
go run cmd/api/main.go -f .env
| 组件 | 技术选型 |
|---|---|
| 语言 | Go 1.24+ |
| Web 框架 | Gin v1.9 (自定义封装 httpx) |
| ORM | GORM v1.25 (自定义 Model 链式 API) |
| 数据库 | MySQL |
| 缓存 | Redis (go-redis v9) |
| 日志 | Zerolog |
| 队列 | Asynq (基于 Redis) |
| 定时任务 | robfig/cron v3 (自定义 cronx) |
| HTTP 客户端 | Resty v2 (自定义 httpc) |
| 验证器 | go-playground/validator v10 |
| Excel | excelize v2 |
router/ → controller/ → logic/ → model/
(any, error),框架自动处理响应格式model/entity/: 表结构 (GORM 模型,强类型,自动生成)model/do/: Data Object (any 类型,用于 Where/Data 条件)model/dao/: Data Access Object (单例实例 + Model 链式 API)go-gin/
├── cmd/ # 入口命令
│ ├── api/main.go # API 服务
│ ├── cron/main.go # 定时任务服务
│ ├── queue/main.go # 队列消费者服务
│ ├── migrate/main.go # 数据库迁移
│ └── make/main.go # 代码生成工具
├── config/ # 配置管理
├── const/ # 常量定义
│ ├── enum/ # 枚举定义
│ └── errcode/ # 业务错误码
├── controller/ # 控制器层
├── cron/ # 定时任务注册
├── event/ # 事件定义
│ └── listener/ # 事件监听器
├── internal/ # 框架内部包
│ ├── component/ # 基础组件 (db, logx, redisx)
│ ├── cronx/ # 定时任务引擎
│ ├── errorx/ # 错误处理
│ ├── etype/ # 枚举类型系统
│ ├── eventbus/ # 事件总线
│ ├── excelx/ # Excel/CSV 导出
│ ├── g/ # 通用类型别名 (g.Map, g.Var)
│ ├── httpc/ # HTTP 客户端
│ ├── httpx/ # HTTP 引擎封装
│ ├── migration/ # 迁移引擎
│ ├── queue/ # 队列引擎
│ ├── token/ # Token 工具
│ └── traceid/ # 链路追踪 ID
├── logic/ # 业务逻辑层
├── middleware/ # 中间件
├── migration/ # 迁移文件
├── model/ # 数据模型
│ ├── entity/ # 表结构 (自动生成)
│ ├── do/ # Data Object (自动生成)
│ └── dao/ # Data Access Object
├── rest/ # REST API 模块
├── router/ # 路由定义
├── task/ # 队列任务
├── test/ # 测试
├── transformer/ # 数据转换
├── typing/ # 请求/响应类型
│ └── query/ # 查询参数类型
└── util/ # 工具函数
框架封装了 Gin 引擎,Controller 方法签名为 func(ctx *httpx.Context) (any, error),框架自动处理 JSON 响应:
// 统一响应格式
{
"code": 200,
"message": "操作成功",
"data": { ... },
"trace_id": "xxx"
}
支持多种请求绑定方式:
httpx.Handle - 自动根据 Content-Type 绑定httpx.HandleJSON - JSON 绑定httpx.HandleQuery - Query 参数绑定httpx.HandleUri - URI 参数绑定httpx.HandleHeader - Header 绑定路由组支持 Before/After 中间件:
group.Before(authMiddleware).GET("/profile", controller.GetProfile)
基于 GORM 封装的链式 API,类似 GoFrame 的 Model 操作:
查询方法: One, Found, All, Scan, Count, Exist, Pluck, Value, Array
写入方法: Insert, InsertAndGetId, InsertIgnore, Update, Delete, Replace, Save
聚合方法: Min, Max, Avg, Sum
其他方法: Increment, Decrement, Chunk, ScanAndCount
条件构建器:
Where / WhereOr - 通用条件WherePri - 主键条件WhereLT/LTE/GT/GTE - 比较条件WhereBetween/WhereNotBetween - 范围条件WhereLike/WhereNotLike - 模糊查询WhereIn/WhereNotIn - IN 查询WhereNull/WhereNotNull - NULL 判断WhereNot - 不等于Wheref - 格式化条件 (仅用于动态列名)链式方法: Fields, FieldsEx, Order, Group, Having, Limit, Offset, Page, Distinct, Unscoped, Data, SetPrimaryKey
# 生成枚举方法 (扫描 const/enum/ 生成 gen_*.go)
go run ./cmd/make/... make:enum
# 生成 DAO 代码 (entity/do/dao 三层)
go run ./cmd/make/... make:dao -f .env # 所有表
go run ./cmd/make/... make:dao -f .env -t user # 指定表
# 生成迁移文件
go run ./cmd/make/... make:migration create_orders
类型安全的枚举,支持数据库扫描和 JSON 序列化:
// 定义枚举
type UserStatus struct { etype.BaseEnum }
var (
USER_STATUS_NORMAL = etype.NewEnum[UserStatus](1, "正常")
USER_STATUS_DISABLED = etype.NewEnum[UserStatus](2, "禁用")
)
// 使用
status.Code() // 1
status.Desc() // "正常"
status.Equal(USER_STATUS_NORMAL) // true
// 注册监听器
eventbus.AddListener(eventName, &MyListener{})
// 同步触发
eventbus.Fire(ctx, event.NewSampleEvent(payload))
// 异步触发
eventbus.FireAsync(ctx, event.NewSampleEvent(payload))
// 条件触发
eventbus.FireIf(ctx, condition, event)
eventbus.FireAsyncIf(ctx, condition, event)
// 分发任务
task.DispatchNow(task.NewSampleTask(data)) // 立即执行
task.NewSampleTask(data).Dispatch(5 * time.Minute) // 延迟执行
task.NewSampleTask(data).DispatchIf(condition) // 条件分发
// 内置队列监控 Web UI: /monitor/queue
支持 cron 表达式和 Laravel 风格的流式调度:
// cron 表达式
cronx.AddJob("@every 3s", &SampleJob{})
// 流式 API
cronx.Schedule(&SampleJob{}).EveryMinute()
cronx.Schedule(&SampleJob{}).DailyAt("08:30")
cronx.Schedule(&SampleJob{}).Weekly()
cronx.ScheduleFunc(func(ctx context.Context) error { ... }).EveryFiveMinutes()
可用调度方法:
EverySecond, EveryTwoSeconds, EveryFiveSeconds, EveryTenSeconds, EveryFifteenSeconds, EveryThirtySecondsEveryMinute, EveryTwoMinutes, EveryThreeMinutes, EveryFiveMinutes, EveryTenMinutes, EveryFifteenMinutes, EveryThirtyMinutesHourly, HourlyAt(minute), EveryTwoHours, EveryThreeHours, EveryFourHours, EverySixHoursDaily, DailyAt("HH:mm"), TwiceDaily(h1, h2), TwiceDailyAt(h1, h2, min)Weekly, WeeklyOn(day, "HH:mm"), Weekdays, Weekends, Mondays~SundaysMonthly, MonthlyOn(day, "HH:mm"), TwiceMonthly(d1, d2, "HH:mm"), LastDayOfMonth("HH:mm")Quarterly, Yearly, Cron("expression")excelx.Download(ctx.Context, "users.xlsx", headers, excelx.StructsToRows(users))
excelx.DownloadCSV(ctx.Context, "users.csv", headers, excelx.StructsToStringRows(users))
excelx.DownloadMultiSheet(ctx.Context, "report.xlsx", []excelx.Sheet{...})
链式调用的 HTTP 客户端,支持自动响应解析:
httpc.NewRequest().
SetContext(ctx).
SetBody(data).
SetResult(&response).
POST(url).
SendAndParse()
GoFrame 风格的类型别名和通用变量:
g.Map // map[string]any
g.Slice // []any
g.SliceStr // []string
g.Var // 通用变量,支持类型转换
g.NewVar(val).Int()
g.NewVar(val).String()
g.NewVar(val).Map()
// typing/order.go
package typing
type CreateOrderReq struct {
ProductId int `form:"product_id" binding:"required" label:"商品ID"`
Quantity int `form:"quantity" binding:"required,min=1" label:"数量"`
Amount float64 `form:"amount" binding:"required" label:"金额"`
}
type CreateOrderResp struct {
OrderId int `json:"order_id"`
Message string `json:"message"`
}
// logic/create_order_logic.go
package logic
import (
"context"
"go-gin/model/dao"
"go-gin/model/do"
"go-gin/typing"
)
type CreateOrderLogic struct{}
func NewCreateOrderLogic() *CreateOrderLogic {
return &CreateOrderLogic{}
}
func (l *CreateOrderLogic) Handle(ctx context.Context, req typing.CreateOrderReq) (*typing.CreateOrderResp, error) {
id, err := dao.Order.Ctx(ctx).
Data(do.Order{
ProductId: req.ProductId,
Quantity: req.Quantity,
Amount: req.Amount,
}).
InsertAndGetId()
if err != nil {
return nil, err
}
return &typing.CreateOrderResp{
OrderId: int(id),
Message: "success",
}, nil
}
// controller/order_controller.go
package controller
import (
"go-gin/internal/httpx"
"go-gin/logic"
)
type orderController struct{}
var OrderController = &orderController{}
func (c *orderController) Create(ctx *httpx.Context) (any, error) {
return httpx.Handle(ctx, logic.NewCreateOrderLogic())
}
// router/order.go
package router
import (
"go-gin/controller"
"go-gin/internal/httpx"
)
func RegisterOrderRoutes(r *httpx.RouterGroup) {
r.POST("/create", controller.OrderController.Create)
}
// router/init.go 中添加
RegisterOrderRoutes(route.Group("/order"))
// 查询单条
var user entity.User
err := dao.User.Ctx(ctx).Where(do.User{Id: 1}).One(&user)
// 判断是否存在
found, err := dao.User.Ctx(ctx).Where(do.User{Name: "test"}).Found(&user)
// 查询列表 + 分页
var users []entity.User
err := dao.User.Ctx(ctx).
Where(do.User{Status: 1}).
Where("age > ?", 18).
Order("id DESC").
Page(1, 10).
All(&users)
// 分页查询 + 总数
var users []entity.User
var total int64
err := dao.User.Ctx(ctx).
Where(do.User{Status: 1}).
Page(page, size).
ScanAndCount(&users, &total)
// 使用 Columns 常量避免硬编码
cols := dao.User.Columns()
err := dao.User.Ctx(ctx).
Fields(cols.Id, cols.Name).
Where(cols.Status+" = ?", 1).
All(&users)
// 插入
_, err := dao.User.Ctx(ctx).
Data(do.User{Name: "test", Status: 1}).
Insert()
// 更新
_, err := dao.User.Ctx(ctx).
Data(do.User{Status: 2}).
Where(do.User{Id: 1}).
Update()
// 删除
_, err := dao.User.Ctx(ctx).Where(do.User{Id: 1}).Delete()
// 聚合
count, _ := dao.Order.Ctx(ctx).Where(do.Order{UserId: 1}).Count()
sum, _ := dao.Order.Ctx(ctx).Where(do.Order{UserId: 1}).Sum("amount")
// 递增/递减
dao.User.Ctx(ctx).Where(do.User{Id: 1}).Increment("score", 10)
dao.User.Ctx(ctx).Where(do.User{Id: 1}).Decrement("balance", 100)
// 分块处理
dao.User.Ctx(ctx).Where(do.User{Status: 1}).Chunk(100, func(result []map[string]any, err error) bool {
// 处理每批数据
return true // 返回 false 停止
})
通过 .env 文件配置,使用 -f 参数指定路径:
go run cmd/api/main.go -f .env
go run cmd/api/main.go -f /path/to/config.env
| 类型 | 说明 | HTTP 状态码 | 用法 |
|---|---|---|---|
BizError | 业务错误 | 200 | errorx.New(code, msg) |
ServerError | 服务端错误 | 对应 HTTP 状态码 | errorx.NewServerError(status) |
DBError | 数据库错误 | 500 | 框架自动转换 |
RedisError | Redis 错误 | 500 | 框架自动转换 |
10000-19999: 框架保留错误码20000+: 业务自定义错误码errorx.ErrBadRequest // 400
errorx.ErrUnauthorized // 401
errorx.ErrForbidden // 403
errorx.ErrNoRoute // 404
errorx.ErrInternalServerError // 500
# API 服务
go run cmd/api/main.go -f .env
# 定时任务服务
go run cmd/cron/main.go -f .env
# 队列消费者服务
go run cmd/queue/main.go -f .env
# 数据库迁移
go run cmd/migrate/main.go -f .env
# 运行测试
go test ./test/...
go test ./test/ -run TestIsTrue
# 枚举方法生成 (扫描 const/enum/)
go run ./cmd/make/... make:enum
# DAO 代码生成 (entity/do/dao)
go run ./cmd/make/... make:dao -f .env
go run ./cmd/make/... make:dao -f .env -t user
# 迁移文件生成
go run ./cmd/make/... make:migration create_orders
logx.WithContext(ctx).Info("keyword", message)
logx.WithContext(ctx).Debug("keyword", message)
logx.WithContext(ctx).Error("keyword", message)
logx.WithContext(ctx).Warn("keyword", message)
| 类型 | 风格 | 示例 |
|---|---|---|
| 枚举常量 | SCREAMING_SNAKE_CASE | USER_STATUS_NORMAL |
| 枚举类型 | PascalCase | UserStatus |
| 结构体 | PascalCase | UserController, GetUsersLogic |
| 方法/函数 | PascalCase (导出) / camelCase (私有) | Handle(), parseInput() |
| 变量 | camelCase | userDao, reqData |
| 包名 | 小写单词 | httpx, errorx, logx |
| DAO 实例 | PascalCase | dao.User, dao.Order |
fmt.Println - 使用 logx.WithContext(ctx).env 或 config/_ = errdao.Xxx 单例dao.Xxx.Ctx(ctx) 链式调用do.Xxx 或 dao.Xxx.Columns()详细参考文档位于 docs/ 目录:
| 文档 | 说明 |
|---|---|
| model.md | Model 数据模型 (entity/do/dao 三层结构、代码生成) |
| controller.md | Controller 控制器层 (请求绑定、使用模式) |
| logic.md | Logic 业务逻辑层 (Handle 签名模式、命名规范) |
| dao.md | DAO 链式调用完整 API 参考 |
| const.md | 常量与枚举定义、业务错误码 |
| cmd.md | CMD 入口命令 (api, cron, queue, migrate, make) |
| cron.md | 定时任务 (结构体/函数方式、流式调度) |
| event.md | 事件系统 (事件定义、监听器、触发) |
| middleware.md | 中间件 (Before/After、Token 校验) |
| task.md | 异步队列任务 (Asynq/Redis) |
| rest.md | REST 第三方服务调用 |
| transformer.md | 数据转换层 (entity → typing) |