上一节讲解了[golang gin框架] 43.Gin商城项目-微服务实战之后台Rbac微服务之管理员的增删改查以及管理员和角色关联,这里讲解权限管理Rbac微服务权限的增删改查微服务
一.实现后台权限管理Rbac之权限增删改查微服务服务端功能
1.创建Access模型
要实现权限的增删改查,就需要创建对应的模型,故在server/rbac/models下创建Access.go模型文件,参考[golang gin框架] 14.Gin 商城项目-RBAC管理代码如下:
package models
//权限模型
type Access struct {
Id int64
ModuleName string //模块名称
ActionName string //操作名称
Type int64 //节点类型 : 1、表示模块 2、表示菜单 3、操作
Url string //路由跳转地址
ModuleId int64 //此module_id和当前模型的id关联 module_id= 0 表示模块
Sort int64
Description string
Status int64
AddTime int64
AccessItem []Access `gorm:"foreignKey:ModuleId;references:Id"` // 表的自关联,获取该数据的子分类
Checked bool `gorm:"-"` // 用户是否有该权, 忽略本字段,给struct加一个自定义属性,和数据库没有关系
}
func (Access) TableName() string {
return "access"
}
2.在proto文件夹下创建rbacAccess.proto
参考[golang gin框架] 14.Gin 商城项目-RBAC管理,创建rbacAccess.proto.生成权限相关方法,具体代码如下:
syntax = "proto3";
package access;
option go_package = "./proto/rbacAccess";
//权限管理
service RbacAccess {
//获取权限rpc方法: 请求参数AccessGetRequest, 响应参数AccessGetResponse
rpc AccessGet(AccessGetRequest) returns (AccessGetResponse) {}
//增加权限rpc方法: 请求参数AccessAddRequest, 响应参数AccessAddResponse
rpc AccessAdd(AccessAddRequest) returns (AccessAddResponse) {}
//编辑权限rpc方法: 请求参数AccessEditRequest, 响应参数AccessEditResponse
rpc AccessEdit(AccessEditRequest) returns (AccessEditResponse) {}
//删除权限rpc方法: 请求参数AccessDeleteRequest, 响应参数AccessDeleteResponse
rpc AccessDelete(AccessDeleteRequest) returns (AccessDeleteResponse) {}
}
//权限相关model: 参考models/access.go
message AccessModel{
int64 id=1;
string moduleName =2;
string actionName=3;
int64 type=4;
string url=5;
int64 moduleId=6;
int64 sort =7;
string description=8;
int64 status=9;
int64 addTime=10;
repeated AccessModel accessItem=11; //权限的自关联(切片类型)
}
//获取权限请求参数
message AccessGetRequest{
//权限id, 也可以不传,不传的话就是获取所有权限列表
int64 id =1;
}
//获取权限响应参数
message AccessGetResponse{
//权限model切片
repeated AccessModel AccessList=1;
}
//增加权限请求参数
message AccessAddRequest{
string moduleName =1;
string actionName=2;
int64 type=3;
string url=4;
int64 moduleId=5;
int64 sort =6;
string description=7;
int64 status=8;
int64 addTime=9;
}
//增加权限响应参数
message AccessAddResponse{
//是否增加成功
bool success=1;
//返回状态说明
string message=2;
}
//编辑权限请求参数
message AccessEditRequest{
int64 id=1;
string moduleName =2;
string actionName=3;
int64 type=4;
string url=5;
int64 moduleId=6;
int64 sort =7;
string description=8;
int64 status=9;
int64 addTime=10;
}
//编辑权限响应参数
message AccessEditResponse{
//是否编辑成功
bool success=1;
//返回状态说明
string message=2;
}
//删除权限请求参数
message AccessDeleteRequest{
//权限id
int64 id=1;
}
//删除权限响应参数
message AccessDeleteResponse{
//是否删除成功
bool success=1;
//返回状态说明
string message=2;
}
3.生成access相关pb.go,pb.micro.go文件
在server/rbac下运行命令protoc --proto_path=. --micro_out=. --go_out=:. proto/rbacAccess.proto即可
4.在handler文件夹下创建rbacAccess.go文件,实现proto中的service方法
参考[golang gin框架] 14.Gin 商城项目-RBAC管理_权限的增删改查方法代码,把对应的方法实现代码拷贝到rbacAccess.go中,并完善修改一下,变成微服务的代码,具体rbacAccess.go代码如下:
package handler
import (
"context"
"strconv"
"rbac/models"
pb "rbac/proto/rbacAccess"
)
type RbacAccess struct{}
//获取权限
func (e *RbacAccess) AccessGet(ctx context.Context, req *pb.AccessGetRequest, res *pb.AccessGetResponse) error {
accessList := []models.Access{}
where := "1=1"
if req.Id > 0 { // 当传入权限id时,获取对应的权限数据, 当没有传入权限id时,获取权限列表数据
where += " AND id=" + strconv.Itoa(int(req.Id))
} else {
where += " AND module_id = 0"
}
//获取权限数据以及对应的关联数据
models.DB.Where(where).Preload("AccessItem").Find(&accessList)
//处理数据
var tempList []*pb.AccessModel
for _, v := range accessList {
//处理自关联的子数据
var tempItemList []*pb.AccessModel
for _, k := range v.AccessItem {
tempItemList = append(tempItemList, &pb.AccessModel{
Id: int64(k.Id),
ModuleName: k.ModuleName,
ActionName: k.ActionName,
Type: int64(k.Type),
Url: k.Url,
ModuleId: int64(k.ModuleId),
Sort: int64(k.Sort),
Description: k.Description,
Status: int64(k.Status),
AddTime: int64(k.AddTime),
})
}
//处理数据
tempList = append(tempList, &pb.AccessModel{
Id: int64(v.Id),
ModuleName: v.ModuleName,
ActionName: v.ActionName,
Type: int64(v.Type),
Url: v.Url,
ModuleId: int64(v.ModuleId),
Sort: int64(v.Sort),
Description: v.Description,
Status: int64(v.Status),
AddTime: int64(v.AddTime),
AccessItem: tempItemList, //关联的子数据
})
}
res.AccessList = tempList
return nil
}
//增加权限
func (e *RbacAccess) AccessAdd(ctx context.Context, req *pb.AccessAddRequest, res *pb.AccessAddResponse) error {
access := models.Access{
ModuleName: req.ModuleName,
Type: req.Type,
ActionName: req.ActionName,
Url: req.Url,
ModuleId: req.ModuleId,
Sort: req.Sort,
Description: req.Description,
Status: req.Status,
}
err := models.DB.Create(&access).Error
if err != nil {
res.Success = false
res.Message = "增加数据失败"
} else {
res.Success = true
res.Message = "增加数据成功"
}
return err
}
//修改权限
func (e *RbacAccess) AccessEdit(ctx context.Context, req *pb.AccessEditRequest, res *pb.AccessEditResponse) error {
access := models.Access{Id: req.Id}
models.DB.Find(&access)
access.ModuleName = req.ModuleName
access.Type = req.Type
access.ActionName = req.ActionName
access.Url = req.Url
access.ModuleId = req.ModuleId
access.Sort = req.Sort
access.Description = req.Description
access.Status = req.Status
err := models.DB.Save(&access).Error
if err != nil {
res.Success = false
res.Message = "修改数据失败"
} else {
res.Success = true
res.Message = "修改数据成功"
}
return err
}
//删除权限
func (e *RbacAccess) AccessDelete(ctx context.Context, req *pb.AccessDeleteRequest, res *pb.AccessDeleteResponse) error {
access := models.Access{Id: req.Id}
models.DB.Find(&access)
if access.ModuleId == 0 { //顶级模块
accessList := []models.Access{}
models.DB.Where("module_id = ?", access.Id).Find(&accessList)
if len(accessList) > 0 {
res.Success = false
res.Message = "当前模块下面有菜单或者操作,请删除菜单或者操作以后再来删除这个数据"
} else {
models.DB.Delete(&access)
res.Success = true
res.Message = "删除数据成功"
}
} else { //操作 或者菜单
models.DB.Delete(&access)
res.Success = true
res.Message = "删除数据成功"
}
return nil
}
5.在main.go文件中注册权限微服务
只需在import中引入pbManager "rbac/proto/rbacAccess"以及在main()中加入以下代码即可:
// Register handler:注册权限微服务
if err := pbAccess.RegisterRbacAccessHandler(srv.Server(), new(handler.RbacAccess)); err != nil {
logger.Fatal(err)
}
具体代码如下:
package main
import (
"rbac/handler"
"rbac/models"
pb "rbac/proto/rbacLogin"
pbRole "rbac/proto/rbacRole"
pbManager "rbac/proto/rbacManager"
pbAccess "rbac/proto/rbacAccess"
"go-micro.dev/v4"
"go-micro.dev/v4/logger"
"github.com/go-micro/plugins/v4/registry/consul"
)
var (
service = "rbac"
version = "latest"
)
func main() {
//集成consul
consulReg := consul.NewRegistry()
// Create service
//读取.ini里面的配置
addr := models.Config.Section("consul").Key("addr").String()
srv := micro.NewService(
micro.Address(addr), //指定微服务的ip: 选择注册服务器地址,也可以不配置,默认为本机,也可以选择consul集群中的client
micro.Name(service),
micro.Version(version),
//注册consul
micro.Registry(consulReg),
)
srv.Init(
micro.Name(service),
micro.Version(version),
)
// Register handler:注册登录微服务
if err := pb.RegisterRbacLoginHandler(srv.Server(), new(handler.RbacLogin)); err != nil {
logger.Fatal(err)
}
// Register handler:注册角色微服务
if err := pbRole.RegisterRbacRoleHandler(srv.Server(), new(handler.RbacRole)); err != nil {
logger.Fatal(err)
}
// Register handler:注册管理员微服务
if err := pbManager.RegisterRbacManagerHandler(srv.Server(), new(handler.RbacManager)); err != nil {
logger.Fatal(err)
}
// Register handler:注册权限微服务
if err := pbAccess.RegisterRbacAccessHandler(srv.Server(), new(handler.RbacAccess)); err != nil {
logger.Fatal(err)
}
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}
二.实现后台权限管理Rbac权限客户端微服务功能
参考[golang gin框架] 43.Gin商城项目-微服务实战之后台Rbac微服务之管理员的增删改查以及管理员和角色关联
1.复制server/rbac/proto文件夹下rbacAccess.go以及rbacAccess文件夹到client项目中的proto文件夹下
2. 调用Rbac权限增删改查微服务
在controllers/admin/access.go的Index(),Add(),DoAdd(),Edit(),DoEdit(),Delete()方法中调用Rbac权限增删改查微服务功能,这里需要在import中引入rbacAccess微服务相关包,代码如下:
import (
pbAccess "goshop/proto/rbacAccess"
)
原controllers/admin/access.go代码如下:也可参考[golang gin框架] 14.Gin 商城项目-RBAC管理
package admin
import (
"github.com/gin-gonic/gin"
"goshop/models"
"net/http"
"strings"
)
type AccessController struct {
BaseController
}
func (con AccessController) Index(c *gin.Context) {
//获取权限列表
accessList := []models.Access{}
models.DB.Where("module_id = ?", 0).Preload("AccessItem").Find(&accessList)
c.HTML(http.StatusOK, "admin/access/index.html", gin.H{
"accessList": accessList,
})
}
func (con AccessController) Add(c *gin.Context) {
//获取顶级模块
accessList := []models.Access{}
models.DB.Where("module_id = ?", 0).Find(&accessList)
c.HTML(http.StatusOK, "admin/access/add.html", gin.H{
"accessList": accessList,
})
}
func (con AccessController) DoAdd(c *gin.Context) {
//获取表单数据
moduleName := strings.Trim(c.PostForm("module_name"), " ")
actionName := strings.Trim(c.PostForm("action_name"), " ")
accessType, err1 := models.Int(c.PostForm("type"))
url := c.PostForm("url")
moduleId, err2 := models.Int(c.PostForm("module_id"))
sort, err3 := models.Int(c.PostForm("sort"))
status, err4 := models.Int(c.PostForm("status"))
description := strings.Trim(c.PostForm("description"), " ")
//判断err
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
con.Error(c, "传入参数错误", "/admin/access/add")
return
}
//判断moduleName
if moduleName == "" {
con.Error(c, "模块名称不能为空", "/admin/access/add")
return
}
//实例化access
access := models.Access{
ModuleName: moduleName,
ActionName: actionName,
Type: accessType,
Url: url,
ModuleId: moduleId,
Sort: sort,
Status: status,
Description: description,
}
err5 := models.DB.Create(&access).Error
if err5 != nil {
con.Error(c, "添加权限失败", "/admin/access/add")
return
}
con.Success(c, "添加权限成功", "/admin/access")
}
//编辑
func (con AccessController) Edit(c *gin.Context) {
//获取id
id, err := models.Int(c.Query("id"))
if err != nil {
con.Error(c, "传入数据错误", "/admin/access")
return
}
access := models.Access{Id: id}
models.DB.Find(&access)
//获取顶级模块
accessList := []models.Access{}
models.DB.Where("module_id = ?", 0).Find(&accessList)
c.HTML(http.StatusOK, "admin/access/edit.html", gin.H{
"access": access,
"accessList": accessList,
})
}
//编辑:提交
func (con AccessController) DoEdit(c *gin.Context) {
//获取提交的表单数据
id, err := models.Int(c.PostForm("id"))
if err != nil {
con.Error(c, "传入数据错误", "/admin/access/edit?id"+models.String(id))
return
}
//获取表单数据
moduleName := strings.Trim(c.PostForm("module_name"), " ")
actionName := strings.Trim(c.PostForm("action_name"), " ")
accessType, err1 := models.Int(c.PostForm("type"))
url := c.PostForm("url")
moduleId, err2 := models.Int(c.PostForm("module_id"))
sort, err3 := models.Int(c.PostForm("sort"))
status, err4 := models.Int(c.PostForm("status"))
description := strings.Trim(c.PostForm("description"), " ")
//判断err
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
con.Error(c, "传入数据错误", "/admin/access/edit?id"+models.String(id))
return
}
//判断moduleName
if moduleName == "" {
con.Error(c, "模块名称不能为空", "/admin/access/edit?id"+models.String(id))
return
}
//获取要修改的数据
access := models.Access{Id: id}
models.DB.Find(&access)
access.ModuleName = moduleName
access.ActionName = actionName
access.Type = accessType
access.Url = url
access.ModuleId = moduleId
access.Sort = sort
access.Status = status
access.Description = description
//保存
err5 := models.DB.Save(&access).Error
if err5 != nil {
con.Error(c, "编辑权限失败", "/admin/access/edit?id"+models.String(id))
return
}
con.Success(c, "编辑权限成功", "/admin/access")
}
//删除
func (con AccessController) Delete(c *gin.Context) {
//获取提交的表单数据
id, err := models.Int(c.Query("id"))
if err != nil {
con.Error(c, "传入数据错误", "/admin/access")
return
}
//获取要删除的数据
access := models.Access{Id: id}
models.DB.Find(&access)
if access.ModuleId == 0 { // 顶级模块
accessList := []models.Access{}
models.DB.Where("module_id = ? ", access.Id).Find(&accessList)
if len(accessList) > 0 {
con.Error(c, "当前模块下子菜单,请先删除子菜单后再来删除这个数据", "/admin/access")
return
}
}
// 操作 或者 菜单, 或者顶级模块下面没有子菜单, 可以直接删除
err = models.DB.Delete(&access).Error
if err != nil {
con.Error(c, "删除数据失败", "/admin/access")
return
}
con.Success(c, "删除数据成功", "/admin/access")
}
(1). Index()方法调用微服务代码
原方法:
func (con AccessController) Index(c *gin.Context) {
//获取权限列表
accessList := []models.Access{}
models.DB.Where("module_id = ?", 0).Preload("AccessItem").Find(&accessList)
c.HTML(http.StatusOK, "admin/access/index.html", gin.H{
"accessList": accessList,
})
}
完善后的方法:
func (con AccessController) Index(c *gin.Context) {
//获取权限列表
rbacClient := pbAccess.NewRbacAccessService("rbac", models.RbacClient)
res, _ := rbacClient.AccessGet(context.Background(), &pbAccess.AccessGetRequest{})
c.HTML(http.StatusOK, "admin/access/index.html", gin.H{
"accessList": res.AccessList,
})
}
(2). Add()方法调用微服务代码
原方法:
func (con AccessController) Add(c *gin.Context) {
//获取顶级模块
accessList := []models.Access{}
models.DB.Where("module_id = ?", 0).Find(&accessList)
c.HTML(http.StatusOK, "admin/access/add.html", gin.H{
"accessList": accessList,
})
}
完善后的方法:
func (con AccessController) Add(c *gin.Context) {
//获取顶级模块
rbacClient := pbAccess.NewRbacAccessService("rbac", models.RbacClient)
res, _ := rbacClient.AccessGet(context.Background(), &pbAccess.AccessGetRequest{})
c.HTML(http.StatusOK, "admin/access/add.html", gin.H{
"accessList": res.AccessList,
})
}
(3). DoAdd()方法调用微服务代码
原方法:
func (con AccessController) DoAdd(c *gin.Context) {
//获取表单数据
moduleName := strings.Trim(c.PostForm("module_name"), " ")
actionName := strings.Trim(c.PostForm("action_name"), " ")
accessType, err1 := models.Int(c.PostForm("type"))
url := c.PostForm("url")
moduleId, err2 := models.Int(c.PostForm("module_id"))
sort, err3 := models.Int(c.PostForm("sort"))
status, err4 := models.Int(c.PostForm("status"))
description := strings.Trim(c.PostForm("description"), " ")
//判断err
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
con.Error(c, "传入参数错误", "/admin/access/add")
return
}
//判断moduleName
if moduleName == "" {
con.Error(c, "模块名称不能为空", "/admin/access/add")
return
}
//实例化access
access := models.Access{
ModuleName: moduleName,
ActionName: actionName,
Type: accessType,
Url: url,
ModuleId: moduleId,
Sort: sort,
Status: status,
Description: description,
}
err5 := models.DB.Create(&access).Error
if err5 != nil {
con.Error(c, "添加权限失败", "/admin/access/add")
return
}
con.Success(c, "添加权限成功", "/admin/access")
}
完善后的方法:
func (con AccessController) DoAdd(c *gin.Context) {
//获取表单数据
moduleName := strings.Trim(c.PostForm("module_name"), " ")
actionName := strings.Trim(c.PostForm("action_name"), " ")
accessType, err1 := models.Int(c.PostForm("type"))
url := c.PostForm("url")
moduleId, err2 := models.Int(c.PostForm("module_id"))
sort, err3 := models.Int(c.PostForm("sort"))
status, err4 := models.Int(c.PostForm("status"))
description := strings.Trim(c.PostForm("description"), " ")
//判断err
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
con.Error(c, "传入参数错误", "/admin/access/add")
return
}
//判断moduleName
if moduleName == "" {
con.Error(c, "模块名称不能为空", "/admin/access/add")
return
}
//调用权限微服务功能:实现权限的添加
rbacClient := pbAccess.NewRbacAccessService("rbac", models.RbacClient)
res, _ := rbacClient.AccessAdd(context.Background(), &pbAccess.AccessAddRequest{
ModuleName: moduleName,
Type: int64(accessType),
ActionName: actionName,
Url: url,
ModuleId: int64(moduleId),
Sort: int64(sort),
Description: description,
Status: int64(status),
})
if !res.Success {
con.Error(c, "添加权限失败", "/admin/access/add")
return
}
con.Success(c, "添加权限成功", "/admin/access")
}
(3). Edit()方法调用微服务代码
原方法:
//编辑
func (con AccessController) Edit(c *gin.Context) {
//获取id
id, err := models.Int(c.Query("id"))
if err != nil {
con.Error(c, "传入数据错误", "/admin/access")
return
}
access := models.Access{Id: id}
models.DB.Find(&access)
//获取顶级模块
accessList := []models.Access{}
models.DB.Where("module_id = ?", 0).Find(&accessList)
c.HTML(http.StatusOK, "admin/access/edit.html", gin.H{
"access": access,
"accessList": accessList,
})
}
完善后的方法:
//编辑
func (con AccessController) Edit(c *gin.Context) {
//获取id
id, err := models.Int(c.Query("id"))
if err != nil {
con.Error(c, "传入数据错误", "/admin/access")
return
}
//获取当前id对应的access
rbacClient := pbAccess.NewRbacAccessService("rbac", models.RbacClient)
access, _ := rbacClient.AccessGet(context.Background(), &pbAccess.AccessGetRequest{
Id: int64(id),
})
//获取顶级模块
resAccess, _ := rbacClient.AccessGet(context.Background(), &pbAccess.AccessGetRequest{})
c.HTML(http.StatusOK, "admin/access/edit.html", gin.H{
"access": access.AccessList[0],
"accessList": resAccess.AccessList,
})
}
(4). DoEdit()方法调用微服务代码
原方法:
//编辑:提交
func (con AccessController) DoEdit(c *gin.Context) {
//获取提交的表单数据
id, err := models.Int(c.PostForm("id"))
if err != nil {
con.Error(c, "传入数据错误", "/admin/access/edit?id"+models.String(id))
return
}
//获取表单数据
moduleName := strings.Trim(c.PostForm("module_name"), " ")
actionName := strings.Trim(c.PostForm("action_name"), " ")
accessType, err1 := models.Int(c.PostForm("type"))
url := c.PostForm("url")
moduleId, err2 := models.Int(c.PostForm("module_id"))
sort, err3 := models.Int(c.PostForm("sort"))
status, err4 := models.Int(c.PostForm("status"))
description := strings.Trim(c.PostForm("description"), " ")
//判断err
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
con.Error(c, "传入数据错误", "/admin/access/edit?id"+models.String(id))
return
}
//判断moduleName
if moduleName == "" {
con.Error(c, "模块名称不能为空", "/admin/access/edit?id"+models.String(id))
return
}
//获取要修改的数据
access := models.Access{Id: id}
models.DB.Find(&access)
access.ModuleName = moduleName
access.ActionName = actionName
access.Type = accessType
access.Url = url
access.ModuleId = moduleId
access.Sort = sort
access.Status = status
access.Description = description
//保存
err5 := models.DB.Save(&access).Error
if err5 != nil {
con.Error(c, "编辑权限失败", "/admin/access/edit?id"+models.String(id))
return
}
con.Success(c, "编辑权限成功", "/admin/access")
}
完善后的方法:
//编辑:提交
func (con AccessController) DoEdit(c *gin.Context) {
//获取提交的表单数据
id, err := models.Int(c.PostForm("id"))
if err != nil {
con.Error(c, "传入数据错误", "/admin/access/edit?id"+models.String(id))
return
}
//获取表单数据
moduleName := strings.Trim(c.PostForm("module_name"), " ")
actionName := strings.Trim(c.PostForm("action_name"), " ")
accessType, err1 := models.Int(c.PostForm("type"))
url := c.PostForm("url")
moduleId, err2 := models.Int(c.PostForm("module_id"))
sort, err3 := models.Int(c.PostForm("sort"))
status, err4 := models.Int(c.PostForm("status"))
description := strings.Trim(c.PostForm("description"), " ")
//判断err
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
con.Error(c, "传入数据错误", "/admin/access/edit?id"+models.String(id))
return
}
//判断moduleName
if moduleName == "" {
con.Error(c, "模块名称不能为空", "/admin/access/edit?id"+models.String(id))
return
}
rbacClient := pbAccess.NewRbacAccessService("rbac", models.RbacClient)
accessRes, _ := rbacClient.AccessEdit(context.Background(), &pbAccess.AccessEditRequest{
Id: int64(id),
ModuleName: moduleName,
Type: int64(accessType),
ActionName: actionName,
Url: url,
ModuleId: int64(moduleId),
Sort: int64(sort),
Description: description,
Status: int64(status),
})
if !accessRes.Success {
con.Error(c, "编辑权限失败", "/admin/access/edit?id="+models.String(id))
return
}
con.Success(c, "编辑权限成功", "/admin/access/edit?id="+models.String(id))
}
(5). Delete()方法调用微服务代码
原方法:
//删除
func (con AccessController) Delete(c *gin.Context) {
//获取提交的表单数据
id, err := models.Int(c.Query("id"))
if err != nil {
con.Error(c, "传入数据错误", "/admin/access")
return
}
//获取要删除的数据
access := models.Access{Id: id}
models.DB.Find(&access)
if access.ModuleId == 0 { // 顶级模块
accessList := []models.Access{}
models.DB.Where("module_id = ? ", access.Id).Find(&accessList)
if len(accessList) > 0 {
con.Error(c, "当前模块下子菜单,请先删除子菜单后再来删除这个数据", "/admin/access")
return
}
}
// 操作 或者 菜单, 或者顶级模块下面没有子菜单, 可以直接删除
err = models.DB.Delete(&access).Error
if err != nil {
con.Error(c, "删除数据失败", "/admin/access")
return
}
con.Success(c, "删除数据成功", "/admin/access")
}
完善后的方法:
//删除
func (con AccessController) Delete(c *gin.Context) {
//获取提交的表单数据
id, err := models.Int(c.Query("id"))
if err != nil {
con.Error(c, "传入数据错误", "/admin/access")
return
}
//获取我们要删除的数据
rbacClient := pbAccess.NewRbacAccessService("rbac", models.RbacClient)
accessRes, _ := rbacClient.AccessDelete(context.Background(), &pbAccess.AccessDeleteRequest{
Id: int64(id),
})
if !accessRes.Success { //顶级模块
con.Error(c, accessRes.Message, "/admin/access")
return
}
//操作 或者菜单
con.Success(c, "删除数据成功", "/admin/access")
}
(6). 完整代码如下
package admin
import (
"context"
"github.com/gin-gonic/gin"
"goshop/models"
pbAccess "goshop/proto/rbacAccess"
"net/http"
"strings"
)
type AccessController struct {
BaseController
}
func (con AccessController) Index(c *gin.Context) {
//获取权限列表
rbacClient := pbAccess.NewRbacAccessService("rbac", models.RbacClient)
res, _ := rbacClient.AccessGet(context.Background(), &pbAccess.AccessGetRequest{})
c.HTML(http.StatusOK, "admin/access/index.html", gin.H{
"accessList": res.AccessList,
})
}
func (con AccessController) Add(c *gin.Context) {
//获取顶级模块
rbacClient := pbAccess.NewRbacAccessService("rbac", models.RbacClient)
res, _ := rbacClient.AccessGet(context.Background(), &pbAccess.AccessGetRequest{})
c.HTML(http.StatusOK, "admin/access/add.html", gin.H{
"accessList": res.AccessList,
})
}
func (con AccessController) DoAdd(c *gin.Context) {
//获取表单数据
moduleName := strings.Trim(c.PostForm("module_name"), " ")
actionName := strings.Trim(c.PostForm("action_name"), " ")
accessType, err1 := models.Int(c.PostForm("type"))
url := c.PostForm("url")
moduleId, err2 := models.Int(c.PostForm("module_id"))
sort, err3 := models.Int(c.PostForm("sort"))
status, err4 := models.Int(c.PostForm("status"))
description := strings.Trim(c.PostForm("description"), " ")
//判断err
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
con.Error(c, "传入参数错误", "/admin/access/add")
return
}
//判断moduleName
if moduleName == "" {
con.Error(c, "模块名称不能为空", "/admin/access/add")
return
}
//调用权限微服务功能:实现权限的添加
rbacClient := pbAccess.NewRbacAccessService("rbac", models.RbacClient)
res, _ := rbacClient.AccessAdd(context.Background(), &pbAccess.AccessAddRequest{
ModuleName: moduleName,
Type: int64(accessType),
ActionName: actionName,
Url: url,
ModuleId: int64(moduleId),
Sort: int64(sort),
Description: description,
Status: int64(status),
})
if !res.Success {
con.Error(c, "添加权限失败", "/admin/access/add")
return
}
con.Success(c, "添加权限成功", "/admin/access")
}
//编辑
func (con AccessController) Edit(c *gin.Context) {
//获取id
id, err := models.Int(c.Query("id"))
if err != nil {
con.Error(c, "传入数据错误", "/admin/access")
return
}
//获取当前id对应的access
rbacClient := pbAccess.NewRbacAccessService("rbac", models.RbacClient)
access, _ := rbacClient.AccessGet(context.Background(), &pbAccess.AccessGetRequest{
Id: int64(id),
})
//获取顶级模块
resAccess, _ := rbacClient.AccessGet(context.Background(), &pbAccess.AccessGetRequest{})
c.HTML(http.StatusOK, "admin/access/edit.html", gin.H{
"access": access.AccessList[0],
"accessList": resAccess.AccessList,
})
}
//编辑:提交
func (con AccessController) DoEdit(c *gin.Context) {
//获取提交的表单数据
id, err := models.Int(c.PostForm("id"))
if err != nil {
con.Error(c, "传入数据错误", "/admin/access/edit?id"+models.String(id))
return
}
//获取表单数据
moduleName := strings.Trim(c.PostForm("module_name"), " ")
actionName := strings.Trim(c.PostForm("action_name"), " ")
accessType, err1 := models.Int(c.PostForm("type"))
url := c.PostForm("url")
moduleId, err2 := models.Int(c.PostForm("module_id"))
sort, err3 := models.Int(c.PostForm("sort"))
status, err4 := models.Int(c.PostForm("status"))
description := strings.Trim(c.PostForm("description"), " ")
//判断err
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
con.Error(c, "传入数据错误", "/admin/access/edit?id"+models.String(id))
return
}
//判断moduleName
if moduleName == "" {
con.Error(c, "模块名称不能为空", "/admin/access/edit?id"+models.String(id))
return
}
rbacClient := pbAccess.NewRbacAccessService("rbac", models.RbacClient)
accessRes, _ := rbacClient.AccessEdit(context.Background(), &pbAccess.AccessEditRequest{
Id: int64(id),
ModuleName: moduleName,
Type: int64(accessType),
ActionName: actionName,
Url: url,
ModuleId: int64(moduleId),
Sort: int64(sort),
Description: description,
Status: int64(status),
})
if !accessRes.Success {
con.Error(c, "编辑权限失败", "/admin/access/edit?id="+models.String(id))
return
}
con.Success(c, "编辑权限成功", "/admin/access/edit?id="+models.String(id))
}
//删除
func (con AccessController) Delete(c *gin.Context) {
//获取提交的表单数据
id, err := models.Int(c.Query("id"))
if err != nil {
con.Error(c, "传入数据错误", "/admin/access")
return
}
//获取我们要删除的数据
rbacClient := pbAccess.NewRbacAccessService("rbac", models.RbacClient)
accessRes, _ := rbacClient.AccessDelete(context.Background(), &pbAccess.AccessDeleteRequest{
Id: int64(id),
})
if !accessRes.Success { //顶级模块
con.Error(c, accessRes.Message, "/admin/access")
return
}
//操作 或者菜单
con.Success(c, "删除数据成功", "/admin/access")
}
三.校验权限管理Rbac权限增删改查微服务功能
1.先启动服务端
见[golang gin框架] 40.Gin商城项目-微服务实战之Captcha验证码微服务代码, 这里还要启动验证码captcha微服务服务端代码以及权限管理Rbac微服务(用户登录微服务服务端,角色管理微服务服务端,管理员管理微服务服务端)服务端才行
2.启动客户端
在项目根目录下运行 :go run main.go,启动项目
3.校验权限管理Rbac权限增删改查微服务操作是否成功
访问后台登录页面,输入用户名,密码,验证码,登录到后台后,进入权限管理页面,对权限进行增删改查
删除操作后,发现没有该数据了,说明删除操作正确
好了,权限管理Rbac权限增删改查微服务功能客户端操作完成,这里微服务操作的服务端,客户端功能大致[golang gin框架] 43.Gin商城项目-微服务实战之后台Rbac微服务之管理员的增删改查以及管理员和角色关联类似,可参考该文章操作,下面一节继续讲解权限管理Rbac微服务之角色权限关联微服务
[上一节][golang gin框架] 43.Gin商城项目-微服务实战之后台Rbac微服务之管理员的增删改查以及管理员和角色关联