| 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" |
go-gin OpenCode Skill
基于 Gin 的企业级 Go Web 应用框架,封装了自定义 HTTP 引擎、GoFrame 风格的 DAO 链式调用、代码生成工具、定时任务、异步队列、事件系统等功能模块,提供清晰的分层架构和开发规范。
Quick Start
git clone git@github.com:fanqingxuan/go-gin.git
cd go-gin
go mod tidy
cp .env.example .env
go run cmd/migrate/main.go -f .env
go run cmd/api/main.go -f .env
Overview
技术栈
| 组件 | 技术选型 |
|---|
| 语言 | 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/
- router/: 路由定义,按模块分文件 (user.go, login.go 等)
- controller/: 控制器薄层,返回
(any, error),框架自动处理响应格式
- logic/: 业务逻辑层,Command 模式,每个操作一个 Logic 结构体
- model/: 数据层,三个子包:
model/entity/: 表结构 (GORM 模型,强类型,自动生成)
model/do/: Data Object (any 类型,用于 Where/Data 条件)
model/dao/: Data Access Object (单例实例 + Model 链式 API)
- typing/: 请求/响应类型定义
- transformer/: 数据转换层
- middleware/: HTTP 中间件
- internal/: 框架内部包 (httpx, errorx, cronx, eventbus 等)
目录结构
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/ # 工具函数
Features
1. 自定义 HTTP 引擎 (httpx)
框架封装了 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)
2. GoFrame 风格 DAO 链式调用
基于 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
3. 代码生成工具 (make)
go run ./cmd/make/... make:enum
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
4. 枚举类型系统 (etype)
类型安全的枚举,支持数据库扫描和 JSON 序列化:
type UserStatus struct { etype.BaseEnum }
var (
USER_STATUS_NORMAL = etype.NewEnum[UserStatus](1, "正常")
USER_STATUS_DISABLED = etype.NewEnum[UserStatus](2, "禁用")
)
status.Code()
status.Desc()
status.Equal(USER_STATUS_NORMAL)
5. 事件系统 (eventbus)
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)
6. 异步队列 (基于 Asynq/Redis)
task.DispatchNow(task.NewSampleTask(data))
task.NewSampleTask(data).Dispatch(5 * time.Minute)
task.NewSampleTask(data).DispatchIf(condition)
7. 定时任务 (cronx)
支持 cron 表达式和 Laravel 风格的流式调度:
cronx.AddJob("@every 3s", &SampleJob{})
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, EveryThirtySeconds
- 分钟级:
EveryMinute, EveryTwoMinutes, EveryThreeMinutes, EveryFiveMinutes, EveryTenMinutes, EveryFifteenMinutes, EveryThirtyMinutes
- 小时级:
Hourly, HourlyAt(minute), EveryTwoHours, EveryThreeHours, EveryFourHours, EverySixHours
- 天级:
Daily, DailyAt("HH:mm"), TwiceDaily(h1, h2), TwiceDailyAt(h1, h2, min)
- 周级:
Weekly, WeeklyOn(day, "HH:mm"), Weekdays, Weekends, Mondays~Sundays
- 月级:
Monthly, MonthlyOn(day, "HH:mm"), TwiceMonthly(d1, d2, "HH:mm"), LastDayOfMonth("HH:mm")
- 其他:
Quarterly, Yearly, Cron("expression")
8. Excel/CSV 导出 (excelx)
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{...})
9. HTTP 客户端 (httpc)
链式调用的 HTTP 客户端,支持自动响应解析:
httpc.NewRequest().
SetContext(ctx).
SetBody(data).
SetResult(&response).
POST(url).
SendAndParse()
10. 通用类型 (g 包)
GoFrame 风格的类型别名和通用变量:
g.Map
g.Slice
g.SliceStr
g.Var
g.NewVar(val).Int()
g.NewVar(val).String()
g.NewVar(val).Map()
Usage
添加新功能的完整流程
1. 定义请求/响应类型 (typing/)
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"`
}
2. 创建 Logic (logic/)
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
}
3. 创建 Controller (controller/)
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())
}
4. 注册路由 (router/)
package router
import (
"go-gin/controller"
"go-gin/internal/httpx"
)
func RegisterOrderRoutes(r *httpx.RouterGroup) {
r.POST("/create", controller.OrderController.Create)
}
RegisterOrderRoutes(route.Group("/order"))
DAO 链式调用示例
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)
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
})
Configuration
通过 .env 文件配置,使用 -f 参数指定路径:
go run cmd/api/main.go -f .env
go run cmd/api/main.go -f /path/to/config.env
Error Handling
错误类型
| 类型 | 说明 | HTTP 状态码 | 用法 |
|---|
BizError | 业务错误 | 200 | errorx.New(code, msg) |
ServerError | 服务端错误 | 对应 HTTP 状态码 | errorx.NewServerError(status) |
DBError | 数据库错误 | 500 | 框架自动转换 |
RedisError | Redis 错误 | 500 | 框架自动转换 |
错误码规范
10000-19999: 框架保留错误码
20000+: 业务自定义错误码
预定义错误
errorx.ErrBadRequest
errorx.ErrUnauthorized
errorx.ErrForbidden
errorx.ErrNoRoute
errorx.ErrInternalServerError
Development
运行命令
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
代码生成
go run ./cmd/make/... make:enum
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)
Code Style (Naming Conventions)
| 类型 | 风格 | 示例 |
|---|
| 枚举常量 | 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/
- 禁止忽略错误 - 必须处理或显式
_ = err
- 禁止在 Controller 中写业务逻辑 - 放入 Logic 层
- 禁止在 Logic 中实例化 DAO - 使用
dao.Xxx 单例
- 禁止在 Controller/Logic 中直接操作 db - 使用
dao.Xxx.Ctx(ctx) 链式调用
- 禁止在 Controller/Logic 中硬编码表字段名 - 使用
do.Xxx 或 dao.Xxx.Columns()
Reference Documentation
详细参考文档位于 docs/ 目录:
Resources