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

news2024/11/17 0:40:17

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

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

1.创建Manager模型 

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

package models

//管理员表

type Manager struct { // 结构体首字母大写, 和数据库表名对应, 默认访问数据表users, 可以设置访问数据表的方法
	Id  int
	Username string
	Password string
	Mobile string
	Email string
	Status int
	RoleId int
	AddTime int
	IsSuper int
	Role 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, 响应参数ManagerGetResponse
    rpc ManagerGet(ManagerGetRequest) returns (ManagerGetResponse) {}
    //增加管理员rpc方法: 请求参数ManagerAddRequest, 响应参数ManagerAddResponse
    rpc ManagerAdd(ManagerAddRequest) returns (ManagerAddResponse) {}
    //编辑管理员rpc方法: 请求参数ManagerEditRequest, 响应参数ManagerEditResponse
    rpc ManagerEdit(ManagerEditRequest) returns (ManagerEditResponse) {}
    //删除管理员rpc方法: 请求参数ManagerDeleteRequest, 响应参数ManagerDeleteResponse
    rpc 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 handler

import (
	"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.ManagerModel
	for _, 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 = tempList
	return 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).Error
	if err != nil {
		res.Success = false
		res.Message = "增加数据失败"
	} else {
		res.Success = true
		res.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.Username
	manager.Email = req.Email
	manager.Mobile = req.Mobile
	manager.RoleId = int(req.RoleId)

	//注意:判断密码是否为空 为空表示不修改密码 不为空表示修改密码
	if req.Password != "" {
		manager.Password = req.Password
	}
	err := models.DB.Save(&manager).Error
	if err != nil {
		res.Success = false
		res.Message = "修改数据失败"
	} else {
		res.Success = true
		res.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).Error
	if err != nil {
		res.Success = false
		res.Message = "删除数据失败"
	} else {
		res.Success = true
		res.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 main

import (
	"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() {
	//集成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)
	}
	// Run service
	if 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 admin

import (
	"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).Error
	if 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 = username
	manager.Email = email
	manager.RoleId = roleId
	manager.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).Error
	if 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).Error
	if 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).Error
	if 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 = username
	manager.Email = email
	manager.RoleId = roleId
	manager.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).Error
	if 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).Error
	if 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 admin

import (
	"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微服务之权限的增删改查微服务

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

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

相关文章

使用Beego和MySQL实现帖子和评论的应用,并进行接口测试(附源码和代码深度剖析)

文章目录 小项目介绍源码分析main.gorouter.gomodels/user.gomodels/Post.gomodels/comment.gocontrollers/post.gocontrollers/comment.go 接口测试测试增加帖子测试查看帖子测试增加评论测试查看评论 小项目介绍 经过对需求的分析&#xff0c;我增加了一些额外的东西&#x…

Linux学习之脚本优先级控制

fork炸弹 在编写Shell脚本时不要写出不可控的死循环&#xff0c;比如func() { func | func& } ; func&#xff0c;简写版为.(){ .|.& };.。接下来见证一下这两条语句的威力。因为在root用户下许多资源没有限制&#xff0c;所以useradd userfork新建一个用户userfork&a…

fwrite函数

1、函数声明 size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream ); 2、参数说明 buffer 指向要写入的数据的指针。 size 项大小&#xff08;以字节为单位&#xff09;。 count 要写入的项的最大数量。 stream 指向 FILE 结构的指针。 3、…

OpenCloudOS 与PolarDB全面适配

近日&#xff0c;OpenCloudOS 开源社区签署阿里巴巴开源 CLA (Contribution License Agreement, 贡献许可协议), 正式与阿里云 PolarDB 开源数据库社区牵手&#xff0c;并展开 OpenCloudOS &#xff08;V8&#xff09;与阿里云开源云原生数据库 PolarDB 分布式版、开源云原生数…

AD21原理图的高级应用(四)线束的设计及应用

&#xff08;四&#xff09;线束的设计及应用 Altium Designer 21 可以使用 Signal Harnesses(信号线束)的方法来建立元件之间的连接,也可用于不同原理图间的信号对接。信号线束是一种抽象连接,操作方式类似于总线,但信号线束可对包括总线、导线和其他信号线束在内的不同信号进…

el-button增加下载功能

vue3和element-plus <el-uploadv-model:file-list="fileList"action="/api/upload"multiple:limit="1":headers="headers" ><el-button type="primary">选择文件</el-button><template #file

【前缀和】560.和为 K 的子数组

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 和为K的子数组 题目:示例:题解&#xff1a;解法一:解法二: 题目: 示例: 题解&#xff1a; 解法一: 暴力解法:我们很容易想到通过两个for循环去遍…

【使用 DSP 滤波器加速速度和位移】使用信号处理算法过滤加速度数据并将其转换为速度和位移研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

操作系统理论:Linux进程与进程状态(进程调度的大O(1)算法数据结构模型)

