GoAdmin和gin-vue-admin不是Gin插件,而是基于Gin的独立项目框架,需克隆完整项目、执行migrate初始化数据库、严格按模块机制注册路由并启用backend权限模式才能正常运行。

别直接在现有 Gin 项目里“集成” GoAdmin 或 gin-vue-admin —— 它们不是插件,而是完整项目结构。强行 go get 后调用某个函数,大概率触发 panic: runtime error: invalid memory address or nil pointer dereference。
GoAdmin 不是 Gin 插件,是独立项目框架
GoAdmin 基于 Gin 构建,但不是通过 gin.Engine.Use() 就能挂载的中间件。它自带初始化流程(app.Initialize())、预设路由分组、Casbin 策略加载时机、CLI 工具和数据库迁移脚本。你无法跳过它的启动链路。
常见错误现象:
- 直接
go get github.com/go-admin-team/go-admin,然后在自己项目里写goadmin.NewAdmin(...)→ panic - 没跑
./go-admin migrate -c config/settings.yml→ 登录接口返回500 internal server error(因为sys_user表不存在) -
config/settings.yml中database.dsn写成root:pass@tcp(127.0.0.1:3306)/go_admin?charset=utf8mb4&loc=Local(漏掉&parseTime=True)→ 连接失败且无明确报错
新增业务路由必须走 GoAdmin 的模块注册机制
想加一个城市管理接口,不能像普通 Gin 那样直接写 r.POST("/city", handler)。GoAdmin 要求所有业务路由必须注册进 routerCheckRole 或 routerNoCheck 切片,并绑定到指定 Group(如 v1.Group("/admin")),否则 JWT 校验和 RBAC 权限检查不会生效。
典型错误写法:
func registerCityRouter(r *gin.RouterGroup) {
r.GET("/city", apis.City{}.GetList) // ❌ 缺少 authMiddleware.MiddlewareFunc(),接口裸奔
}
正确做法(参考 app/adm 模块):
- 在
app/adm/router.go中将路由注册进routerCheckRole切片 - 确保该路由属于
v1.Group("/admin")下的子路由 - 使用
authMiddleware.MiddlewareFunc()显式包裹,或依赖 GoAdmin 自动注入的中间件链
gin-vue-admin 的定时任务需手动启用并注意生命周期
gin-vue-admin 的 Cron 系统位于 server/utils/timer/timed_task.go,默认不自动启动。你写的清理任务(如 server/task/clearTable.go)不会运行,除非显式调用 timer.StartCron("default")。
容易踩的坑:
- 在
main.go初始化阶段未调用timer.StartCron()→ 定时任务静默不执行 - 用
AddTaskByFuncWithSecond注册任务时传入的spec(Cron 表达式)格式错误,比如写成"0 */5 * * *"(每 5 分钟)却漏了秒字段 → 实际被解释为 “每小时第 0 分钟”,行为不符预期 - 服务重启后未持久化任务状态 → 依赖内存存储的任务会丢失,需配合数据库记录任务执行历史
RBAC 权限控制依赖 Casbin 策略加载顺序
Gin-Admin 和 gin-vue-admin 都用 Casbin 做权限校验,但策略加载必须在路由注册之后、服务启动之前完成。如果在 init() 阶段就初始化 Casbin,而数据库还没连上或 casbin_rule 表为空,会导致所有带权限校验的接口统一返回 403 Forbidden。
关键点:
- Casbin adapter 必须使用已连接的 DB 实例(如
gormadapter.NewAdapterByDBUseTableName(db, "casbin_rule")) -
enforcer.LoadPolicy()应放在 DB 初始化成功、migration 执行完毕之后 - 动态菜单数据通常从
sys_menu表读取,但前端展示权限还受casbin_rule中p(policy)和g(group)规则双重约束 —— 缺一不可
最常被忽略的是:菜单能显示 ≠ 接口可访问。前者查 sys_menu,后者查 casbin_rule,两者完全解耦,必须分别配置。











