بنقرة واحدة
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) |