当前位置: 首页 > news >正文

[golang gin框架] 43.Gin商城项目-微服务实战之后台Rbac微服务之管理员的增删改查以及管理员和角色关联

上一节讲解了后台Rbac微服务角色增删改查微服务,这里讲解权限管理Rbac微服务管理员的增删改查微服务以及管理员和角色关联微服务功能

 一.实现后台权限管理Rbac之管理员增删改查微服务服务端功能

1.创建Manager模型 

要实现管理员的增删改查,就需要创建对应的模型,故在server/rbac/models下创建manager.go模型文件,参考[golang gin框架] 14.Gin 商城项目-RBAC管理代码如下: 

package models//管理员表type Manager struct { // 结构体首字母大写, 和数据库表名对应, 默认访问数据表users, 可以设置访问数据表的方法Id  intUsername stringPassword stringMobile stringEmail stringStatus intRoleId intAddTime intIsSuper intRole Role `gorm:"foreignKey:RoleId;references:Id"`  // 配置关联关系
}//配置数据库操作的表名称
func (Manager) TableName() string {return "manager"
}

 2.在proto文件夹下创建rbacManager.proto

 参考[golang gin框架] 14.Gin 商城项目-RBAC管理,创建rbacManager.proto.生成管理员相关方法,具体代码如下:

syntax = "proto3";package manager;option go_package = "./proto/rbacManager";//管理员管理微服务rpc方法
service RbacManager {//获取管理员rpc方法: 请求参数ManagerGetRequest, 响应参数ManagerGetResponserpc ManagerGet(ManagerGetRequest) returns (ManagerGetResponse) {}//增加管理员rpc方法: 请求参数ManagerAddRequest, 响应参数ManagerAddResponserpc ManagerAdd(ManagerAddRequest) returns (ManagerAddResponse) {}//编辑管理员rpc方法: 请求参数ManagerEditRequest, 响应参数ManagerEditResponserpc ManagerEdit(ManagerEditRequest) returns (ManagerEditResponse) {}//删除管理员rpc方法: 请求参数ManagerDeleteRequest, 响应参数ManagerDeleteResponserpc ManagerDelete(ManagerDeleteRequest) returns (ManagerDeleteResponse) {}
}//管理员对应的结构体
message ManagerModel{int64 id=1;string username=2;string password=3;string mobile=4;string email=5;int64 status =6;int64 roleId=7;int64 addTime=8;int64 isSuper=9;RoleModel role=10;  // 管理员关联的角色
}//角色对应的结构体
message RoleModel{int64 id=1;string title=2;string description=3;int64 status=4;int64 addTime =5;
}//获取管理员请求参数, 当传入id或者管理员名称时,获取对应的管理员数据,如果什么都没传入,则获取管理员列表
message ManagerGetRequest{int64 id =1;string username =2;
}//获取管理员响应参数
message ManagerGetResponse{repeated ManagerModel ManagerList=1;  //返回管理员切片
}//增加管理员请求参数
message ManagerAddRequest{string username=1;string password=2;string mobile=3;string email=4;int64 status =5;int64 roleId=6;int64 addTime=7;int64 isSuper=8;
}//增加管理员响应参数
message ManagerAddResponse{bool success=1;string message=2;
}//编辑管理员请求参数
message ManagerEditRequest{int64 id=1;string username=2;string password=3;string mobile=4;string email=5;int64 status =6;int64 roleId=7;int64 addTime=8;int64 isSuper=9;
}//编辑管理员响应参数
message ManagerEditResponse{bool success=1;string message=2;
}//删除管理员请求参数
message ManagerDeleteRequest{int64 id=1;
}//删除管理员响应参数
message ManagerDeleteResponse{bool success=1;string message=2;
}

3.生成manager相关pb.go,pb.micro.go文件

在server/rbac下运行命令protoc --proto_path=. --micro_out=. --go_out=:. proto/rbacManager.proto即可

 4.在handler文件夹下创建rbacManager.go文件,实现proto中的service方法

参考[golang gin框架] 14.Gin 商城项目-RBAC管理_角色的增删改查方法代码,具体rbacManager.go代码如下:

