[golang gin框架] 44.Gin商城项目-微服务实战之后台Rbac微服务之权限的增删改查微服务

上一节讲解了[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          int64ModuleName  string //模块名称ActionName  string //操作名称Type        int64    //节点类型 :  1、表示模块    2、表示菜单     3、操作Url         string //路由跳转地址ModuleId    int64    //此module_id和当前模型的id关联       module_id= 0 表示模块Sort        int64Description stringStatus      int64AddTime     int64AccessItem  []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, 响应参数AccessGetResponserpc AccessGet(AccessGetRequest) returns (AccessGetResponse) {}//增加权限rpc方法: 请求参数AccessAddRequest, 响应参数AccessAddResponserpc AccessAdd(AccessAddRequest) returns (AccessAddResponse) {}//编辑权限rpc方法: 请求参数AccessEditRequest, 响应参数AccessEditResponserpc AccessEdit(AccessEditRequest) returns (AccessEditResponse) {}//删除权限rpc方法: 请求参数AccessDeleteRequest, 响应参数AccessDeleteResponserpc 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{//权限idint64 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 handlerimport ("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.AccessModelfor _, v := range accessList {//处理自关联的子数据var tempItemList []*pb.AccessModelfor _, 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 = tempListreturn 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).Errorif err != nil {res.Success = falseres.Message = "增加数据失败"} else {res.Success = trueres.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.ModuleNameaccess.Type = req.Typeaccess.ActionName = req.ActionNameaccess.Url = req.Urlaccess.ModuleId = req.ModuleIdaccess.Sort = req.Sortaccess.Description = req.Descriptionaccess.Status = req.Statuserr := models.DB.Save(&access).Errorif err != nil {res.Success = falseres.Message = "修改数据失败"} else {res.Success = trueres.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 = falseres.Message = "当前模块下面有菜单或者操作,请删除菜单或者操作以后再来删除这个数据"} else {models.DB.Delete(&access)res.Success = trueres.Message = "删除数据成功"}} else { //操作 或者菜单models.DB.Delete(&access)res.Success = trueres.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 mainimport ("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() {//集成consulconsulReg := consul.NewRegistry()// Create service//读取.ini里面的配置addr := models.Config.Section("consul").Key("addr").String()srv := micro.NewService(micro.Address(addr),  //指定微服务的ip:  选择注册服务器地址,也可以不配置,默认为本机,也可以选择consul集群中的clientmicro.Name(service),micro.Version(version),//注册consulmicro.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 serviceif 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 adminimport ("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"), " ")//判断errif err1 != nil || err2 != nil || err3 != nil || err4 != nil {con.Error(c, "传入参数错误", "/admin/access/add")return}//判断moduleNameif moduleName == "" {con.Error(c, "模块名称不能为空", "/admin/access/add")return}//实例化accessaccess := models.Access{ModuleName:  moduleName,ActionName:  actionName,Type:        accessType,Url:         url,ModuleId:    moduleId,Sort:        sort,Status:      status,Description: description,}err5 := models.DB.Create(&access).Errorif err5 != nil {con.Error(c, "添加权限失败", "/admin/access/add")return}con.Success(c, "添加权限成功", "/admin/access")
}//编辑
func (con AccessController) Edit(c *gin.Context) {//获取idid, 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"), " ")//判断errif err1 != nil || err2 != nil || err3 != nil || err4 != nil {con.Error(c, "传入数据错误", "/admin/access/edit?id"+models.String(id))return}//判断moduleNameif moduleName == "" {con.Error(c, "模块名称不能为空", "/admin/access/edit?id"+models.String(id))return}//获取要修改的数据access := models.Access{Id: id}models.DB.Find(&access)access.ModuleName = moduleNameaccess.ActionName = actionNameaccess.Type = accessTypeaccess.Url = urlaccess.ModuleId = moduleIdaccess.Sort = sortaccess.Status = statusaccess.Description = description//保存err5 := models.DB.Save(&access).Errorif 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).Errorif 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"), " ")//判断errif err1 != nil || err2 != nil || err3 != nil || err4 != nil {con.Error(c, "传入参数错误", "/admin/access/add")return}//判断moduleNameif moduleName == "" {con.Error(c, "模块名称不能为空", "/admin/access/add")return}//实例化accessaccess := models.Access{ModuleName:  moduleName,ActionName:  actionName,Type:        accessType,Url:         url,ModuleId:    moduleId,Sort:        sort,Status:      status,Description: description,}err5 := models.DB.Create(&access).Errorif 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"), " ")//判断errif err1 != nil || err2 != nil || err3 != nil || err4 != nil {con.Error(c, "传入参数错误", "/admin/access/add")return}//判断moduleNameif 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) {//获取idid, 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) {//获取idid, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/access")return}//获取当前id对应的accessrbacClient := 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"), " ")//判断errif err1 != nil || err2 != nil || err3 != nil || err4 != nil {con.Error(c, "传入数据错误", "/admin/access/edit?id"+models.String(id))return}//判断moduleNameif moduleName == "" {con.Error(c, "模块名称不能为空", "/admin/access/edit?id"+models.String(id))return}//获取要修改的数据access := models.Access{Id: id}models.DB.Find(&access)access.ModuleName = moduleNameaccess.ActionName = actionNameaccess.Type = accessTypeaccess.Url = urlaccess.ModuleId = moduleIdaccess.Sort = sortaccess.Status = statusaccess.Description = description//保存err5 := models.DB.Save(&access).Errorif 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"), " ")//判断errif err1 != nil || err2 != nil || err3 != nil || err4 != nil {con.Error(c, "传入数据错误", "/admin/access/edit?id"+models.String(id))return}//判断moduleNameif 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).Errorif 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 adminimport ("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"), " ")//判断errif err1 != nil || err2 != nil || err3 != nil || err4 != nil {con.Error(c, "传入参数错误", "/admin/access/add")return}//判断moduleNameif 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) {//获取idid, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/access")return}//获取当前id对应的accessrbacClient := 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"), " ")//判断errif err1 != nil || err2 != nil || err3 != nil || err4 != nil {con.Error(c, "传入数据错误", "/admin/access/edit?id"+models.String(id))return}//判断moduleNameif 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微服务之管理员的增删改查以及管理员和角色关联

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/15623.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NIDEC COMPONENTS尼得科科宝滑动型DIP开关各系列介绍

今天AMEYA360对尼得科科宝电子滑动型DIP开关各系列参数进行详细介绍,方便大家选择适合自己的型号。 系列一、滑动型DIP开关 CVS 针脚数:1, 2, 3, 4, 8 安装类型:表面贴装,通孔 可水洗:无 端子类型:PC引脚(只…

RPC与REST有什么区别?

原文:RPC与REST有什么区别? 背景 好多开发的同学在工作中,经常分不清RPC和REST的区别,导致经常沟通不在一个层次上。甚至有些同学把这两个当成同一个东西。 RPC与REST的区别? 对比名称 rpc rest 备注 架构风格 RP…

[个人笔记] Windows配置NTP时间同步

Windows - 运维篇 第六章 Windows配置NTP时间同步 Windows - 运维篇系列文章回顾Windows配置NTP时间同步域控环境的NTP配置工作组环境的NTP配置Windows的CMD部分命令集 参考来源 系列文章回顾 第一章 迁移WinSrv系统到虚拟机 第二章 本地安全策略xcopy实现实时备份文件夹内容 …

重发布及路由策略

目录 重发布 作用 条件 规则 名词解释点 点 向 单点重发布 双点重发布 路由策略 控制层流量和数据层流量 抓流量 ACL列表 前缀列表( ip-prefix) 实例演示 做策略 过滤策略(过滤器-策略) 路由策略(route-policy) 基本配置 路由策略使用 配置实验 重发布 在…

【C++】反向迭代器的模拟实现通用(可运用于vector,string,list等模拟容器)

文章目录 前言一、反向迭代器封装(reverseiterator)1.构造函数1解引用操作.3.->运算符重载4.前置,后置5.前置--,后置--6.不等号运算符重载7.完整代码 二、rbegin()以及rend()1.rb…

数学分析:外微分

先回顾下微分的概念,首先我们找到一个道路x,它是关于时间t的函数,然后我们可以得到一个速度,也就是切向量,所有道路的切向量组成了切空间。如果从泛函角度来理解,它应该是一个求偏导的基。是一个向量。而微…

国内 github.com经常打不开的解决办法

1、打开网站http://tool.chinaz.com/dns/ 2、在A类型中填写github.com,再点击监测按钮 3、复制下面任意一个ip 4、打开电脑文件C:\Windows\System32\drivers\etc下的host文件 5、在host文件的最后一刚加入刚才复制的IP 6、重新打开GitHub

[内测招募] IDEA 插件 X-ChatGPT 内测预览版 支持自定义 ChatGPT 回调函数 释放 AI 的无限可能性

X-ChatGPT 独创的 [项目感知] 功能 打造更精准、更智能、更懂你 的专属 ai 编程助手 这个插件是一款基于开源项目 ChatGPT-Next-Web的 IntelliJ IDEA 平台的插件 价格 :免费、速率限制 每小时/100 次/ip 使用方式 :在 IDEA 插件商店中搜索 X-ChatGPT…

DNP透明屏有哪些优点?

DNP透明屏是一种新型的显示技术,它能够将图像或视频直接投射到透明的屏幕上,使得观众可以同时看到屏幕后面的实物。 这种技术在广告、展览、商场等场合得到了广泛的应用。 DNP透明屏的工作原理是利用光学投影技术,将图像或视频通过投影仪投射…

品牌活动 | 阿里云云原生技术实践营:大模型+CloudOS,实现企业智能化

近日,由阿里云举办的“云原生技术实践营-应用和容器实践专场”在广州顺利开展。行云创新CEO马洪喜作为受邀嘉宾之一,参加了本次活动,分享了主题为“API大语言模型,以非侵入式实现企业业务智能化变革”的演讲,向参会者展…

json-server详解

零、文章目录 json-server详解 1、简介 Json-server 是一个零代码快速搭建本地 RESTful API 的工具。它使用 JSON 文件作为数据源,并提供了一组简单的路由和端点,可以模拟后端服务器的行为。github地址:https://github.com/typicode/json-…

芯片制造详解.刻蚀原理.学习笔记(五)

本篇笔记是看完原视频后的整理和补充,建议各位观看原视频,这里附上地址。 如何雕刻芯片:刻蚀原理|芯片制造详解05 芯片制造详解.刻蚀原理.学习笔记 五 一、刻蚀技术的分类二、刻蚀中三个关键指标2.1 刻蚀速率2.2 选择比2.3 方向性…

pytorch学习——线性神经网络——1线性回归

概要:线性神经网络是一种最简单的神经网络模型,它由若干个线性变换和非线性变换组成。线性变换通常表示为矩阵乘法,非线性变换通常是一个逐元素的非线性函数。线性神经网络通常用于解决回归和分类问题。 一.线性回归 线性回归是一种常见的机…

RISC-V公测平台发布 · 如何在SG2042上玩转k3s

前言 Kubernetes是一个开源的容器管理平台,通过Kubernetes的跨集群管理功能,用户可以方便地进行应用程序的复制、迁移和跨云平台的部署。 而k3s作为Kubernetes的轻量级发行版,相比传统的Kubernetes具有更小的二进制文件大小和更低的资源消耗…

#typescript 使用file-saver模块#

场景:前端使用file-saver模块做导出文档的时候,出现两个错误 1:npm run build 提示找不到模块,如图 解决方法: 先卸载,不管是否安装都先要卸载 ,然后安装: npm uninstall file-saver npm…

流星特效案例代码

实际效果&#xff0c;代码下载即可使用 流星图片 <!-- 描述: 流星特效 作者: Jack GUO 日期: 20230727 --> <template> <div class"wrap-container sn-container"> <div class"pd-main-left"> <div class"yun-container&…

Flutter环境搭建踩坑集锦

Flutter 背景准备工作先检查一下自己的电脑&#xff0c;看一下是不是满足配置要求下载安装配置环境下载安装JDK下载安装Android studio下载Flutterflutter doctor故障Android license status unknownNetwork resources 故障 后记 背景 发现一个不错的框架Flutter&#xff0c;听…

线程同步问题——锁

文章目录 线程同步互斥锁&#xff08;互斥量&#xff09;相关操作函数应用 死锁读写锁相关操作函数 线程同步 临界区——代码 临界数据——共享数据 原子操作&#xff1a;不可以被其他操作打断 必须的&#xff0c;用以保证数据的安全性 实现线程同步的方式&#xff1a; 互斥量…

什么是 DNS ANAME 解析?

本人使用谷歌搜索了简中互联网&#xff0c;完全没有找到任何有关 ANAME 的文章……本文该不会是头一份吧 相信大家对于 DNS 的解析方式都不陌生&#xff0c;常见的有 A、CNAME、MX、TXT 记录等等。其中&#xff0c;网站常用的是 A 记录和 CNAME 记录&#xff1a;A 记录用于将域…