文章目录 一.进程的基本概念进程间的基本关系:父子关系 二.进程状态(1)进程的运行状态RLinux进程调度的大O(1)算法数据结构模型(运行队列哈希桶):进程的运行时间片 (2)进程的睡眠状态(S和D)(3)进程的僵尸状态和死亡状态 一.进程的基本概念 冯诺依曼体系的计算机在运行时,内存中…

基于C语言 --- 自己写一个三子棋小游戏

C语言程序设计笔记---019 初阶三子棋小游戏(开源)1、arr_main.c程序大纲2、arr_game1.h3、arr_game1.c3.1、 自定义初识化函数 InitBoard( ) 和 自定义显示函数 DisPlayBoard( )3.2、 自定义玩家下棋函数 PlayerMove( )3.4、 自定义电脑下棋函数 ComputerMove( )3.5、 输赢判断…

成为一名黑客(网络安全),需要掌握哪些黑客技能?

前言 黑客技能是一项非常复杂和专业的技能&#xff0c;需要广泛的计算机知识和网络安全知识。你可以参考下面一些学习步骤&#xff0c;系统自学网络安全。 在学习之前&#xff0c;要给自己定一个目标或者思考一下要达到一个什么样的水平&#xff0c;是学完找工作&#xff08;…

使用DataX实现mysql与hive数据互相导入导出

一、概论 1.1 什么是DataX DataX 是阿里巴巴开源的一个异构数据源离线同步工具&#xff0c;致力于实现包括关系型数据库(MySQL、Oracle 等)、HDFS、Hive、ODPS、HBase、FTP 等各种异构数据源之间稳定高效的数据同步功能。 1.2 DataX 的设计 为了解决异构数据源同步问题&#xf…

【外卖系统】分类管理业务

公共字段自动填充 需求分析 对于之前的开发中&#xff0c;有创建时间、创建人、修改时间、修改人等字段&#xff0c;在其他功能中也会有出现&#xff0c;属于公共字段&#xff0c;对于这些公共字段最好是在某个地方统一处理以简化开发&#xff0c;使用Mybatis Plus提供的公共…

简单记录牛客top101算法题(初级题C语言实现)判断回文字符串 反转字符串 合并两个有序的数组

1. 判断是否为回文字符串 给定一个长度为 n 的字符串&#xff0c;请编写一个函数判断该字符串是否回文。如果是回文请返回true&#xff0c;否则返回false。   字符串回文指该字符串正序与其逆序逐字符一致。 //示例 输入&#xff1a;"ranko" 返回值&#xff1a;fa…

DevOps系列文章之 自动化测试大全(单测和集成测试)

自动化测试业界主流工具 核心目标&#xff1a; 主要是功能测试和覆盖率测试 业界常用主流工具 GoogleTest GoogleTest是一个跨平台的(Liunx、Mac OS X、Windows 、Cygwin 、Windows CE and Symbian ) C单元测试框架&#xff0c;由google公司发布&#xff0c;为在不同平台上为编…

案例:缺陷个数与返工工作量强相关

某公司积累了21个项目缺陷个数与返工工作量的数据&#xff0c;如下表所示&#xff1a; 项目序号缺陷修复工时缺陷数1943314452299040536347446471385496071061370246774066812232189276652810830213781162678126111511381110514209032015144023516516078417710010301875601239…

3.Makefile变量的用法(附示例)

一、本节概要 本专栏所有内容围绕Makefile官方文档进行刨析,给出详细具体示例做辅助理解手撕Makefile官方手册 二、Makefile中的变量 1、没有使用变量的makefile 以下是不使用变量的makefile完整示例: edit: main.o kbd.o command.o display.o insert.o search.o files…

django channels实战(websocket底层原理和案例)

1、websocket相关 1.1、轮询 1.2、长轮询 1.3、websocket 1.3.1、websocket原理 1.3.2、django框架 asgi.py在django项目同名app目录下 1.3.3、聊天室 django代码总结 小结 1.3.4、群聊&#xff08;一&#xff09; 前端代码 后端代码 1.3.5、群聊&#xff08;二&#xff09…

网络编程 IO多路复用 [epoll版] (TCP网络聊天室)

//head.h 头文件 //TcpGrpSer.c 服务器端 //TcpGrpUsr.c 客户端 通过IO多路复用实现服务器在单进程单线程下可以与多个客户端交互 API epoll函数 #include<sys/epoll.h> int epoll_create(int size); 功能&#xff1a;创建一个epoll句柄//创建红黑树根…

TypeScript算法题实战——剑指 Offer篇(5)

目录 一、平衡二叉树1.1、题目描述1.2、题解 二、数组中数字出现的次数2.1、题目描述2.2、题解 三、数组中数字出现的次数 II3.1、题目描述3.2、题解 四、和为s的两个数字4.1、题目描述4.2、题解 五、和为s的连续正数序列5.1、题目描述5.2、题解 六、翻转单词顺序6.1、题目描述…