安装 GoAdmin 需要以下步骤:
首先需要安装 Go 语言,可以从官网 https://golang.org/dl/ 下载并安装。安装完成后,需要设置 GOPATH 环境变量。
可以使用如下命令来安装 GoAdmin:
go get -u github.com/GoAdminGroup/go-admin
进入项目目录,并执行如下命令来安装依赖包:
cd $GOPATH/src/github.com/GoAdminGroup/go-admin/demo && go mod tidy
在项目目录中执行如下命令启动示例工程:
go run main.go
然后访问 http://localhost:9033/admin 即可进入 GoAdmin 后台管理系统。
二,架构分析和各模块精讲
GoAdmin 后台管理系统的架构可以分为四个层次:
前端页面负责展示用户界面和交互逻辑,GoAdmin 使用了 Bootstrap 和 AdminLTE 作为前端框架,同时支持自定义主题和模板。
路由控制器负责接收用户请求并进行路由匹配,然后将请求转发给对应的处理器进行处理。GoAdmin 使用了 Gin 框架作为路由控制器,同时支持自定义中间件和拦截器。
处理器负责具体业务逻辑的实现,包括权限认证、数据查询、数据修改等操作。GoAdmin 内置了多个处理器,例如表单构建器、列表构建器、文件上传处理等,并支持自定义扩展。
数据库访问层负责与数据库进行交互,并提供基本的 CRUD 操作。GoAdmin 支持多种数据库引擎,例如 MySQL、PostgreSQL 等,并使用 GORM 作为 ORM 工具。
以上是 GoAdmin 后台管理系统的四个层次及其核心组件。在这些组件的基础上,GoAdmin 提供了丰富的插件和扩展机制,在满足基本需求的同时也能够方便地扩展功能。
三,cobra命令行实战
在 GoAdmin 后台管理系统中,使用了 Cobra 框架作为命令行工具的实现方式。Cobra 可以帮助我们快速地构建出一个功能完整、易于扩展的命令行应用程序。
下面是一个简单的示例,演示如何使用 Cobra 实现一个简单的命令行工具:
可以使用以下命令安装 Cobra:
go get -u github.com/spf13/cobra/cobra
创建一个新项目,并初始化一个 Cobra 应用程序:
mkdir myapp && cd myapp
cobra init --pkg-name=myapp
在 cmd/root.go
文件中添加一个子命令:
var helloCmd = &cobra.Command{
Use: "hello",
Short: "Say hello to the world",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Hello, world!")
},
}
func init() {
rootCmd.AddCommand(helloCmd)
}
运行以下命令即可执行 hello
子命令:
go run main.go hello
以上就是使用 Cobra 实现一个简单的命令行工具的流程。在 GoAdmin 中,我们可以根据需要定义更多复杂的子命令,并通过参数传递来实现不同的功能。
四,casbin权限管理
在 GoAdmin 后台管理系统中,使用了 Casbin 作为权限管理框架,可以帮助我们快速地实现细粒度的权限控制。
下面是一个简单的示例,演示如何使用 Casbin 实现 RBAC 权限控制:
可以使用以下命令安装 Casbin:
go get github.com/casbin/casbin/v2
在项目目录下创建 rbac_model.conf
文件,并添加以下内容:
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
在代码中加载策略文件并创建 Enforcer 对象:
import (
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
"github.com/casbin/casbin/v2/persist/file-adapter"
)
var e *casbin.Enforcer
func init() {
m := model.NewModel()
a := fileadapter.NewAdapter("path/to/rbac_policy.csv")
e, _ = casbin.NewEnforcer("path/to/rbac_model.conf", m, a)
}
// 检查权限
func checkPermission(sub string, obj string, act string) bool {
return e.Enforce(sub, obj, act)
}
使用以下代码为用户添加角色:
e.AddRoleForUser("alice", "admin")
使用以下代码检查用户是否有某个操作的权限:
checkPermission("alice", "data1", "read") // 返回 true 或 false
以上就是使用 Casbin 实现 RBAC 权限控制的流程。在 GoAdmin 中,我们可以根据需要定义更多复杂的策略和角色,并通过 Enforcer 对象来实现细粒度的权限控制。
五,RBAC实践、多租户实践
GoAdmin 是一个基于 Go 语言的后台管理系统,它支持 RBAC 权限控制和多租户功能。
下面分别介绍如何在 GoAdmin 中实现 RBAC 和多租户功能:
在 GoAdmin 中实现 RBAC 权限控制可以使用 Casbin 框架。Casbin 可以帮助我们快速地实现细粒度的权限控制。
以下是简单示例:
// main.go
package main
import (
"github.com/casbin/casbin/v2"
"github.com/gin-gonic/gin"
)
func main() {
// 加载策略文件
e, err := casbin.NewEnforcer("path/to/rbac_model.conf", "path/to/rbac_policy.csv")
if err != nil {
panic(err)
}
r := gin.Default()
// 鉴权中间件
r.Use(func(c *gin.Context) {
sub := c.GetString("sub") // 用户 ID
obj := c.GetString("obj") // 资源 ID
act := c.GetString("act") // 操作类型(GET、POST 等)
ok, _ := e.Enforce(sub, obj, act)
if !ok {
c.AbortWithStatus(403)
return
}
c.Next()
})
r.GET("/api/v1/users/:id", func(c *gin.Context) {
id := c.Param("id")
// ...
c.JSON(200, gin.H{
"data": user,
})
})
r.POST("/api/v1/users", func(c *gin.Context) {
// ...
c.JSON(200, gin.H{
"data": user,
})
})
r.Run(":8080")
}
以上示例中,我们创建了一个 Gin 应用,并使用 Casbin 实现了鉴权中间件。在路由处理函数中,我们可以获取到用户 ID、资源 ID 和操作类型等信息,并使用 Enforce
方法检查权限。
在 GoAdmin 中实现多租户功能可以通过 URL 参数或者 HTTP 头部来区分不同的租户。
以下是简单示例:
// main.go
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// 多租户中间件
r.Use(func(c *gin.Context) {
tenantID := c.Query("tenant_id") // 从 URL 参数获取租户 ID
if tenantID == "" {
tenantID = c.GetHeader("X-Tenant-ID") // 从 HTTP 头部获取租户 ID
}
if tenantID == "" {
c.AbortWithStatus(400)
return
}
c.Set("tenant_id", tenantID) // 将租户 ID 存储到上下文中
c.Next()
})
r.GET("/api/v1/users/:id", func(c *gin.Context) {
id := c.Param("id")
tenantID := c.GetString("tenant_id") // 获取租户 ID
// ...
c.JSON(200, gin.H{
"data": user,
})
})
r.POST("/api/v1/users", func(c *gin.Context) {
tenantID := c.GetString("tenant_id") // 获取租户 ID
// ...
c.JSON(200, gin.H{
"data": user,
})
})
r.Run(":8080")
}
以上示例中,我们创建了一个 Gin 应用,并实现了多租户中间件。在路由处理函数中,我们可以从上下文中获取租户 ID,并根据不同的租户来进行处理。
六,添加新应用
在 GoAdmin 中添加新应用需要进行以下几个步骤:
可以使用 goadmincli
工具创建一个新的 GoAdmin 应用,命令如下:
goadmincli new your-app-name
其中 your-app-name
是你要创建的应用名称。
在创建好的新应用中,我们需要添加相应的路由。可以参考已有的示例程序,在 main.go
文件中添加对应的路由。
例如,我们要添加一个名为 myapp
的新应用,并在该应用中添加一个名为 users
的管理模块。则可以按照以下方式添加路由:
// main.go
package main
import (
"github.com/gin-gonic/gin"
"github.com/gogf/gf/util/gconv"
"github.com/your-username/your-app-name/app/dashboard"
"github.com/your-username/your-app-name/app/users"
_ "github.com/your-username/your-app-name/boot/config"
_ "github.com/your-username/your-app-name/boot/database"
_ "github.com/your-username/your-app-name/boot/router"
_ "github.com/your-username/your-app-name/boot/session"
// 导入 myapp 模块
_ "github.com/your-username/your-app-name/app/myapp"
)
func main() {
r := gin.Default()
// 注册管理模块
dashboard.Register(r)
// 注册 users 模块
users.Register(r)
// 注册 myapp 模块(假设 myapp 中有一个名为 foo 的控制器)
r.GET("/myapp/foo", func(c *gin.Context) {
userID := gconv.Int(c.Query("user_id"))
// ...
c.JSON(200, gin.H{
"data": user,
})
})
r.Run(":8080")
}
在以上示例中,我们首先导入了 myapp
模块,并注册了 dashboard
和 users
两个管理模块。然后,我们在路由中添加了一个名为 /myapp/foo
的新路由。
最后,在 GoAdmin 后台管理系统中添加对应的菜单项即可。
七,添加新模块
在 GoAdmin 中添加新模块需要进行以下几个步骤:
可以使用 goadmincli
工具创建一个新的 GoAdmin 模块,命令如下:
goadmincli module your-module-name
其中 your-module-name
是你要创建的模块名称。
在创建好的新模块中,我们需要配置相应的路由和控制器。可以参考已有的示例程序,在 routes.go
文件中添加对应的路由配置,并在 controller
目录下添加对应的控制器。
例如,我们要添加一个名为 users
的管理模块,则可以按照以下方式配置路由和控制器:
// routes.go
package users
import (
"github.com/gin-gonic/gin"
"github.com/your-username/your-app-name/app/users/controller"
)
func Register(r *gin.Engine) {
// 注册用户管理模块路由(假设该模块包含列表、详情和编辑三个页面)
r.GET("/admin/users", controller.List)
r.GET("/admin/users/detail/:id", controller.Detail)
r.GET("/admin/users/edit/:id", controller.Edit)
}
// controller/user.go
package controller
import (
"github.com/gin-gonic/gin"
)
// 用户列表页
func List(c *gin.Context) {
// ...
}
// 用户详情页
func Detail(c *gin.Context) {
// ...
}
// 编辑用户信息页
func Edit(c *gin.Context) {
// ...
}
在以上示例中,我们首先在 routes.go
文件中注册了三个路由(列表、详情和编辑页面),并指定相应的控制器方法。然后,在 controller
目录下添加了对应的控制器代码。
最后,在 GoAdmin 后台管理系统中添加对应的菜单项即可。
八,自动生成代码
GoAdmin 后台管理系统可以通过 goadmincli
工具自动生成代码,包括模块、控制器和页面等。
首先,使用以下命令创建一个新的 GoAdmin 模块:
goadmincli module your-module-name
其中 your-module-name
是你要创建的模块名称。执行该命令后,会在当前目录下生成一个名为 your-module-name
的文件夹,并在其中创建了一些默认的文件和目录结构。
接下来,进入刚刚生成的模块目录,在终端中运行以下命令即可自动生成相应的代码:
goadmincli generate -c your-controller-name
其中 -c
参数表示指定要生成控制器代码。your-controller-name
则是你要生成的控制器名称。例如,如果你想生成一个名为 user
的控制器,则可以运行以下命令:
goadmincli generate -c user
执行该命令后,工具会自动在相应的目录下生成与控制器相关的代码文件(包括路由配置、列表页、编辑页等)。
需要注意的是,默认情况下,生成的代码基于 GORM 框架实现数据库操作。如果你使用了其他 ORM 框架或者直接操作数据库,则需要手动修改相应代码。
九,配置权限
GoAdmin 后台管理系统提供了丰富的权限控制功能,可以通过以下步骤进行配置:
首先,需要定义不同的角色。在 GoAdmin 中,每个用户都必须属于一个或多个角色。可以使用如下代码来定义角色:
// 定义管理员和普通用户两种角色
roleMap := map[string]string{
"admin": "管理员",
"user": "普通用户",
}
// 注册所有角色
for k, v := range roleMap {
err := eng.AddRole(goadmin.Role{
Name: k,
DisplayName: v,
})
if err != nil {
log.Fatalf("add role error: %v", err)
}
}
定义好角色后,需要为每个角色配置相应的权限。可以通过以下方式进行配置:
// 配置管理员角色拥有全部权限
_, _ = eng.Role("admin").AllowAll()
也可以单独为某个页面或操作设置权限:
// 为列表页设置只读权限(普通用户只能查看数据,无法编辑)
_, _ = eng.Permission().Update(goadmin.Permission{
ID: "list",
Name: "列表页",
Slug: "/admin/info/user/list",
HTTPMethod: []string{"GET"},
})
_, _ = eng.Role("user").AddPermissionID("list")
最后,在登录时需要将当前用户与相应的角色绑定。可以通过如下代码实现:
// 获取当前用户信息
user, err := eng.Auth(ctx)
if err != nil {
// 未登录或者登录超时,需要跳转到登录页面
return echo.Redirect(http.StatusFound, "/admin/login")
}
// 获取当前用户所属的角色列表
roles, _ := user.GetRoles()
// 将当前用户与相应的角色绑定
_, _ = eng.User(user.ID).WithRoles(roles).Save()
这样,当用户访问某个需要权限验证的页面时,GoAdmin 会根据用户所属的角色进行权限验证,并返回相应的错误信息。
十,swagger api
如果您使用 GoAdmin 框架开发了后台管理系统,并且希望通过 Swagger 提供 API 文档和测试工具,可以按照以下步骤进行配置:
在 Go 项目中,需要安装 swaggo/swag
和 swaggo/gin-swagger
两个包来支持 Swagger。可以使用如下命令安装:
go get -u github.com/swaggo/swag/cmd/swag
go get -u github.com/swaggo/gin-swagger
在代码中添加 Swagger 注释,用于自动生成 API 文档。例如:
// @Summary 获取用户列表
// @Description 获取用户列表
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param page query int false "页码"
// @Param limit query int false "每页数量"
// @Success 200 {object} model.UserList
// @Router /admin/users [get]
func GetUserList(ctx *gin.Context) {
// ...
}
执行以下命令,在项目根目录下生成 docs
目录和相应的文档文件:
swag init --generalInfo main.go --output docs --parseDependency --parseInternal --exclude third_party,tests,migrations
在路由设置中添加以下代码,启用 Swagger UI:
import (
"github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
)
func setupRouter() *gin.Engine {
r := gin.Default()
// ...
// 注册 Swagger API 文档路由
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
return r
}
现在,访问 http://localhost:8080/swagger/index.html
可以看到自动生成的 API 文档和测试工具了。