[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引脚(只…

Linux echo命令与反引号、重定向符号以及管道符

echo echo命令echo结合反引号echo结合重定向符echo结合管道符 echo命令 Linux中的echo命令用于在终端输出指定的文本内容或变量值。 基本语法如下: echo [选项] [字符串]常用选项包括: -e:启用特殊字符的解析,例如\n表示换行符…

RPC与REST有什么区别?

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

vue使用,引用 腾讯pag 播放文件,且解决销毁问题

PAG官网:官网 https://pag.art/docs/sdk.html#web-%E7%AB%AF%E6%8E%A5%E5%85%A5 一、创建依赖准备 libpag.min.js libpag.wasm去git上下载就行了 https://github.com/Tencent/libpag/releases/tag/v4.3.3 下载 libpag_4.3.3_web.zip 里边有 两个文件放到 public 中…

Scala定时任务启动例子

Scala定时任务启动例子 Scala代码 package com.scala.testimport java.time.LocalDateTime import java.util.concurrent.Executors import scala.concurrent.duration._ import org.apache.spark.sql.SparkSessionobject TimingTaskTest {def main(args: Array[String]): Un…

[个人笔记] 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的函数,然后我们可以得到一个速度,也就是切向量,所有道路的切向量组成了切空间。如果从泛函角度来理解,它应该是一个求偏导的基。是一个向量。而微…

从零开始学习 Java:简单易懂的入门指南之数组(五)

java基础知识 1.数组概念: 2.数组的定义格式一:格式二:详解:注意点: 3.数组的静态初始化完整格式:格式详解:注意点:简化格式:练习1:练习2:练习3: …

国内 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大语言模型,以非侵入式实现企业业务智能化变革”的演讲,向参会者展…

【设计模式|行为型】命令模式(Command Pattern)

说明 命令模式(Command Pattern)是一种行为设计模式,它将请求封装为一个对象,以便在不同的请求者和接收者之间进行解耦、参数化和操作的队列化。命令模式允许你将具体的请求封装为对象,这些对象之间彼此独立&#xff…

json-server详解

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

Spark编程-Spark中的Row

Spark中的Row Spark中的Row是Spark SQL中的一种数据结构,用于表示一行数据。 代码案例 创建Row对象 import org.apache.spark.sql.Row // 创建一个Row对象,表示一行数据 val row Row("John", 30, "New York") // 访问Row对象的字…

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

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

Arm 扩大开源合作伙伴关系,加强投入开放协作

作者:Arm 开源软件副总裁 Mark Hambleton Arm 和我们的生态系统的关键信念之一是与开源社区合作,共创一个高度发达的 Arm 架构,使软件的落地更加稳定,从而让全球数百万开发者能够测试并创建自己的应用。 为此,Arm 支…

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

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