package handlerimport ("context""strconv""rbac/models"pb "rbac/proto/rbacManager"
)type RbacManager struct{}//获取管理员
func (e *RbacManager) ManagerGet(ctx context.Context, req *pb.ManagerGetRequest, res *pb.ManagerGetResponse) error {managerList := []models.Manager{}where := "1=1"if req.Id > 0 { // 当传入管理员id时,获取对应的管理员数据, 当没有传入管理员id时,获取管理员列表数据where += " AND id=" + strconv.Itoa(int(req.Id))}if len(req.Username) > 0 { //判断是否传入管理员名称where += " AND username=" + req.Username}models.DB.Where(where).Preload("Role").Find(&managerList)  //获取管理员数据自己对应的关联角色数据//处理数据var tempList []*pb.ManagerModelfor _, v := range managerList {tempList = append(tempList, &pb.ManagerModel{Id:       int64(v.Id),Username: v.Username,Mobile:   v.Mobile,Email:    v.Email,Status:   int64(v.Status),RoleId:   int64(v.RoleId),AddTime:  int64(v.AddTime),IsSuper:  int64(v.IsSuper),Role: &pb.RoleModel{  //角色数据,可根据自己项目情况获取自己想要的数据Title:       v.Role.Title,Description: v.Role.Description,},})}res.ManagerList = tempListreturn nil
}//增加管理员
func (e *RbacManager) ManagerAdd(ctx context.Context, req *pb.ManagerAddRequest, res *pb.ManagerAddResponse) error {//执行增加管理员manager := models.Manager{Username: req.Username,Password: req.Password,Email:    req.Email,Mobile:   req.Mobile,RoleId:   int(req.RoleId),Status:   int(req.Status),AddTime:  int(req.AddTime),}err := models.DB.Create(&manager).Errorif err != nil {res.Success = falseres.Message = "增加数据失败"} else {res.Success = trueres.Message = "增加数据成功"}return err
}//修改管理员
func (e *RbacManager) ManagerEdit(ctx context.Context, req *pb.ManagerEditRequest, res *pb.ManagerEditResponse) error {//执行修改manager := models.Manager{Id: int(req.Id)}models.DB.Find(&manager)manager.Username = req.Usernamemanager.Email = req.Emailmanager.Mobile = req.Mobilemanager.RoleId = int(req.RoleId)//注意:判断密码是否为空 为空表示不修改密码 不为空表示修改密码if req.Password != "" {manager.Password = req.Password}err := models.DB.Save(&manager).Errorif err != nil {res.Success = falseres.Message = "修改数据失败"} else {res.Success = trueres.Message = "修改数据成功"}return err
}//删除管理员
func (e *RbacManager) ManagerDelete(ctx context.Context, req *pb.ManagerDeleteRequest, res *pb.ManagerDeleteResponse) error {manager := models.Manager{Id: int(req.Id)}//这里可以是物理删除或者逻辑删除,根据自己项目情况选择err := models.DB.Delete(&manager).Errorif err != nil {res.Success = falseres.Message = "删除数据失败"} else {res.Success = trueres.Message = "删除数据成功"}return err
}

5.在main.go文件中注册管理员微服务

只需在import中引入pbManager "rbac/proto/rbacManager"以及在main()中加入以下代码即可: 

// Register handler:注册管理员微服务if err := pbRole.RegisterRbacManagerHandler(srv.Server(), new(handler.RbacManager)); err != nil {logger.Fatal(err)}

具体代码如下:

package mainimport ("rbac/handler""rbac/models"pb "rbac/proto/rbacLogin"pbRole "rbac/proto/rbacRole"pbManager "rbac/proto/rbacManager""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)}// Run serviceif err := srv.Run(); err != nil {logger.Fatal(err)}
}

二.实现后台权限管理Rbac管理员客户端微服务功能

参考[golang gin框架] 41.Gin商城项目-微服务实战之后台Rbac微服务(用户登录 ,Gorm数据库配置单独抽离,Consul配置单独抽离)

1.复制server/rbac/proto文件夹下rbacManager.go以及rbacManager文件夹到client项目中的proto文件夹下 

2. 调用Rbac角色增删改查微服务

在controllers/admin/maanger.go的Index(),Add(),DoAdd(),Edit(),DoEdit(),Delete()方法中调用Rbac管理员增删改查微服务功能,这里需要在import中引入rbacRole,rbacManager微服务相关包,代码如下:

import (pbManager "goshop/proto/rbacManager"pbRole "goshop/proto/rbacRole"
)

原controllers/admin/manager.go代码如下:也可参考[golang gin框架] 14.Gin 商城项目-RBAC管理

package adminimport ("github.com/gin-gonic/gin""goshop/models""net/http""strings"
)type ManagerController struct {BaseController
}func (con ManagerController) Index(c *gin.Context) {//获取管理员列表,以及关联对应的角色managerList := []models.Manager{}models.DB.Preload("Role").Find(&managerList)c.HTML(http.StatusOK, "admin/manager/index.html", gin.H{"managerList": managerList,})
}//添加管理员
func (con ManagerController) Add(c *gin.Context) {//获取角色roleList := []models.Role{}models.DB.Find(&roleList)c.HTML(http.StatusOK, "admin/manager/add.html", gin.H{"roleList": roleList,})
}//添加管理员:提交
func (con ManagerController) DoAdd(c *gin.Context) {//获取角色id,判断是否合法roleId, err := models.Int(c.PostForm("role_id"))if err != nil {con.Error(c, "角色不合法", "/admin/manager/add")return}//获取提交的表单信息username := strings.Trim(c.PostForm("username"), " ")password := strings.Trim(c.PostForm("password"), " ")email := strings.Trim(c.PostForm("email"), " ")mobile := strings.Trim(c.PostForm("mobile"), " ")//判断用户名和密码是否符合要求if len(username) < 2 || len(password) < 6 {con.Error(c, "用户名或密码长度不合法", "/admin/manager/add")return}//判断管理员是否存在managerList := []models.Manager{}models.DB.Where("username = ?", username).Find(&managerList)if len(managerList) > 0 {con.Error(c, "管理员已存在", "/admin/manager/add")return}//实例化Manager,执行增加管理员manager := models.Manager{Username: username,Password: models.Md5(password),Email:    email,Mobile:   mobile,AddTime:  int(models.GetUnix()),RoleId:   roleId,Status:   1,}err = models.DB.Create(&manager).Errorif err != nil {con.Error(c, "添加管理员失败", "/admin/manager/add")return}con.Success(c, "添加管理员成功", "/admin/manager")
}//编辑管理员
func (con ManagerController) Edit(c *gin.Context) {//获取管理员id, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/manager")return}manager := models.Manager{Id: id}models.DB.Find(&manager)if manager.Username == "" {con.Error(c, "管理员#" + models.String(id) + "不存在", "/admin/manager")return}//获取所有角色roleList := []models.Role{}models.DB.Find(&roleList)c.HTML(http.StatusOK, "admin/manager/edit.html", gin.H{"manager":  manager,"roleList": roleList,})
}//编辑管理员提交
func (con ManagerController) DoEdit(c *gin.Context) {//获取管理员id,并判断id, err := models.Int(c.PostForm("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//获取角色id,并判断roleId, err2 := models.Int(c.PostForm("role_id"))if err2 != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//获取提交的表单信息username := strings.Trim(c.PostForm("username"), " ")password := strings.Trim(c.PostForm("password"), " ")email := strings.Trim(c.PostForm("email"), " ")mobile := strings.Trim(c.PostForm("mobile"), " ")//执行修改manager := models.Manager{Id: id}models.DB.Find(&manager)manager.Username = usernamemanager.Email = emailmanager.RoleId = roleIdmanager.Mobile = mobile//判断密码, 为空 表示不修改密码if password != "" {//判断密码长度if len(password) < 6 {con.Error(c, "密码长度不合法", "/admin/manager/edit?id" + models.String(id))return}manager.Password = models.Md5(password)}//保存err = models.DB.Save(&manager).Errorif err != nil {con.Error(c, "修改数据失败", "/admin/manager/edit?id="+models.String(id))return}con.Success(c, "修改数据成功", "/admin/manager")
}//删除
func (con ManagerController) Delete(c *gin.Context) {//获取提交的表单数据id, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//查询管理员是否存在manager := models.Manager{Id: id}err = models.DB.Delete(&manager).Errorif err != nil {con.Error(c, "删除数据失败", "/admin/manager")return}con.Success(c, "删除数据成功", "/admin/manager")
}

(1). 这里需要完善一下 models/tool.go中的UnixToTime()方法

目的是为了根据传入不同类型的时间戳,来返回对应的时间,原方法:

//时间戳转换成日期函数
func UnixToTime(timestamp int) string {t := time.Unix(int64(timestamp), 0)return t.Format("2006-01-02 15:04:05")
}

 完善后的方法:

//时间戳转换成日期函数
func UnixToTime(timestamp interface{}) string {value1, ok64 := timestamp.(int64)  //类型断言,判断传入的参数数据类型,并根据不同数据类型进行逻辑处理value2, ok32 := timestamp.(int32)value3, ok := timestamp.(int)if ok64 {t := time.Unix(value1, 0)return t.Format("2006-01-02 15:04:05")} else if ok32 {t := time.Unix(int64(value2), 0)return t.Format("2006-01-02 15:04:05")} else if ok {t := time.Unix(int64(value3), 0)return t.Format("2006-01-02 15:04:05")} else {return "time error"}
}

(2). Index()方法调用微服务代码

原方法:

func (con ManagerController) Index(c *gin.Context) {//获取管理员列表,以及关联对应的角色managerList := []models.Manager{}models.DB.Preload("Role").Find(&managerList)c.HTML(http.StatusOK, "admin/manager/index.html", gin.H{"managerList": managerList,})
}

完善后的方法:

func (con ManagerController) Index(c *gin.Context) {//调用Rbac微服务:获取管理员列表,以及关联对应的角色rbacClient := pbManager.NewRbacManagerService("rbac", models.RbacClient)res, _ := rbacClient.ManagerGet(context.Background(), &pbManager.ManagerGetRequest{})c.HTML(http.StatusOK, "admin/manager/index.html", gin.H{"managerList": res.ManagerList,})
}

(3).Add()方法调用微服务代码

原方法:

//添加管理员
func (con ManagerController) Add(c *gin.Context) {//获取角色roleList := []models.Role{}models.DB.Find(&roleList)c.HTML(http.StatusOK, "admin/manager/add.html", gin.H{"roleList": roleList,})
}

完善后的方法:

//添加管理员
func (con ManagerController) Add(c *gin.Context) {//获取所有的角色rbacClient := pbRole.NewRbacRoleService("rbac", models.RbacClient)res, _ := rbacClient.RoleGet(context.Background(), &pbRole.RoleGetRequest{})c.HTML(http.StatusOK, "admin/manager/add.html", gin.H{"roleList": res.RoleList,})
}

 (4).DoAdd()方法调用微服务代码

原方法:

//添加管理员:提交
func (con ManagerController) DoAdd(c *gin.Context) {//获取角色id,判断是否合法roleId, err := models.Int(c.PostForm("role_id"))if err != nil {con.Error(c, "角色不合法", "/admin/manager/add")return}//获取提交的表单信息username := strings.Trim(c.PostForm("username"), " ")password := strings.Trim(c.PostForm("password"), " ")email := strings.Trim(c.PostForm("email"), " ")mobile := strings.Trim(c.PostForm("mobile"), " ")//判断用户名和密码是否符合要求if len(username) < 2 || len(password) < 6 {con.Error(c, "用户名或密码长度不合法", "/admin/manager/add")return}//判断管理员是否存在managerList := []models.Manager{}models.DB.Where("username = ?", username).Find(&managerList)if len(managerList) > 0 {con.Error(c, "管理员已存在", "/admin/manager/add")return}//实例化Manager,执行增加管理员manager := models.Manager{Username: username,Password: models.Md5(password),Email:    email,Mobile:   mobile,AddTime:  int(models.GetUnix()),RoleId:   roleId,Status:   1,}err = models.DB.Create(&manager).Errorif err != nil {con.Error(c, "添加管理员失败", "/admin/manager/add")return}con.Success(c, "添加管理员成功", "/admin/manager")
}

完善后的方法:

//添加管理员:提交
func (con ManagerController) DoAdd(c *gin.Context) {//获取角色id,判断是否合法roleId, err := models.Int(c.PostForm("role_id"))if err != nil {con.Error(c, "角色不合法", "/admin/manager/add")return}//获取提交的表单信息username := strings.Trim(c.PostForm("username"), " ")password := strings.Trim(c.PostForm("password"), " ")email := strings.Trim(c.PostForm("email"), " ")mobile := strings.Trim(c.PostForm("mobile"), " ")//判断用户名和密码是否符合要求if len(username) < 2 || len(password) < 6 {con.Error(c, "用户名或密码长度不合法", "/admin/manager/add")return}//判断管理员是否存在rbacClient := pbManager.NewRbacManagerService("rbac", models.RbacClient)res, _ := rbacClient.ManagerGet(context.Background(), &pbManager.ManagerGetRequest{Username: username,})if len(res.ManagerList) > 0 {con.Error(c, "此管理员已存在", "/admin/manager/add")return}//调用增加管理员微服务方法:执行增加管理员addResult, _ := rbacClient.ManagerAdd(context.Background(), &pbManager.ManagerAddRequest{Username: username,Password: models.Md5(password),Email:    email,Mobile:   mobile,RoleId:   int64(roleId),Status:   1,AddTime:  int64(models.GetUnix()),})if !addResult.Success {con.Error(c, "添加管理员失败", "/admin/manager/add")return}con.Success(c, "增加管理员成功", "/admin/manager")
}

 (5).Edit()方法调用微服务代码

原方法:

//编辑管理员
func (con ManagerController) Edit(c *gin.Context) {//获取管理员id, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/manager")return}manager := models.Manager{Id: id}models.DB.Find(&manager)if manager.Username == "" {con.Error(c, "管理员#" + models.String(id) + "不存在", "/admin/manager")return}//获取所有角色roleList := []models.Role{}models.DB.Find(&roleList)c.HTML(http.StatusOK, "admin/manager/edit.html", gin.H{"manager":  manager,"roleList": roleList,})
}

完善后的方法:

//编辑管理员
func (con ManagerController) Edit(c *gin.Context) {//获取管理员id, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//通过管理员微服务获取管理员//获取管理员managerClient := pbManager.NewRbacManagerService("rbac", models.RbacClient)resManager, _ := managerClient.ManagerGet(context.Background(), &pbManager.ManagerGetRequest{Id: int64(id),})if len(resManager.ManagerList) <= 0  {con.Error(c, "管理员#" + models.String(id) + "不存在", "/admin/manager")return}//获取所有的角色roleClient := pbRole.NewRbacRoleService("rbac", models.RbacClient)resRole, _ := roleClient.RoleGet(context.Background(), &pbRole.RoleGetRequest{})c.HTML(http.StatusOK, "admin/manager/edit.html", gin.H{"manager":  resManager.ManagerList[0],"roleList": resRole.RoleList,})
}

(6).DoEdit()方法调用微服务代码

原方法:

//编辑管理员提交
func (con ManagerController) DoEdit(c *gin.Context) {//获取管理员id,并判断id, err := models.Int(c.PostForm("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//获取角色id,并判断roleId, err2 := models.Int(c.PostForm("role_id"))if err2 != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//获取提交的表单信息username := strings.Trim(c.PostForm("username"), " ")password := strings.Trim(c.PostForm("password"), " ")email := strings.Trim(c.PostForm("email"), " ")mobile := strings.Trim(c.PostForm("mobile"), " ")//执行修改manager := models.Manager{Id: id}models.DB.Find(&manager)manager.Username = usernamemanager.Email = emailmanager.RoleId = roleIdmanager.Mobile = mobile//判断密码, 为空 表示不修改密码if password != "" {//判断密码长度if len(password) < 6 {con.Error(c, "密码长度不合法", "/admin/manager/edit?id" + models.String(id))return}manager.Password = models.Md5(password)}//保存err = models.DB.Save(&manager).Errorif err != nil {con.Error(c, "修改数据失败", "/admin/manager/edit?id="+models.String(id))return}con.Success(c, "修改数据成功", "/admin/manager")
}

完善后的方法:

//编辑管理员提交
func (con ManagerController) DoEdit(c *gin.Context) {//获取管理员id,并判断id, err := models.Int(c.PostForm("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//获取角色id,并判断roleId, err2 := models.Int(c.PostForm("role_id"))if err2 != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//获取提交的表单信息username := strings.Trim(c.PostForm("username"), " ")password := strings.Trim(c.PostForm("password"), " ")email := strings.Trim(c.PostForm("email"), " ")mobile := strings.Trim(c.PostForm("mobile"), " ")//执行修改//判断电话号码是否合法if len(mobile) > 11 {con.Error(c, "mobile长度不合法", "/admin/manager/edit?id="+models.String(id))return}//注意:判断密码是否为空 为空表示不修改密码 不为空表示修改密码if password != "" {//判断密码长度是否合法if len(password) < 6 {con.Error(c, "密码的长度不合法 密码长度不能小于6位", "/admin/manager/edit?id="+models.String(id))return}password = models.Md5(password)}//调用管理员修改微服务方法进行修改managerClient := pbManager.NewRbacManagerService("rbac", models.RbacClient)editResult, _ := managerClient.ManagerEdit(context.Background(), &pbManager.ManagerEditRequest{Id:       int64(id),Username: username,Password: password,Email:    email,Mobile:   mobile,RoleId:   int64(roleId),})if !editResult.Success {con.Error(c, "修改数据失败", "/admin/manager/edit?id="+models.String(id))return}con.Success(c, "修改数据成功", "/admin/manager")
}

(7).Delete()方法调用微服务代码

原方法:

//删除
func (con ManagerController) Delete(c *gin.Context) {//获取提交的表单数据id, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//查询管理员是否存在manager := models.Manager{Id: id}err = models.DB.Delete(&manager).Errorif err != nil {con.Error(c, "删除数据失败", "/admin/manager")return}con.Success(c, "删除数据成功", "/admin/manager")
}

完善后的方法:

//删除
func (con ManagerController) Delete(c *gin.Context) {//获取提交的表单数据id, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//查询管理员是否存在//获取管理员managerClient := pbManager.NewRbacManagerService("rbac", models.RbacClient)resManager, _ := managerClient.ManagerGet(context.Background(), &pbManager.ManagerGetRequest{Id: int64(id),})if len(resManager.ManagerList) <= 0  {con.Error(c, "管理员#" + models.String(id) + "不存在", "/admin/manager")return}//调用管理员删除方法进行删除managerDeleteClient := pbManager.NewRbacManagerService("rbac", models.RbacClient)managerRes, _ := managerDeleteClient.ManagerDelete(context.Background(), &pbManager.ManagerDeleteRequest{Id: int64(id),})if managerRes.Success {con.Success(c, "删除数据成功", "/admin/manager")return}con.Success(c, "删除数据失败", "/admin/manager")
}

(8).完整代码如下

package adminimport ("github.com/gin-gonic/gin""goshop/models"pbRole "goshop/proto/rbacRole""net/http""strings""context"pbManager "goshop/proto/rbacManager"
)type ManagerController struct {BaseController
}func (con ManagerController) Index(c *gin.Context) {//调用Rbac微服务:获取管理员列表,以及关联对应的角色rbacClient := pbManager.NewRbacManagerService("rbac", models.RbacClient)res, _ := rbacClient.ManagerGet(context.Background(), &pbManager.ManagerGetRequest{})c.HTML(http.StatusOK, "admin/manager/index.html", gin.H{"managerList": res.ManagerList,})}//添加管理员
func (con ManagerController) Add(c *gin.Context) {//获取所有的角色rbacClient := pbRole.NewRbacRoleService("rbac", models.RbacClient)res, _ := rbacClient.RoleGet(context.Background(), &pbRole.RoleGetRequest{})c.HTML(http.StatusOK, "admin/manager/add.html", gin.H{"roleList": res.RoleList,})
}//添加管理员:提交
func (con ManagerController) DoAdd(c *gin.Context) {//获取角色id,判断是否合法roleId, err := models.Int(c.PostForm("role_id"))if err != nil {con.Error(c, "角色不合法", "/admin/manager/add")return}//获取提交的表单信息username := strings.Trim(c.PostForm("username"), " ")password := strings.Trim(c.PostForm("password"), " ")email := strings.Trim(c.PostForm("email"), " ")mobile := strings.Trim(c.PostForm("mobile"), " ")//判断用户名和密码是否符合要求if len(username) < 2 || len(password) < 6 {con.Error(c, "用户名或密码长度不合法", "/admin/manager/add")return}//判断管理员是否存在rbacClient := pbManager.NewRbacManagerService("rbac", models.RbacClient)res, _ := rbacClient.ManagerGet(context.Background(), &pbManager.ManagerGetRequest{Username: username,})if len(res.ManagerList) > 0 {con.Error(c, "此管理员已存在", "/admin/manager/add")return}//调用增加管理员微服务方法:执行增加管理员addResult, _ := rbacClient.ManagerAdd(context.Background(), &pbManager.ManagerAddRequest{Username: username,Password: models.Md5(password),Email:    email,Mobile:   mobile,RoleId:   int64(roleId),Status:   1,AddTime:  int64(models.GetUnix()),})if !addResult.Success {con.Error(c, "添加管理员失败", "/admin/manager/add")return}con.Success(c, "增加管理员成功", "/admin/manager")
}//编辑管理员
func (con ManagerController) Edit(c *gin.Context) {//获取管理员id, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//通过管理员微服务获取管理员//获取管理员managerClient := pbManager.NewRbacManagerService("rbac", models.RbacClient)resManager, _ := managerClient.ManagerGet(context.Background(), &pbManager.ManagerGetRequest{Id: int64(id),})if len(resManager.ManagerList) <= 0  {con.Error(c, "管理员#" + models.String(id) + "不存在", "/admin/manager")return}//获取所有的角色roleClient := pbRole.NewRbacRoleService("rbac", models.RbacClient)resRole, _ := roleClient.RoleGet(context.Background(), &pbRole.RoleGetRequest{})c.HTML(http.StatusOK, "admin/manager/edit.html", gin.H{"manager":  resManager.ManagerList[0],"roleList": resRole.RoleList,})
}//编辑管理员提交
func (con ManagerController) DoEdit(c *gin.Context) {//获取管理员id,并判断id, err := models.Int(c.PostForm("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//获取角色id,并判断roleId, err2 := models.Int(c.PostForm("role_id"))if err2 != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//获取提交的表单信息username := strings.Trim(c.PostForm("username"), " ")password := strings.Trim(c.PostForm("password"), " ")email := strings.Trim(c.PostForm("email"), " ")mobile := strings.Trim(c.PostForm("mobile"), " ")//执行修改//判断电话号码是否合法if len(mobile) > 11 {con.Error(c, "mobile长度不合法", "/admin/manager/edit?id="+models.String(id))return}//注意:判断密码是否为空 为空表示不修改密码 不为空表示修改密码if password != "" {//判断密码长度是否合法if len(password) < 6 {con.Error(c, "密码的长度不合法 密码长度不能小于6位", "/admin/manager/edit?id="+models.String(id))return}password = models.Md5(password)}//调用管理员修改微服务方法进行修改managerClient := pbManager.NewRbacManagerService("rbac", models.RbacClient)editResult, _ := managerClient.ManagerEdit(context.Background(), &pbManager.ManagerEditRequest{Id:       int64(id),Username: username,Password: password,Email:    email,Mobile:   mobile,RoleId:   int64(roleId),})if !editResult.Success {con.Error(c, "修改数据失败", "/admin/manager/edit?id="+models.String(id))return}con.Success(c, "修改数据成功", "/admin/manager")
}//删除
func (con ManagerController) Delete(c *gin.Context) {//获取提交的表单数据id, err := models.Int(c.Query("id"))if err != nil {con.Error(c, "传入数据错误", "/admin/manager")return}//查询管理员是否存在//获取管理员managerClient := pbManager.NewRbacManagerService("rbac", models.RbacClient)resManager, _ := managerClient.ManagerGet(context.Background(), &pbManager.ManagerGetRequest{Id: int64(id),})if len(resManager.ManagerList) <= 0  {con.Error(c, "管理员#" + models.String(id) + "不存在", "/admin/manager")return}//调用管理员删除方法进行删除managerDeleteClient := pbManager.NewRbacManagerService("rbac", models.RbacClient)managerRes, _ := managerDeleteClient.ManagerDelete(context.Background(), &pbManager.ManagerDeleteRequest{Id: int64(id),})if managerRes.Success {con.Success(c, "删除数据成功", "/admin/manager")return}con.Success(c, "删除数据失败", "/admin/manager")
}

 三.校验权限管理Rbac管理员增删改查微服务功能

1.先启动服务端

见[golang gin框架] 40.Gin商城项目-微服务实战之Captcha验证码微服务代码, 这里还要启动验证码captcha微服务服务端代码以及权限管理Rbac微服务(用户登录微服务服务端,角色管理微服务服务端,管理员管理微服务服务端)服务端才行

2.启动客户端

在项目根目录下运行 :go run main.go,启动项目

3.校验权限管理Rbac管理员增删改查微服务操作是否成功 

访问后台登录页面,输入用户名,密码,验证码,登录到后台后,进入管理员管理页面,对管理员进行增删改查

 好了,权限管理Rbac管理员增删改查微服务功能客户端操作完成,这里微服务操作的服务端,客户端功能大致[golang gin框架] 42.Gin商城项目-微服务实战之后台Rbac微服务角色增删改查微服务类似,可参考该文章操作,下面一节继续讲解权限管理Rbac微服务之权限的增删改查

[上一节][golang gin框架] 42.Gin商城项目-微服务实战之后台Rbac微服务角色增删改查微服务

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

相关文章:

[golang gin框架] 43.Gin商城项目-微服务实战之后台Rbac微服务之管理员的增删改查以及管理员和角色关联

上一节讲解了后台Rbac微服务角色增删改查微服务,这里讲解权限管理Rbac微服务管理员的增删改查微服务以及管理员和角色关联微服务功能 一.实现后台权限管理Rbac之管理员增删改查微服务服务端功能 1.创建Manager模型 要实现管理员的增删改查,就需要创建对应的模型,故在server/r…...

2023-07-31力扣每日一题

链接&#xff1a; 143. 重排链表 题意&#xff1a; 将链表L0 → L1 → … → Ln - 1 → Ln变成L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 解&#xff1a; 线性表法还是好写的 这边搞一下翻转法&#xff0c;快慢指针求翻转点&#xff08;翻转后面一半然后双指针合并…...

接口自动化报告,生成本地服务并自动打开时失败

错误原因&#xff1a; 端口号被占用 首先可以在cmd中调出命令窗口然后执行命令netstat -ano就可以查看所有活动的链接&#xff0c;找到被占用的端口号 1、通过命令taskkill /f /t /im "进程名称" &#xff0c;根据进程的名称杀掉所有的进程。或者taskkill /f /t /p…...

Git 的基本概念和使用方式

Git 是一种分布式版本控制系统&#xff0c;它能够记录文件内容的变化&#xff0c;并且允许用户在这些变化之间轻松地进行切换。 Git 的基本概念如下&#xff1a; 1. 仓库&#xff08;Repository&#xff09;&#xff1a;Git 存放项目代码的地方。通常&#xff0c;一个仓库对应一…...

【JVM】(三) 深入理解JVM垃圾回收机制(GC)

文章目录 前言一、死亡对象的判断方法1.1 引用计数算法1.2 可达性分析算法 二、垃圾回收算法2.1 标记-清除算法2.2 复制算法2.3 标记-整理算法2.5 分代算法2.6 Minor GC 和 Major GC 前言 JVM 的垃圾回收机制&#xff08;Garbage Collection&#xff09;是 Java 中的重要特性之…...

Flink CEP(二) 运行源码解析

通过DemoApp学习一下&#xff0c;CEP的源码执行逻辑。为下一篇实现CEP动态Pattern奠定理论基础。 1. Pattern的定义 Pattern<Tuple3<String, Long, String>,?> pattern Pattern.<Tuple3<String, Long, String>>begin("begin").where(new…...

剑指Offer-学习计划(四)双指针(下)

剑指 Offer 57. 和为s的两个数字 剑指 Offer 58 - I. 翻转单词顺序 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 题目一&#xff1a;调整数组顺序使奇数位于偶数前面 输入一个整数数组&#xff0c;实现一个函数来调整该数组中数字的顺序&#xff0c;使得所有奇数在数组的…...

深度学习——常见注意力机制

1.SENet SENet属于通道注意力机制。2017年提出&#xff0c;是imageNet最后的冠军 SENet采用的方法是对于特征层赋予权值。 重点在于如何赋权 1.将输入信息的所有通道平均池化。 2.平均池化后进行两次全连接&#xff0c;第一次全连接链接的神经元较少&#xff0c;第二次全连…...

Python 进阶(七):高级文件操作(shutil 模块)

❤️ 博客主页&#xff1a;水滴技术 &#x1f338; 订阅专栏&#xff1a;Python 入门核心技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; 文章目录 1. 简介2. 常用函数2.1 复制文件2.2 复制目录2.3 移动文件或目录2.4 删除文件或目录2.…...

保留网络:大型语言模型的Transformer继任者

原文信息 原文题目&#xff1a;《Retentive Network: A Successor to Transformer for Large Language Models》 原文引用&#xff1a;Sun Y, Dong L, Huang S, et al. Retentive Network: A Successor to Transformer for Large Language Models[J]. arXiv preprint arXiv:2…...

算法通关村第二关——反转链表青铜笔记

LeetCode 206.反转链表 建立虚拟结点辅助翻转 public ListNode reverseList(ListNode head) {ListNode ans new ListNode(-1);ListNode cur head;while(cur!null){ListNode curNext cur.next;cur.next ans.next;ans.next cur;cur curNext;}return ans.next; }不带虚拟头…...

【Linux】——线程安全

目录 关于线程进程的问题 可重入与线程安全 常见的线程安全的情况 常见的不可重入的情况 常见的可重入的情况 可重入与线程安全区别 可重入与线程安全联系 Linux线程互斥 进程线程间的互斥相关概念 互斥量mutex 互斥量mutex常用接口 互斥量改造抢票系统 互斥量的原…...

[React]生命周期

前言 学习React&#xff0c;生命周期很重要&#xff0c;我们了解完生命周期的各个组件&#xff0c;对写高性能组件会有很大的帮助. Ract生命周期 React 生命周期分为三种状态 1. 初始化 2.更新 3.销毁 初始化 1、getDefaultProps() 设置默认的props&#xff0c;也可以用duf…...

【2023】Redis实现消息队列的方式汇总以及代码实现

Redis实现消息队列的方式汇总以及代码实现 前言开始前准备1、添加依赖2、添加配置的Bean 具体实现一、从最简单的开始&#xff1a;List 队列代码实现 二、发布订阅模式&#xff1a;Pub/Sub1、使用RedisMessageListenerContainer实现订阅2、还可以使用redisTemplate实现订阅 三、…...

ARM裸机-10

1、X210开发板和光盘资料 1.1、配置信息 CPU&#xff1a;三星S5PV210 内存&#xff1a;512M DDR2 SDRAM Flash&#xff1a;4GB iBand LCD&#xff1a;7寸&#xff0c;分辨率800x480 触摸屏&#xff1a;电容触摸屏 2、X210开发板硬件手册 3、X210开发板刷系统 3.1、什么是刷…...

「C/C++」C/C++指针详解

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C」C/C程序设计「Win」Windows程序设计「算法」数据结构与算法「File」数据文件格式 目录 一、术语…...

提高电脑寿命的维护技巧与方法分享

在维护电脑运行方面&#xff0c;我有一些自己觉得非常有用的技巧和方法。下面我将分享一些我常用的维护技巧&#xff0c;并解释为什么我会选择这样做以及这样做的好处。 首先&#xff0c;我经常清理我的电脑内部的灰尘。电脑内部的灰尘会影响散热效果&#xff0c;导致电脑发热…...

React常见面试题

React常见面试题 一、React中的样式管理有哪些方法 内联样式&#xff1a;对象&#xff0c;作用于当前组件普通样式表&#xff1a; 作用于全局&#xff0c;文件名是&#xff1a;xxx.scssCSS模块&#xff1a;类似Vue的scoped&#xff0c; 文件名需是&#xff1a;xxx.module.scs…...

C++中数据的输入输出介绍

C中数据的输入输出介绍 C中数据的输入输出涉及到的文件 <iostream>&#xff1a;这是C标准库中最常用的头文件之一&#xff0c;包含了进行标准输入输出操作的类和对象&#xff0c;如std::cin、std::cout、std::endl等。 <iomanip>&#xff1a;该头文件提供了一些用…...

0101日志-运维-mysql

1 错误日志 错误日志&#xff08;Error Log&#xff09;&#xff1a;错误日志记录了MySQL引擎在运行过程中出现的错误和异常情况。这些错误可能包括启动和关闭问题、数据库崩溃、权限问题等。错误日志对于排查和解决MySQL引擎问题非常有帮助。 改日志默认开启&#xff0c;默认存…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...