本文最后更新于 2024-08-19,文章内容距离上一次更新已经过去了很久啦,可能已经过时了,请谨慎参考喵。

前情提要

https://blog.imbhj.com/archives/fsaSCzwqhttps://blog.imbhj.com/archives/VePoGk3D

新增角色

首先呢,还是进行表创建,结构如下:

CREATE TABLE `sys_role` (
    `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
    `role_name` varchar(64) NOT NULL COMMENT '角色名称',
    `role_key` varchar(64) NOT NULL COMMENT '角色权限字符串',
    `status` int(11) NOT NULL DEFAULT '1' COMMENT '启用状态:1-启用;2-禁用',
    `description` varchar(500) DEFAULT NULL COMMENT '描述',
    `create_time` datetime NOT NULL COMMENT '创建时间',
    PRIMARY KEY (`id`) USING BTREE,
    KEY `name` (`role_name`) USING BTREE,
    KEY `create_time` (`create_time`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='后台角色表';

实际上Navicat16的执行结果:

2951376083.png

创建角色表的结构体 /model/sysRole.go

// 角色相关模型
// @author DaBaiLuoBo

package model

import "goblog-admin/utils"

// SysRole 角色相关模型
type SysRole struct {
    ID          uint        `gorm:"column:id;comment:'主键';primaryKey;NOT NULL" json:"id"`                      // ID
    RoleName    string      `gorm:"column:role_name;varchar(64);comment:'角色名称';NOT NULL" json:"roleName"`      // 角色名称
    RoleKey     string      `gorm:"column:role_key;varchar(64);comment:'权限字符串';NOT NULL" json:"roleKey"`       // 权限字符串
    Status      int         `gorm:"column:status;default:1;comment:'账号启用状态:1-启用;2-禁用';NOT NULL" json:"status"` // 账号启用状态:1-启用;2-禁用
    Description string      `gorm:"column:description;varchar(500);comment:'描述';NOT NULL" json:"description"`  // 描述
    CreatTime   utils.HTime `gorm:"column:create_time;comment:'创建时间'" json:"createTime"`                       // 创建时间
}

func (SysRole) TableName() string {
    return "sys_role"
}

// AddSysRoleDto 新增角色参数
type AddSysRoleDto struct {
    RoleName    string `json:"roleName"`    // 角色名称
    RoleKey     string `json:"roleKey"`     // 权限字符串
    Status      int    `json:"status"`      // 账号启用状态:1-启用;2-禁用
    Description string `json:"description"` // 描述
}

然后创建角色接口 /api/sysRole.go

// 角色相关接口
// @author DaBaiLuoBo

package api

import (
    "github.com/gin-gonic/gin"
    "goblog-admin/core"
    "goblog-admin/model"
    "goblog-admin/result"
    "goblog-admin/utils"
    "time"
)

// CreateSysRole 新增角色
// @Summary 新增角色
// @Tags 角色相关接口
// @Produce json
// @Description 新增角色
// @Param data body model.AddSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/add [post]
func CreateSysRole(c *gin.Context) {
    var dto model.AddSysRoleDto
    _ = c.BindJSON(&dto)
    sysRoleByName := GetSysRoleByName(dto.RoleName)
    if sysRoleByName.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    sysRoleByKey := GetSysRoleByKey(dto.RoleKey)
    if sysRoleByKey.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    // 新增角色
    addSysRole := model.SysRole{
        RoleName:    dto.RoleName,
        RoleKey:     dto.RoleKey,
        Description: dto.Description,
        Status:      dto.Status,
        CreatTime:   utils.HTime{Time: time.Now()},
    }
    // 判断是否操作成功
    tx := core.Db.Create(&addSysRole)
    if tx.RowsAffected > 0 {
        result.Success(c, true)
        return
    } else {
        result.Failed(c, int(result.ApiCode.Failed), result.ApiCode.GetMessage(result.ApiCode.Failed))
        return
    }
}

// GetSysRoleByName 根据角色名称查询角色数据
func GetSysRoleByName(roleName string) (sysRole model.SysRole) {
    core.Db.Where("role_name = ?", roleName).First(&sysRole)
    return sysRole
}

// GetSysRoleByKey 根据角色Key查询角色数据
func GetSysRoleByKey(roleKey string) (sysRole model.SysRole) {
    core.Db.Where("role_key = ?", roleKey).First(&sysRole)
    return sysRole
}

再在 /result/code.go 中定义新增加的状态码:

// 状态码/状态信息
// @author DaiBaiLuoBo

package result

// Codes 定义状态
type Codes struct {
    Message               map[uint]string
    Success               uint
    Failed                uint
    SysMenuIsExist        uint
    DelSysMenuFailed      uint
    DelSysChildMenuFailed uint
    RoleAlreadExists      uint
}

// ApiCode 状态码
var ApiCode = &Codes{
    Success:               200,
    Failed:                501,
    SysMenuIsExist:        600,
    DelSysMenuFailed:      601,
    DelSysChildMenuFailed: 602,
    RoleAlreadExists:      603,
}

// 状态信息初始化
func init() {
    ApiCode.Message = map[uint]string{
        ApiCode.Success:               "成功",
        ApiCode.Failed:                "失败",
        ApiCode.SysMenuIsExist:        "菜单名称已存在,请重新输入",
        ApiCode.DelSysMenuFailed:      "菜单已分配,不能删除",
        ApiCode.DelSysChildMenuFailed: "该菜单存在子菜单,不能删除",
        ApiCode.RoleAlreadExists:      "角色名或角色Key已存在,请重新输入",
    }
}

// GetMessage 供给外部调用状态信息
func (c *Codes) GetMessage(code uint) string {
    message, ok := c.Message[code]
    // 如果不 ok,返回空,ok 则返回 message
    if !ok {
        return ""
    }
    return message
}

然后就是在路由 /router/router.go 中增加路由啦:

// 路由初始化以及注册
// @author DaBaiLuoBo

package router

import (
    "github.com/gin-gonic/gin"
    swaggerFiles "github.com/swaggo/files"
    ginSwagger "github.com/swaggo/gin-swagger"
    "goblog-admin/api"
    "goblog-admin/config"
)

// InitRouter 初始化先拿到Gin框架
func InitRouter() *gin.Engine {
    // 设置启动模式
    gin.SetMode(config.Config.System.Env)
    // 新建路由
    router := gin.New()
    // 设置跌机时恢复
    router.Use(gin.Recovery())
    // Register 注册
    register(router)
    // 返回路由
    return router
}

// Register 路由接口
func register(router *gin.Engine) {
    // todo 后续的所有接口 url 将在此配置
    router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
    router.GET("/api/success", api.Success)
    router.GET("/api/failed", api.Failed)
    router.POST("/api/sysMenu/add", api.CreateSysMenu)
    router.GET("/api/sysMenu/list", api.GetSysMenuList)
    router.GET("/api/sysMenu/info", api.GetSysMenu)
    router.PUT("/api/sysMenu/update", api.UpdateSysMenu)
    router.DELETE("/api/sysMenu/delete", api.DeleteSysMenu)
    router.POST("/api/sysRole/add", api.CreateSysRole)
}

初始化swag,启动项目,测试一下:

1792428567.png

4270121128.png

查询角色列表

/api/sysRole.go 文件中:

// 角色相关接口
// @author DaBaiLuoBo

package api

import (
    "github.com/gin-gonic/gin"
    "goblog-admin/core"
    "goblog-admin/model"
    "goblog-admin/result"
    "goblog-admin/utils"
    "strconv"
    "time"
)

// CreateSysRole 新增角色
// @Summary 新增角色
// @Tags 角色相关接口
// @Produce json
// @Description 新增角色
// @Param data body model.AddSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/add [post]
func CreateSysRole(c *gin.Context) {
    var dto model.AddSysRoleDto
    _ = c.BindJSON(&dto)
    sysRoleByName := GetSysRoleByName(dto.RoleName)
    if sysRoleByName.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    sysRoleByKey := GetSysRoleByKey(dto.RoleKey)
    if sysRoleByKey.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    // 新增角色
    addSysRole := model.SysRole{
        RoleName:    dto.RoleName,
        RoleKey:     dto.RoleKey,
        Description: dto.Description,
        Status:      dto.Status,
        CreatTime:   utils.HTime{Time: time.Now()},
    }
    // 判断是否操作成功
    tx := core.Db.Create(&addSysRole)
    if tx.RowsAffected > 0 {
        result.Success(c, true)
        return
    } else {
        result.Failed(c, int(result.ApiCode.Failed), result.ApiCode.GetMessage(result.ApiCode.Failed))
        return
    }
}

// GetSysRoleList 分页查询角色列表
// @Summary 分页查询角色列表
// @Tags 角色相关接口
// @Produce json
// @Description 分页查询角色列表
// @Param pageNum query int false "分页数"
// @Param pageSize query int false "每页数"
// @Param roleName query string false "角色名称"
// @Param status query string false "账号启用状态:1-启用;2-禁用"
// @Param beginTime query string false "开始时间"
// @Param endTime query string false "结束时间"
// @Success 200 {object} result.Result
// @router /api/sysRole/list [get]
func GetSysRoleList(c *gin.Context) {
    PageNum, _ := strconv.Atoi(c.Query("pageNum"))
    PageSize, _ := strconv.Atoi(c.Query("pageSize"))
    RoleName := c.Query("roleName")
    Status := c.Query("status")
    BeginTime := c.Query("beginTime")
    EndTime := c.Query("endTime")
    if PageSize < 1 {
        PageSize = 10
    }
    if PageNum < 1 {
        PageNum = 1
    }
    var sysRoles []model.SysRole
    var count int64
    curDb := core.Db.Table("sys_role")
    if RoleName != "" {
        curDb = curDb.Where("role_name = ?", RoleName)
    }
    if BeginTime != "" && EndTime != "" {
        curDb = curDb.Where("create_time BETWEEN ? AND ?", BeginTime, EndTime)
    }
    if Status != "" {
        curDb = curDb.Where("status = ?", Status)
    }
    curDb.Count(&count).Limit(PageSize).Offset((PageNum - 1) * PageSize).Order("create_time DESC").Find(&sysRoles)
    result.Success(c, map[string]interface{}{"total": count, "pageSize": PageSize, "pageNum": PageNum, "list": sysRoles})
}

// GetSysRoleByName 根据角色名称查询角色数据
func GetSysRoleByName(roleName string) (sysRole model.SysRole) {
    core.Db.Where("role_name = ?", roleName).First(&sysRole)
    return sysRole
}

// GetSysRoleByKey 根据角色Key查询角色数据
func GetSysRoleByKey(roleKey string) (sysRole model.SysRole) {
    core.Db.Where("role_key = ?", roleKey).First(&sysRole)
    return sysRole
}

再把路由加进去 /router/router.go

router.GET("/api/sysRole/list", api.GetSysRoleList)

然后初始化swag,再运行项目测试一下:

2276302147.png

查询修改角色

先在 /model/sysRole.go 中定义结构体:

// 角色相关模型
// @author DaBaiLuoBo

package model

import "goblog-admin/utils"

// SysRole 角色相关模型
type SysRole struct {
    ID          uint        `gorm:"column:id;comment:'主键';primaryKey;NOT NULL" json:"id"`                      // ID
    RoleName    string      `gorm:"column:role_name;varchar(64);comment:'角色名称';NOT NULL" json:"roleName"`      // 角色名称
    RoleKey     string      `gorm:"column:role_key;varchar(64);comment:'权限字符串';NOT NULL" json:"roleKey"`       // 权限字符串
    Status      int         `gorm:"column:status;default:1;comment:'账号启用状态:1-启用;2-禁用';NOT NULL" json:"status"` // 账号启用状态:1-启用;2-禁用
    Description string      `gorm:"column:description;varchar(500);comment:'描述';NOT NULL" json:"description"`  // 描述
    CreatTime   utils.HTime `gorm:"column:create_time;comment:'创建时间'" json:"createTime"`                       // 创建时间
}

func (SysRole) TableName() string {
    return "sys_role"
}

// AddSysRoleDto 新增角色参数
type AddSysRoleDto struct {
    RoleName    string `json:"roleName"`    // 角色名称
    RoleKey     string `json:"roleKey"`     // 权限字符串
    Status      int    `json:"status"`      // 账号启用状态:1-启用;2-禁用
    Description string `json:"description"` // 描述
}

// UpdateSysRoleDto 新增角色参数
type UpdateSysRoleDto struct {
    ID          uint   `json:"id"`          // ID
    RoleName    string `json:"roleName"`    // 角色名称
    RoleKey     string `json:"roleKey"`     // 权限字符串
    Status      int    `json:"status"`      // 账号启用状态:1-启用;2-禁用
    Description string `json:"description"` // 描述
}

// SysRoleIdDto ID参数
type SysRoleIdDto struct {
    ID uint `json:"id"` // ID
}

再回到 /api/sysRole.go 中写api:

// 角色相关接口
// @author DaBaiLuoBo

package api

import (
    "github.com/gin-gonic/gin"
    "goblog-admin/core"
    "goblog-admin/model"
    "goblog-admin/result"
    "goblog-admin/utils"
    "strconv"
    "time"
)

// CreateSysRole 新增角色
// @Summary 新增角色
// @Tags 角色相关接口
// @Produce json
// @Description 新增角色
// @Param data body model.AddSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/add [post]
func CreateSysRole(c *gin.Context) {
    var dto model.AddSysRoleDto
    _ = c.BindJSON(&dto)
    sysRoleByName := GetSysRoleByName(dto.RoleName)
    if sysRoleByName.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    sysRoleByKey := GetSysRoleByKey(dto.RoleKey)
    if sysRoleByKey.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    // 新增角色
    addSysRole := model.SysRole{
        RoleName:    dto.RoleName,
        RoleKey:     dto.RoleKey,
        Description: dto.Description,
        Status:      dto.Status,
        CreatTime:   utils.HTime{Time: time.Now()},
    }
    // 判断是否操作成功
    tx := core.Db.Create(&addSysRole)
    if tx.RowsAffected > 0 {
        result.Success(c, true)
        return
    } else {
        result.Failed(c, int(result.ApiCode.Failed), result.ApiCode.GetMessage(result.ApiCode.Failed))
        return
    }
}

// GetSysRoleList 分页查询角色列表
// @Summary 分页查询角色列表
// @Tags 角色相关接口
// @Produce json
// @Description 分页查询角色列表
// @Param pageNum query int false "分页数"
// @Param pageSize query int false "每页数"
// @Param roleName query string false "角色名称"
// @Param status query string false "账号启用状态:1-启用;2-禁用"
// @Param beginTime query string false "开始时间"
// @Param endTime query string false "结束时间"
// @Success 200 {object} result.Result
// @router /api/sysRole/list [get]
func GetSysRoleList(c *gin.Context) {
    PageNum, _ := strconv.Atoi(c.Query("pageNum"))
    PageSize, _ := strconv.Atoi(c.Query("pageSize"))
    RoleName := c.Query("roleName")
    Status := c.Query("status")
    BeginTime := c.Query("beginTime")
    EndTime := c.Query("endTime")
    if PageSize < 1 {
        PageSize = 10
    }
    if PageNum < 1 {
        PageNum = 1
    }
    var sysRoles []model.SysRole
    var count int64
    curDb := core.Db.Table("sys_role")
    if RoleName != "" {
        curDb = curDb.Where("role_name = ?", RoleName)
    }
    if BeginTime != "" && EndTime != "" {
        curDb = curDb.Where("create_time BETWEEN ? AND ?", BeginTime, EndTime)
    }
    if Status != "" {
        curDb = curDb.Where("status = ?", Status)
    }
    curDb.Count(&count).Limit(PageSize).Offset((PageNum - 1) * PageSize).Order("create_time DESC").Find(&sysRoles)
    result.Success(c, map[string]interface{}{"total": count, "pageSize": PageSize, "pageNum": PageNum, "list": sysRoles})
}

// GetSysRole 根据ID查询角色
// @Summary 根据ID查询角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID查询角色
// @Param id query int true "角色ID"
// @Success 200 {object} result.Result
// @router /api/sysRole/info [get]
func GetSysRole(c *gin.Context) {
    Id, _ := strconv.Atoi(c.Query("id"))
    var sysRole model.SysRole
    core.Db.First(&sysRole, Id)
    result.Success(c, sysRole)
}

// GetSysRoleByName 根据角色名称查询角色数据
func GetSysRoleByName(roleName string) (sysRole model.SysRole) {
    core.Db.Where("role_name = ?", roleName).First(&sysRole)
    return sysRole
}

// GetSysRoleByKey 根据角色Key查询角色数据
func GetSysRoleByKey(roleKey string) (sysRole model.SysRole) {
    core.Db.Where("role_key = ?", roleKey).First(&sysRole)
    return sysRole
}

再加入路由 /router/router.go

router.GET("/api/sysRole/info", api.GetSysRole)

初始化swag,测试:

这里是为了严谨,新增一个接口测试一个接口

再返回 /api/sysRole.go 中继续写update的接口:

// 角色相关接口
// @author DaBaiLuoBo

package api

import (
    "github.com/gin-gonic/gin"
    "goblog-admin/core"
    "goblog-admin/model"
    "goblog-admin/result"
    "goblog-admin/utils"
    "strconv"
    "time"
)

// CreateSysRole 新增角色
// @Summary 新增角色
// @Tags 角色相关接口
// @Produce json
// @Description 新增角色
// @Param data body model.AddSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/add [post]
func CreateSysRole(c *gin.Context) {
    var dto model.AddSysRoleDto
    _ = c.BindJSON(&dto)
    sysRoleByName := GetSysRoleByName(dto.RoleName)
    if sysRoleByName.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    sysRoleByKey := GetSysRoleByKey(dto.RoleKey)
    if sysRoleByKey.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    // 新增角色
    addSysRole := model.SysRole{
        RoleName:    dto.RoleName,
        RoleKey:     dto.RoleKey,
        Description: dto.Description,
        Status:      dto.Status,
        CreatTime:   utils.HTime{Time: time.Now()},
    }
    // 判断是否操作成功
    tx := core.Db.Create(&addSysRole)
    if tx.RowsAffected > 0 {
        result.Success(c, true)
        return
    } else {
        result.Failed(c, int(result.ApiCode.Failed), result.ApiCode.GetMessage(result.ApiCode.Failed))
        return
    }
}

// GetSysRoleList 分页查询角色列表
// @Summary 分页查询角色列表
// @Tags 角色相关接口
// @Produce json
// @Description 分页查询角色列表
// @Param pageNum query int false "分页数"
// @Param pageSize query int false "每页数"
// @Param roleName query string false "角色名称"
// @Param status query string false "账号启用状态:1-启用;2-禁用"
// @Param beginTime query string false "开始时间"
// @Param endTime query string false "结束时间"
// @Success 200 {object} result.Result
// @router /api/sysRole/list [get]
func GetSysRoleList(c *gin.Context) {
    PageNum, _ := strconv.Atoi(c.Query("pageNum"))
    PageSize, _ := strconv.Atoi(c.Query("pageSize"))
    RoleName := c.Query("roleName")
    Status := c.Query("status")
    BeginTime := c.Query("beginTime")
    EndTime := c.Query("endTime")
    if PageSize < 1 {
        PageSize = 10
    }
    if PageNum < 1 {
        PageNum = 1
    }
    var sysRoles []model.SysRole
    var count int64
    curDb := core.Db.Table("sys_role")
    if RoleName != "" {
        curDb = curDb.Where("role_name = ?", RoleName)
    }
    if BeginTime != "" && EndTime != "" {
        curDb = curDb.Where("create_time BETWEEN ? AND ?", BeginTime, EndTime)
    }
    if Status != "" {
        curDb = curDb.Where("status = ?", Status)
    }
    curDb.Count(&count).Limit(PageSize).Offset((PageNum - 1) * PageSize).Order("create_time DESC").Find(&sysRoles)
    result.Success(c, map[string]interface{}{"total": count, "pageSize": PageSize, "pageNum": PageNum, "list": sysRoles})
}

// GetSysRole 根据ID查询角色
// @Summary 根据ID查询角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID查询角色
// @Param id query int true "角色ID"
// @Success 200 {object} result.Result
// @router /api/sysRole/info [get]
func GetSysRole(c *gin.Context) {
    Id, _ := strconv.Atoi(c.Query("id"))
    var sysRole model.SysRole
    core.Db.First(&sysRole, Id)
    result.Success(c, sysRole)
}

// UpdateSysRole 修改角色信息
// @Summary 修改角色信息
// @Tags 角色相关接口
// @Produce json
// @Description 修改角色信息
// @Param data body model.UpdateSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/update [put]
func UpdateSysRole(c *gin.Context) {
    var dto model.UpdateSysRoleDto
    _ = c.BindJSON(&dto)
    var sysRole model.SysRole
    core.Db.First(&sysRole, dto.ID)
    sysRole.RoleName = dto.RoleName
    sysRole.RoleKey = dto.RoleKey
    sysRole.Status = dto.Status
    if dto.Description != "" {
        sysRole.Description = dto.Description
    }
    core.Db.Save(&sysRole)
    result.Success(c, true)
}

// GetSysRoleByName 根据角色名称查询角色数据
func GetSysRoleByName(roleName string) (sysRole model.SysRole) {
    core.Db.Where("role_name = ?", roleName).First(&sysRole)
    return sysRole
}

// GetSysRoleByKey 根据角色Key查询角色数据
func GetSysRoleByKey(roleKey string) (sysRole model.SysRole) {
    core.Db.Where("role_key = ?", roleKey).First(&sysRole)
    return sysRole
}

再加入路由 /router/router.go

router.PUT("/api/sysRole/update", api.UpdateSysRole)

初始化swag,测试一下:

删除角色

首先在 /api/sysRole.go 中写删除角色的逻辑:

// 角色相关接口
// @author DaBaiLuoBo

package api

import (
    "github.com/gin-gonic/gin"
    "goblog-admin/core"
    "goblog-admin/model"
    "goblog-admin/result"
    "goblog-admin/utils"
    "strconv"
    "time"
)

// CreateSysRole 新增角色
// @Summary 新增角色
// @Tags 角色相关接口
// @Produce json
// @Description 新增角色
// @Param data body model.AddSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/add [post]
func CreateSysRole(c *gin.Context) {
    var dto model.AddSysRoleDto
    _ = c.BindJSON(&dto)
    sysRoleByName := GetSysRoleByName(dto.RoleName)
    if sysRoleByName.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    sysRoleByKey := GetSysRoleByKey(dto.RoleKey)
    if sysRoleByKey.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    // 新增角色
    addSysRole := model.SysRole{
        RoleName:    dto.RoleName,
        RoleKey:     dto.RoleKey,
        Description: dto.Description,
        Status:      dto.Status,
        CreatTime:   utils.HTime{Time: time.Now()},
    }
    // 判断是否操作成功
    tx := core.Db.Create(&addSysRole)
    if tx.RowsAffected > 0 {
        result.Success(c, true)
        return
    } else {
        result.Failed(c, int(result.ApiCode.Failed), result.ApiCode.GetMessage(result.ApiCode.Failed))
        return
    }
}

// GetSysRoleList 分页查询角色列表
// @Summary 分页查询角色列表
// @Tags 角色相关接口
// @Produce json
// @Description 分页查询角色列表
// @Param pageNum query int false "分页数"
// @Param pageSize query int false "每页数"
// @Param roleName query string false "角色名称"
// @Param status query string false "账号启用状态:1-启用;2-禁用"
// @Param beginTime query string false "开始时间"
// @Param endTime query string false "结束时间"
// @Success 200 {object} result.Result
// @router /api/sysRole/list [get]
func GetSysRoleList(c *gin.Context) {
    PageNum, _ := strconv.Atoi(c.Query("pageNum"))
    PageSize, _ := strconv.Atoi(c.Query("pageSize"))
    RoleName := c.Query("roleName")
    Status := c.Query("status")
    BeginTime := c.Query("beginTime")
    EndTime := c.Query("endTime")
    if PageSize < 1 {
        PageSize = 10
    }
    if PageNum < 1 {
        PageNum = 1
    }
    var sysRoles []model.SysRole
    var count int64
    curDb := core.Db.Table("sys_role")
    if RoleName != "" {
        curDb = curDb.Where("role_name = ?", RoleName)
    }
    if BeginTime != "" && EndTime != "" {
        curDb = curDb.Where("create_time BETWEEN ? AND ?", BeginTime, EndTime)
    }
    if Status != "" {
        curDb = curDb.Where("status = ?", Status)
    }
    curDb.Count(&count).Limit(PageSize).Offset((PageNum - 1) * PageSize).Order("create_time DESC").Find(&sysRoles)
    result.Success(c, map[string]interface{}{"total": count, "pageSize": PageSize, "pageNum": PageNum, "list": sysRoles})
}

// GetSysRole 根据ID查询角色
// @Summary 根据ID查询角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID查询角色
// @Param id query int true "角色ID"
// @Success 200 {object} result.Result
// @router /api/sysRole/info [get]
func GetSysRole(c *gin.Context) {
    Id, _ := strconv.Atoi(c.Query("id"))
    var sysRole model.SysRole
    core.Db.First(&sysRole, Id)
    result.Success(c, sysRole)
}

// UpdateSysRole 修改角色信息
// @Summary 修改角色信息
// @Tags 角色相关接口
// @Produce json
// @Description 修改角色信息
// @Param data body model.UpdateSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/update [put]
func UpdateSysRole(c *gin.Context) {
    var dto model.UpdateSysRoleDto
    _ = c.BindJSON(&dto)
    var sysRole model.SysRole
    core.Db.First(&sysRole, dto.ID)
    sysRole.RoleName = dto.RoleName
    sysRole.RoleKey = dto.RoleKey
    sysRole.Status = dto.Status
    if dto.Description != "" {
        sysRole.Description = dto.Description
    }
    core.Db.Save(&sysRole)
    result.Success(c, true)
}

// DeleteSysRole 根据ID删除角色
// @Summary 根据ID删除角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID删除角色
// @Param data body model.SysRoleIdDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/delete [delete]
func DeleteSysRole(c *gin.Context) {
    var dto model.SysRoleIdDto
    _ = c.BindJSON(&dto)
    core.Db.Table("sys_role").Delete(&model.SysRole{}, dto.ID)
    core.Db.Table("sys_role_menu").Where("role_id = ?", dto.ID).Delete(&model.SysRoleMenu{})
    result.Success(c, true)
}

// GetSysRoleByName 根据角色名称查询角色数据
func GetSysRoleByName(roleName string) (sysRole model.SysRole) {
    core.Db.Where("role_name = ?", roleName).First(&sysRole)
    return sysRole
}

// GetSysRoleByKey 根据角色Key查询角色数据
func GetSysRoleByKey(roleKey string) (sysRole model.SysRole) {
    core.Db.Where("role_key = ?", roleKey).First(&sysRole)
    return sysRole
}

到这里还会有点问题,没有校验当这个角色被分配用户的时候也不能删除,所以先创建用户与角色的表结构:

CREATE TABLE `sys_admin_role` (
    `admin_id` int(11) NOT NULL COMMENT '管理员ID',
    `role_id` int(11) NOT NULL COMMENT '角色ID'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='管理员和角色关系表';

执行结果:

然后创建 /model/sysAdminRole.go ,并在其中创建结构体:

// 角色与用户相关模型
// @author DaBaiLuoBo

package model

// SysAdminRole 角色与用户关系模型
type SysAdminRole struct {
    RoleId  uint `gorm:"column:role_id;comment:'角色ID';NOT NULL" json:"roleId"`   // 角色ID
    AdminId uint `gorm:"column:admin_id;comment:'用户ID';NOT NULL" json:"adminId"` // 用户ID
}

func (SysAdminRole) TableName() string {
    return "sys_admin_role"
}

这里需要注意一下, RoleId 和 AdminId 都是 uint 类型,然后我发现我之前的 /model/sysRoleMenu.go 里的类型写错了,写成 int 了,记得修改一下

回到 /api/sysRole.go 文件中,继续写相关逻辑:

// 角色相关接口
// @author DaBaiLuoBo

package api

import (
    "github.com/gin-gonic/gin"
    "goblog-admin/core"
    "goblog-admin/model"
    "goblog-admin/result"
    "goblog-admin/utils"
    "strconv"
    "time"
)

// CreateSysRole 新增角色
// @Summary 新增角色
// @Tags 角色相关接口
// @Produce json
// @Description 新增角色
// @Param data body model.AddSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/add [post]
func CreateSysRole(c *gin.Context) {
    var dto model.AddSysRoleDto
    _ = c.BindJSON(&dto)
    sysRoleByName := GetSysRoleByName(dto.RoleName)
    if sysRoleByName.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    sysRoleByKey := GetSysRoleByKey(dto.RoleKey)
    if sysRoleByKey.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    // 新增角色
    addSysRole := model.SysRole{
        RoleName:    dto.RoleName,
        RoleKey:     dto.RoleKey,
        Description: dto.Description,
        Status:      dto.Status,
        CreatTime:   utils.HTime{Time: time.Now()},
    }
    // 判断是否操作成功
    tx := core.Db.Create(&addSysRole)
    if tx.RowsAffected > 0 {
        result.Success(c, true)
        return
    } else {
        result.Failed(c, int(result.ApiCode.Failed), result.ApiCode.GetMessage(result.ApiCode.Failed))
        return
    }
}

// GetSysRoleList 分页查询角色列表
// @Summary 分页查询角色列表
// @Tags 角色相关接口
// @Produce json
// @Description 分页查询角色列表
// @Param pageNum query int false "分页数"
// @Param pageSize query int false "每页数"
// @Param roleName query string false "角色名称"
// @Param status query string false "账号启用状态:1-启用;2-禁用"
// @Param beginTime query string false "开始时间"
// @Param endTime query string false "结束时间"
// @Success 200 {object} result.Result
// @router /api/sysRole/list [get]
func GetSysRoleList(c *gin.Context) {
    PageNum, _ := strconv.Atoi(c.Query("pageNum"))
    PageSize, _ := strconv.Atoi(c.Query("pageSize"))
    RoleName := c.Query("roleName")
    Status := c.Query("status")
    BeginTime := c.Query("beginTime")
    EndTime := c.Query("endTime")
    if PageSize < 1 {
        PageSize = 10
    }
    if PageNum < 1 {
        PageNum = 1
    }
    var sysRoles []model.SysRole
    var count int64
    curDb := core.Db.Table("sys_role")
    if RoleName != "" {
        curDb = curDb.Where("role_name = ?", RoleName)
    }
    if BeginTime != "" && EndTime != "" {
        curDb = curDb.Where("create_time BETWEEN ? AND ?", BeginTime, EndTime)
    }
    if Status != "" {
        curDb = curDb.Where("status = ?", Status)
    }
    curDb.Count(&count).Limit(PageSize).Offset((PageNum - 1) * PageSize).Order("create_time DESC").Find(&sysRoles)
    result.Success(c, map[string]interface{}{"total": count, "pageSize": PageSize, "pageNum": PageNum, "list": sysRoles})
}

// GetSysRole 根据ID查询角色
// @Summary 根据ID查询角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID查询角色
// @Param id query int true "角色ID"
// @Success 200 {object} result.Result
// @router /api/sysRole/info [get]
func GetSysRole(c *gin.Context) {
    Id, _ := strconv.Atoi(c.Query("id"))
    var sysRole model.SysRole
    core.Db.First(&sysRole, Id)
    result.Success(c, sysRole)
}

// UpdateSysRole 修改角色信息
// @Summary 修改角色信息
// @Tags 角色相关接口
// @Produce json
// @Description 修改角色信息
// @Param data body model.UpdateSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/update [put]
func UpdateSysRole(c *gin.Context) {
    var dto model.UpdateSysRoleDto
    _ = c.BindJSON(&dto)
    var sysRole model.SysRole
    core.Db.First(&sysRole, dto.ID)
    sysRole.RoleName = dto.RoleName
    sysRole.RoleKey = dto.RoleKey
    sysRole.Status = dto.Status
    if dto.Description != "" {
        sysRole.Description = dto.Description
    }
    core.Db.Save(&sysRole)
    result.Success(c, true)
}

// DeleteSysRole 根据ID删除角色
// @Summary 根据ID删除角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID删除角色
// @Param data body model.SysRoleIdDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/delete [delete]
func DeleteSysRole(c *gin.Context) {
    var dto model.SysRoleIdDto
    _ = c.BindJSON(&dto)
    sysRoleById := GetSysAdminRole(dto.ID)
    // 如果查询到已绑定了角色,则返回删除失败
    if sysRoleById.RoleId > 0 {
        result.Failed(c, int(result.ApiCode.DelSysRoleFailed), result.ApiCode.GetMessage(result.ApiCode.DelSysRoleFailed))
        return
    }
    core.Db.Table("sys_role").Delete(&model.SysRole{}, dto.ID)
    core.Db.Table("sys_role_menu").Where("role_id = ?", dto.ID).Delete(&model.SysRoleMenu{})
    result.Success(c, true)
}

// GetSysRoleByName 根据角色名称查询角色数据
func GetSysRoleByName(roleName string) (sysRole model.SysRole) {
    core.Db.Where("role_name = ?", roleName).First(&sysRole)
    return sysRole
}

// GetSysRoleByKey 根据角色Key查询角色数据
func GetSysRoleByKey(roleKey string) (sysRole model.SysRole) {
    core.Db.Where("role_key = ?", roleKey).First(&sysRole)
    return sysRole
}

// GetSysAdminRole 查询是否分配角色
func GetSysAdminRole(id uint) (sysAdminRole model.SysAdminRole) {
    core.Db.Where("role_id = ?", id).First(&sysAdminRole)
    return sysAdminRole
}

然后在 /result/code.go 中定义一下新增的 code 码:

// 状态码/状态信息
// @author DaiBaiLuoBo

package result

// Codes 定义状态
type Codes struct {
    Message               map[uint]string
    Success               uint
    Failed                uint
    SysMenuIsExist        uint
    DelSysMenuFailed      uint
    DelSysChildMenuFailed uint
    RoleAlreadExists      uint
    DelSysRoleFailed      uint
}

// ApiCode 状态码
var ApiCode = &Codes{
    Success:               200,
    Failed:                501,
    SysMenuIsExist:        600,
    DelSysMenuFailed:      601,
    DelSysChildMenuFailed: 602,
    RoleAlreadExists:      603,
    DelSysRoleFailed:      604,
}

// 状态信息初始化
func init() {
    ApiCode.Message = map[uint]string{
        ApiCode.Success:               "成功",
        ApiCode.Failed:                "失败",
        ApiCode.SysMenuIsExist:        "菜单名称已存在,请重新输入",
        ApiCode.DelSysMenuFailed:      "菜单已分配,不能删除",
        ApiCode.DelSysChildMenuFailed: "该菜单存在子菜单,不能删除",
        ApiCode.RoleAlreadExists:      "角色名或角色Key已存在,请重新输入",
        ApiCode.DelSysRoleFailed:      "角色已分配,不能删除",
    }
}

// GetMessage 供给外部调用状态信息
func (c *Codes) GetMessage(code uint) string {
    message, ok := c.Message[code]
    // 如果不 ok,返回空,ok 则返回 message
    if !ok {
        return ""
    }
    return message
}

在加入路由 /router/router.go

router.DELETE("/api/sysRole/delete", api.DeleteSysRole)

初始化swag,测试一下:

先手动给刚创建的 sys_admin_role 加个数据:

然后测试 api:

然后手动删除刚才新加的这个数据,再测试一下:

看一下数据库:

好的,之前的那个测试管理员的数据已经被删除了,没问题

设置角色状态

第一步还是一样,先去 /model/sysRole.go 中定义结构体:

// 角色相关模型
// @author DaBaiLuoBo

package model

import "goblog-admin/utils"

// SysRole 角色相关模型
type SysRole struct {
    ID          uint        `gorm:"column:id;comment:'主键';primaryKey;NOT NULL" json:"id"`                      // ID
    RoleName    string      `gorm:"column:role_name;varchar(64);comment:'角色名称';NOT NULL" json:"roleName"`      // 角色名称
    RoleKey     string      `gorm:"column:role_key;varchar(64);comment:'权限字符串';NOT NULL" json:"roleKey"`       // 权限字符串
    Status      int         `gorm:"column:status;default:1;comment:'账号启用状态:1-启用;2-禁用';NOT NULL" json:"status"` // 账号启用状态:1-启用;2-禁用
    Description string      `gorm:"column:description;varchar(500);comment:'描述';NOT NULL" json:"description"`  // 描述
    CreatTime   utils.HTime `gorm:"column:create_time;comment:'创建时间'" json:"createTime"`                       // 创建时间
}

func (SysRole) TableName() string {
    return "sys_role"
}

// AddSysRoleDto 新增角色参数
type AddSysRoleDto struct {
    RoleName    string `json:"roleName"`    // 角色名称
    RoleKey     string `json:"roleKey"`     // 权限字符串
    Status      int    `json:"status"`      // 账号启用状态:1-启用;2-禁用
    Description string `json:"description"` // 描述
}

// UpdateSysRoleDto 新增角色参数
type UpdateSysRoleDto struct {
    ID          uint   `json:"id"`          // ID
    RoleName    string `json:"roleName"`    // 角色名称
    RoleKey     string `json:"roleKey"`     // 权限字符串
    Status      int    `json:"status"`      // 账号启用状态:1-启用;2-禁用
    Description string `json:"description"` // 描述
}

// SysRoleIdDto ID参数
type SysRoleIdDto struct {
    ID uint `json:"id"` // ID
}

// UpdateSysRoleStatusDto 设置角色启用状态
type UpdateSysRoleStatusDto struct {
    ID     uint `json:"id"`     // ID
    Status int  `json:"status"` // 账号启用状态:1-启用;2-禁用
}

下一步在 /api/sysRole.go 中定义接口:

// 角色相关接口
// @author DaBaiLuoBo

package api

import (
    "github.com/gin-gonic/gin"
    "goblog-admin/core"
    "goblog-admin/model"
    "goblog-admin/result"
    "goblog-admin/utils"
    "strconv"
    "time"
)

// CreateSysRole 新增角色
// @Summary 新增角色
// @Tags 角色相关接口
// @Produce json
// @Description 新增角色
// @Param data body model.AddSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/add [post]
func CreateSysRole(c *gin.Context) {
    var dto model.AddSysRoleDto
    _ = c.BindJSON(&dto)
    sysRoleByName := GetSysRoleByName(dto.RoleName)
    if sysRoleByName.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    sysRoleByKey := GetSysRoleByKey(dto.RoleKey)
    if sysRoleByKey.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    // 新增角色
    addSysRole := model.SysRole{
        RoleName:    dto.RoleName,
        RoleKey:     dto.RoleKey,
        Description: dto.Description,
        Status:      dto.Status,
        CreatTime:   utils.HTime{Time: time.Now()},
    }
    // 判断是否操作成功
    tx := core.Db.Create(&addSysRole)
    if tx.RowsAffected > 0 {
        result.Success(c, true)
        return
    } else {
        result.Failed(c, int(result.ApiCode.Failed), result.ApiCode.GetMessage(result.ApiCode.Failed))
        return
    }
}

// GetSysRoleList 分页查询角色列表
// @Summary 分页查询角色列表
// @Tags 角色相关接口
// @Produce json
// @Description 分页查询角色列表
// @Param pageNum query int false "分页数"
// @Param pageSize query int false "每页数"
// @Param roleName query string false "角色名称"
// @Param status query string false "账号启用状态:1-启用;2-禁用"
// @Param beginTime query string false "开始时间"
// @Param endTime query string false "结束时间"
// @Success 200 {object} result.Result
// @router /api/sysRole/list [get]
func GetSysRoleList(c *gin.Context) {
    PageNum, _ := strconv.Atoi(c.Query("pageNum"))
    PageSize, _ := strconv.Atoi(c.Query("pageSize"))
    RoleName := c.Query("roleName")
    Status := c.Query("status")
    BeginTime := c.Query("beginTime")
    EndTime := c.Query("endTime")
    if PageSize < 1 {
        PageSize = 10
    }
    if PageNum < 1 {
        PageNum = 1
    }
    var sysRoles []model.SysRole
    var count int64
    curDb := core.Db.Table("sys_role")
    if RoleName != "" {
        curDb = curDb.Where("role_name = ?", RoleName)
    }
    if BeginTime != "" && EndTime != "" {
        curDb = curDb.Where("create_time BETWEEN ? AND ?", BeginTime, EndTime)
    }
    if Status != "" {
        curDb = curDb.Where("status = ?", Status)
    }
    curDb.Count(&count).Limit(PageSize).Offset((PageNum - 1) * PageSize).Order("create_time DESC").Find(&sysRoles)
    result.Success(c, map[string]interface{}{"total": count, "pageSize": PageSize, "pageNum": PageNum, "list": sysRoles})
}

// GetSysRole 根据ID查询角色
// @Summary 根据ID查询角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID查询角色
// @Param id query int true "角色ID"
// @Success 200 {object} result.Result
// @router /api/sysRole/info [get]
func GetSysRole(c *gin.Context) {
    Id, _ := strconv.Atoi(c.Query("id"))
    var sysRole model.SysRole
    core.Db.First(&sysRole, Id)
    result.Success(c, sysRole)
}

// UpdateSysRole 修改角色信息
// @Summary 修改角色信息
// @Tags 角色相关接口
// @Produce json
// @Description 修改角色信息
// @Param data body model.UpdateSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/update [put]
func UpdateSysRole(c *gin.Context) {
    var dto model.UpdateSysRoleDto
    _ = c.BindJSON(&dto)
    var sysRole model.SysRole
    core.Db.First(&sysRole, dto.ID)
    sysRole.RoleName = dto.RoleName
    sysRole.RoleKey = dto.RoleKey
    sysRole.Status = dto.Status
    if dto.Description != "" {
        sysRole.Description = dto.Description
    }
    core.Db.Save(&sysRole)
    result.Success(c, true)
}

// DeleteSysRole 根据ID删除角色
// @Summary 根据ID删除角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID删除角色
// @Param data body model.SysRoleIdDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/delete [delete]
func DeleteSysRole(c *gin.Context) {
    var dto model.SysRoleIdDto
    _ = c.BindJSON(&dto)
    sysRoleById := GetSysAdminRole(dto.ID)
    // 如果查询到已绑定了角色,则返回删除失败
    if sysRoleById.RoleId > 0 {
        result.Failed(c, int(result.ApiCode.DelSysRoleFailed), result.ApiCode.GetMessage(result.ApiCode.DelSysRoleFailed))
        return
    }
    core.Db.Table("sys_role").Delete(&model.SysRole{}, dto.ID)
    core.Db.Table("sys_role_menu").Where("role_id = ?", dto.ID).Delete(&model.SysRoleMenu{})
    result.Success(c, true)
}

// UpdateSysRoleStatus 设置角色启用状态
// @Summary 设置角色启用状态
// @Tags 角色相关接口
// @Produce json
// @Description 设置角色启用状态
// @Param data body model.UpdateSysRoleStatusDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/updateStatus [put]
func UpdateSysRoleStatus(c *gin.Context)  {
    var dto model.UpdateSysRoleStatusDto
    _ = c.BindJSON(&dto)
    var sysRole model.SysRole
    core.Db.First(&sysRole, dto.ID)
    sysRole.Status = dto.Status
    core.Db.Save(&sysRole)
    result.Success(c, true)
}

// GetSysRoleByName 根据角色名称查询角色数据
func GetSysRoleByName(roleName string) (sysRole model.SysRole) {
    core.Db.Where("role_name = ?", roleName).First(&sysRole)
    return sysRole
}

// GetSysRoleByKey 根据角色Key查询角色数据
func GetSysRoleByKey(roleKey string) (sysRole model.SysRole) {
    core.Db.Where("role_key = ?", roleKey).First(&sysRole)
    return sysRole
}

// GetSysAdminRole 查询是否分配角色
func GetSysAdminRole(id uint) (sysAdminRole model.SysAdminRole) {
    core.Db.Where("role_id = ?", id).First(&sysAdminRole)
    return sysAdminRole
}

下一步在 /router/router.go 中定义路由:

router.PUT("/api/sysRole/updateStatus", api.UpdateSysRoleStatus)

最后初始化swag,测试一下:

因为刚才测试删除角色把唯一一个角色删除了,先利用新增角色接口来增加一个:

这里可以看到新增的角色 id 为2,测试一下设置启用状态接口:

新增用户时查询角色

这个接口是为后面新增用户准备的,举个例子新增用户的时候可以选择是管理员、普通用户等角色

第一步在 /model/sysRole.go 中新增结构体:

// 角色相关模型
// @author DaBaiLuoBo

package model

import "goblog-admin/utils"

// SysRole 角色相关模型
type SysRole struct {
    ID          uint        `gorm:"column:id;comment:'主键';primaryKey;NOT NULL" json:"id"`                      // ID
    RoleName    string      `gorm:"column:role_name;varchar(64);comment:'角色名称';NOT NULL" json:"roleName"`      // 角色名称
    RoleKey     string      `gorm:"column:role_key;varchar(64);comment:'权限字符串';NOT NULL" json:"roleKey"`       // 权限字符串
    Status      int         `gorm:"column:status;default:1;comment:'账号启用状态:1-启用;2-禁用';NOT NULL" json:"status"` // 账号启用状态:1-启用;2-禁用
    Description string      `gorm:"column:description;varchar(500);comment:'描述';NOT NULL" json:"description"`  // 描述
    CreatTime   utils.HTime `gorm:"column:create_time;comment:'创建时间'" json:"createTime"`                       // 创建时间
}

func (SysRole) TableName() string {
    return "sys_role"
}

// AddSysRoleDto 新增角色参数
type AddSysRoleDto struct {
    RoleName    string `json:"roleName"`    // 角色名称
    RoleKey     string `json:"roleKey"`     // 权限字符串
    Status      int    `json:"status"`      // 账号启用状态:1-启用;2-禁用
    Description string `json:"description"` // 描述
}

// UpdateSysRoleDto 新增角色参数
type UpdateSysRoleDto struct {
    ID          uint   `json:"id"`          // ID
    RoleName    string `json:"roleName"`    // 角色名称
    RoleKey     string `json:"roleKey"`     // 权限字符串
    Status      int    `json:"status"`      // 账号启用状态:1-启用;2-禁用
    Description string `json:"description"` // 描述
}

// SysRoleIdDto ID参数
type SysRoleIdDto struct {
    ID uint `json:"id"` // ID
}

// UpdateSysRoleStatusDto 设置角色启用状态
type UpdateSysRoleStatusDto struct {
    ID     uint `json:"id"`     // ID
    Status int  `json:"status"` // 账号启用状态:1-启用;2-禁用
}

// SysRoleVo 角色下拉列表
type SysRoleVo struct {
    ID          uint   `json:"id"`          // ID
    RoleName    string `json:"roleName"`    // 角色名称
}

下一步在 /api/sysRole.go 中定义接口:

// 角色相关接口
// @author DaBaiLuoBo

package api

import (
    "github.com/gin-gonic/gin"
    "goblog-admin/core"
    "goblog-admin/model"
    "goblog-admin/result"
    "goblog-admin/utils"
    "strconv"
    "time"
)

// CreateSysRole 新增角色
// @Summary 新增角色
// @Tags 角色相关接口
// @Produce json
// @Description 新增角色
// @Param data body model.AddSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/add [post]
func CreateSysRole(c *gin.Context) {
    var dto model.AddSysRoleDto
    _ = c.BindJSON(&dto)
    sysRoleByName := GetSysRoleByName(dto.RoleName)
    if sysRoleByName.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    sysRoleByKey := GetSysRoleByKey(dto.RoleKey)
    if sysRoleByKey.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    // 新增角色
    addSysRole := model.SysRole{
        RoleName:    dto.RoleName,
        RoleKey:     dto.RoleKey,
        Description: dto.Description,
        Status:      dto.Status,
        CreatTime:   utils.HTime{Time: time.Now()},
    }
    // 判断是否操作成功
    tx := core.Db.Create(&addSysRole)
    if tx.RowsAffected > 0 {
        result.Success(c, true)
        return
    } else {
        result.Failed(c, int(result.ApiCode.Failed), result.ApiCode.GetMessage(result.ApiCode.Failed))
        return
    }
}

// GetSysRoleList 分页查询角色列表
// @Summary 分页查询角色列表
// @Tags 角色相关接口
// @Produce json
// @Description 分页查询角色列表
// @Param pageNum query int false "分页数"
// @Param pageSize query int false "每页数"
// @Param roleName query string false "角色名称"
// @Param status query string false "账号启用状态:1-启用;2-禁用"
// @Param beginTime query string false "开始时间"
// @Param endTime query string false "结束时间"
// @Success 200 {object} result.Result
// @router /api/sysRole/list [get]
func GetSysRoleList(c *gin.Context) {
    PageNum, _ := strconv.Atoi(c.Query("pageNum"))
    PageSize, _ := strconv.Atoi(c.Query("pageSize"))
    RoleName := c.Query("roleName")
    Status := c.Query("status")
    BeginTime := c.Query("beginTime")
    EndTime := c.Query("endTime")
    if PageSize < 1 {
        PageSize = 10
    }
    if PageNum < 1 {
        PageNum = 1
    }
    var sysRoles []model.SysRole
    var count int64
    curDb := core.Db.Table("sys_role")
    if RoleName != "" {
        curDb = curDb.Where("role_name = ?", RoleName)
    }
    if BeginTime != "" && EndTime != "" {
        curDb = curDb.Where("create_time BETWEEN ? AND ?", BeginTime, EndTime)
    }
    if Status != "" {
        curDb = curDb.Where("status = ?", Status)
    }
    curDb.Count(&count).Limit(PageSize).Offset((PageNum - 1) * PageSize).Order("create_time DESC").Find(&sysRoles)
    result.Success(c, map[string]interface{}{"total": count, "pageSize": PageSize, "pageNum": PageNum, "list": sysRoles})
}

// GetSysRole 根据ID查询角色
// @Summary 根据ID查询角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID查询角色
// @Param id query int true "角色ID"
// @Success 200 {object} result.Result
// @router /api/sysRole/info [get]
func GetSysRole(c *gin.Context) {
    Id, _ := strconv.Atoi(c.Query("id"))
    var sysRole model.SysRole
    core.Db.First(&sysRole, Id)
    result.Success(c, sysRole)
}

// UpdateSysRole 修改角色信息
// @Summary 修改角色信息
// @Tags 角色相关接口
// @Produce json
// @Description 修改角色信息
// @Param data body model.UpdateSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/update [put]
func UpdateSysRole(c *gin.Context) {
    var dto model.UpdateSysRoleDto
    _ = c.BindJSON(&dto)
    var sysRole model.SysRole
    core.Db.First(&sysRole, dto.ID)
    sysRole.RoleName = dto.RoleName
    sysRole.RoleKey = dto.RoleKey
    sysRole.Status = dto.Status
    if dto.Description != "" {
        sysRole.Description = dto.Description
    }
    core.Db.Save(&sysRole)
    result.Success(c, true)
}

// DeleteSysRole 根据ID删除角色
// @Summary 根据ID删除角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID删除角色
// @Param data body model.SysRoleIdDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/delete [delete]
func DeleteSysRole(c *gin.Context) {
    var dto model.SysRoleIdDto
    _ = c.BindJSON(&dto)
    sysRoleById := GetSysAdminRole(dto.ID)
    // 如果查询到已绑定了角色,则返回删除失败
    if sysRoleById.RoleId > 0 {
        result.Failed(c, int(result.ApiCode.DelSysRoleFailed), result.ApiCode.GetMessage(result.ApiCode.DelSysRoleFailed))
        return
    }
    core.Db.Table("sys_role").Delete(&model.SysRole{}, dto.ID)
    core.Db.Table("sys_role_menu").Where("role_id = ?", dto.ID).Delete(&model.SysRoleMenu{})
    result.Success(c, true)
}

// UpdateSysRoleStatus 设置角色启用状态
// @Summary 设置角色启用状态
// @Tags 角色相关接口
// @Produce json
// @Description 设置角色启用状态
// @Param data body model.UpdateSysRoleStatusDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/updateStatus [put]
func UpdateSysRoleStatus(c *gin.Context) {
    var dto model.UpdateSysRoleStatusDto
    _ = c.BindJSON(&dto)
    var sysRole model.SysRole
    core.Db.First(&sysRole, dto.ID)
    sysRole.Status = dto.Status
    core.Db.Save(&sysRole)
    result.Success(c, true)
}

// GetSysRoleVoList 查询角色下拉列表
// @Summary 查询角色下拉列表
// @Tags 角色相关接口
// @Produce json
// @Description 查询角色下拉列表
// @Success 200 {object} result.Result
// @router /api/sysRole/vo/list [get]
func GetSysRoleVoList(c *gin.Context)  {
    var sysRoleVo []model.SysRole
    core.Db.Table("sys_role").Select("id, role_name").Scan(&sysRoleVo)
    result.Success(c, sysRoleVo)
}

// GetSysRoleByName 根据角色名称查询角色数据
func GetSysRoleByName(roleName string) (sysRole model.SysRole) {
    core.Db.Where("role_name = ?", roleName).First(&sysRole)
    return sysRole
}

// GetSysRoleByKey 根据角色Key查询角色数据
func GetSysRoleByKey(roleKey string) (sysRole model.SysRole) {
    core.Db.Where("role_key = ?", roleKey).First(&sysRole)
    return sysRole
}

// GetSysAdminRole 查询是否分配角色
func GetSysAdminRole(id uint) (sysAdminRole model.SysAdminRole) {
    core.Db.Where("role_id = ?", id).First(&sysAdminRole)
    return sysAdminRole
}

下一步增加路由 /router/router.go

router.GET("/api/sysRole/vo/list", api.GetSysRoleVoList)

最后初始化swag,测试一下:

ok,没问题的

分配角色权限接口

第一步在 /model/sysRole.go 中定义结构体:

// 角色相关模型
// @author DaBaiLuoBo

package model

import "goblog-admin/utils"

// SysRole 角色相关模型
type SysRole struct {
    ID          uint        `gorm:"column:id;comment:'主键';primaryKey;NOT NULL" json:"id"`                      // ID
    RoleName    string      `gorm:"column:role_name;varchar(64);comment:'角色名称';NOT NULL" json:"roleName"`      // 角色名称
    RoleKey     string      `gorm:"column:role_key;varchar(64);comment:'权限字符串';NOT NULL" json:"roleKey"`       // 权限字符串
    Status      int         `gorm:"column:status;default:1;comment:'账号启用状态:1-启用;2-禁用';NOT NULL" json:"status"` // 账号启用状态:1-启用;2-禁用
    Description string      `gorm:"column:description;varchar(500);comment:'描述';NOT NULL" json:"description"`  // 描述
    CreatTime   utils.HTime `gorm:"column:create_time;comment:'创建时间'" json:"createTime"`                       // 创建时间
}

func (SysRole) TableName() string {
    return "sys_role"
}

// AddSysRoleDto 新增角色参数
type AddSysRoleDto struct {
    RoleName    string `json:"roleName"`    // 角色名称
    RoleKey     string `json:"roleKey"`     // 权限字符串
    Status      int    `json:"status"`      // 账号启用状态:1-启用;2-禁用
    Description string `json:"description"` // 描述
}

// UpdateSysRoleDto 新增角色参数
type UpdateSysRoleDto struct {
    ID          uint   `json:"id"`          // ID
    RoleName    string `json:"roleName"`    // 角色名称
    RoleKey     string `json:"roleKey"`     // 权限字符串
    Status      int    `json:"status"`      // 账号启用状态:1-启用;2-禁用
    Description string `json:"description"` // 描述
}

// SysRoleIdDto ID参数
type SysRoleIdDto struct {
    ID uint `json:"id"` // ID
}

// UpdateSysRoleStatusDto 设置角色启用状态
type UpdateSysRoleStatusDto struct {
    ID     uint `json:"id"`     // ID
    Status int  `json:"status"` // 账号启用状态:1-启用;2-禁用
}

// SysRoleVo 角色下拉列表
type SysRoleVo struct {
    ID       uint   `json:"id"`       // ID
    RoleName string `json:"roleName"` // 角色名称
}

// IdVo 当前角色分配的菜单权限ID
type IdVo struct {
    ID int `json:"id"` // ID
}

下一步在 /api/sysRole.go 中实现接口:

// 角色相关接口
// @author DaBaiLuoBo

package api

import (
    "github.com/gin-gonic/gin"
    "goblog-admin/core"
    "goblog-admin/model"
    "goblog-admin/result"
    "goblog-admin/utils"
    "strconv"
    "time"
)

// CreateSysRole 新增角色
// @Summary 新增角色
// @Tags 角色相关接口
// @Produce json
// @Description 新增角色
// @Param data body model.AddSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/add [post]
func CreateSysRole(c *gin.Context) {
    var dto model.AddSysRoleDto
    _ = c.BindJSON(&dto)
    sysRoleByName := GetSysRoleByName(dto.RoleName)
    if sysRoleByName.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    sysRoleByKey := GetSysRoleByKey(dto.RoleKey)
    if sysRoleByKey.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    // 新增角色
    addSysRole := model.SysRole{
        RoleName:    dto.RoleName,
        RoleKey:     dto.RoleKey,
        Description: dto.Description,
        Status:      dto.Status,
        CreatTime:   utils.HTime{Time: time.Now()},
    }
    // 判断是否操作成功
    tx := core.Db.Create(&addSysRole)
    if tx.RowsAffected > 0 {
        result.Success(c, true)
        return
    } else {
        result.Failed(c, int(result.ApiCode.Failed), result.ApiCode.GetMessage(result.ApiCode.Failed))
        return
    }
}

// GetSysRoleList 分页查询角色列表
// @Summary 分页查询角色列表
// @Tags 角色相关接口
// @Produce json
// @Description 分页查询角色列表
// @Param pageNum query int false "分页数"
// @Param pageSize query int false "每页数"
// @Param roleName query string false "角色名称"
// @Param status query string false "账号启用状态:1-启用;2-禁用"
// @Param beginTime query string false "开始时间"
// @Param endTime query string false "结束时间"
// @Success 200 {object} result.Result
// @router /api/sysRole/list [get]
func GetSysRoleList(c *gin.Context) {
    PageNum, _ := strconv.Atoi(c.Query("pageNum"))
    PageSize, _ := strconv.Atoi(c.Query("pageSize"))
    RoleName := c.Query("roleName")
    Status := c.Query("status")
    BeginTime := c.Query("beginTime")
    EndTime := c.Query("endTime")
    if PageSize < 1 {
        PageSize = 10
    }
    if PageNum < 1 {
        PageNum = 1
    }
    var sysRoles []model.SysRole
    var count int64
    curDb := core.Db.Table("sys_role")
    if RoleName != "" {
        curDb = curDb.Where("role_name = ?", RoleName)
    }
    if BeginTime != "" && EndTime != "" {
        curDb = curDb.Where("create_time BETWEEN ? AND ?", BeginTime, EndTime)
    }
    if Status != "" {
        curDb = curDb.Where("status = ?", Status)
    }
    curDb.Count(&count).Limit(PageSize).Offset((PageNum - 1) * PageSize).Order("create_time DESC").Find(&sysRoles)
    result.Success(c, map[string]interface{}{"total": count, "pageSize": PageSize, "pageNum": PageNum, "list": sysRoles})
}

// GetSysRole 根据ID查询角色
// @Summary 根据ID查询角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID查询角色
// @Param id query int true "角色ID"
// @Success 200 {object} result.Result
// @router /api/sysRole/info [get]
func GetSysRole(c *gin.Context) {
    Id, _ := strconv.Atoi(c.Query("id"))
    var sysRole model.SysRole
    core.Db.First(&sysRole, Id)
    result.Success(c, sysRole)
}

// UpdateSysRole 修改角色信息
// @Summary 修改角色信息
// @Tags 角色相关接口
// @Produce json
// @Description 修改角色信息
// @Param data body model.UpdateSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/update [put]
func UpdateSysRole(c *gin.Context) {
    var dto model.UpdateSysRoleDto
    _ = c.BindJSON(&dto)
    var sysRole model.SysRole
    core.Db.First(&sysRole, dto.ID)
    sysRole.RoleName = dto.RoleName
    sysRole.RoleKey = dto.RoleKey
    sysRole.Status = dto.Status
    if dto.Description != "" {
        sysRole.Description = dto.Description
    }
    core.Db.Save(&sysRole)
    result.Success(c, true)
}

// DeleteSysRole 根据ID删除角色
// @Summary 根据ID删除角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID删除角色
// @Param data body model.SysRoleIdDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/delete [delete]
func DeleteSysRole(c *gin.Context) {
    var dto model.SysRoleIdDto
    _ = c.BindJSON(&dto)
    sysRoleById := GetSysAdminRole(dto.ID)
    // 如果查询到已绑定了角色,则返回删除失败
    if sysRoleById.RoleId > 0 {
        result.Failed(c, int(result.ApiCode.DelSysRoleFailed), result.ApiCode.GetMessage(result.ApiCode.DelSysRoleFailed))
        return
    }
    core.Db.Table("sys_role").Delete(&model.SysRole{}, dto.ID)
    core.Db.Table("sys_role_menu").Where("role_id = ?", dto.ID).Delete(&model.SysRoleMenu{})
    result.Success(c, true)
}

// UpdateSysRoleStatus 设置角色启用状态
// @Summary 设置角色启用状态
// @Tags 角色相关接口
// @Produce json
// @Description 设置角色启用状态
// @Param data body model.UpdateSysRoleStatusDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/updateStatus [put]
func UpdateSysRoleStatus(c *gin.Context) {
    var dto model.UpdateSysRoleStatusDto
    _ = c.BindJSON(&dto)
    var sysRole model.SysRole
    core.Db.First(&sysRole, dto.ID)
    sysRole.Status = dto.Status
    core.Db.Save(&sysRole)
    result.Success(c, true)
}

// GetSysRoleVoList 查询角色下拉列表
// @Summary 查询角色下拉列表
// @Tags 角色相关接口
// @Produce json
// @Description 查询角色下拉列表
// @Success 200 {object} result.Result
// @router /api/sysRole/vo/list [get]
func GetSysRoleVoList(c *gin.Context) {
    var sysRoleVo []model.SysRoleVo
    core.Db.Table("sys_role").Select("id, role_name").Scan(&sysRoleVo)
    result.Success(c, sysRoleVo)
}

// QueryRoleMenuIdList 根据角色ID查询菜单权限
// @Summary 根据角色ID查询菜单权限
// @Tags 角色相关接口
// @Produce json
// @Description 根据角色ID查询菜单权限
// @Param id query int true "ID"
// @Success 200 {object} result.Result
// @router /api/sysRole/vo/idList [get]
func QueryRoleMenuIdList(c *gin.Context) {
    Id, _ := strconv.Atoi(c.Query("id"))
    var idVo []model.IdVo
    const menuType = 3 // 查询深度等于三级,目录级>菜单级>按钮级
    core.Db.Table("sys_menu").
        Select("sys_menu.id").Joins("LEFT JOIN sys_role_menu ON sys_role_menu.menu_id = sys_menu.id").
        Joins("LEFT JOIN sys_role ON sys_role.id = sys_role_menu.role_id").
        Where("sys_menu.menu_type = ?", menuType).
        Where("sys_role.id = ?", Id).
        Scan(&idVo)
    var idList = make([]int, 0, 10)
    for _, id := range idVo {
        idList = append(idList, id.ID)
    }
    result.Success(c, idList)
}

// GetSysRoleByName 根据角色名称查询角色数据
func GetSysRoleByName(roleName string) (sysRole model.SysRole) {
    core.Db.Where("role_name = ?", roleName).First(&sysRole)
    return sysRole
}

// GetSysRoleByKey 根据角色Key查询角色数据
func GetSysRoleByKey(roleKey string) (sysRole model.SysRole) {
    core.Db.Where("role_key = ?", roleKey).First(&sysRole)
    return sysRole
}

// GetSysAdminRole 查询是否分配角色
func GetSysAdminRole(id uint) (sysAdminRole model.SysAdminRole) {
    core.Db.Where("role_id = ?", id).First(&sysAdminRole)
    return sysAdminRole
}

下一步添加路由 /router/router.go

router.GET("/api/sysRole/vo/idList", api.QueryRoleMenuIdList)

最后swag初始化,测试一下:

因为我们之前测试接口,数据都删了,所以先填充一下数据:

这里根据实际的来,我这里的角色 id 之前是2,所以就是2

查询一下,发现返回数据为空,手动修改一下刚才的新加的 menu_type 为3,因为查询的是第三级的数据:

再测试一下:

现在只完成了查询,接下来继续完善分配权限

还是在 /model/sysRole.go 中先定义结构体:

// 角色相关模型
// @author DaBaiLuoBo

package model

import "goblog-admin/utils"

// SysRole 角色相关模型
type SysRole struct {
    ID          uint        `gorm:"column:id;comment:'主键';primaryKey;NOT NULL" json:"id"`                      // ID
    RoleName    string      `gorm:"column:role_name;varchar(64);comment:'角色名称';NOT NULL" json:"roleName"`      // 角色名称
    RoleKey     string      `gorm:"column:role_key;varchar(64);comment:'权限字符串';NOT NULL" json:"roleKey"`       // 权限字符串
    Status      int         `gorm:"column:status;default:1;comment:'账号启用状态:1-启用;2-禁用';NOT NULL" json:"status"` // 账号启用状态:1-启用;2-禁用
    Description string      `gorm:"column:description;varchar(500);comment:'描述';NOT NULL" json:"description"`  // 描述
    CreatTime   utils.HTime `gorm:"column:create_time;comment:'创建时间'" json:"createTime"`                       // 创建时间
}

func (SysRole) TableName() string {
    return "sys_role"
}

// AddSysRoleDto 新增角色参数
type AddSysRoleDto struct {
    RoleName    string `json:"roleName"`    // 角色名称
    RoleKey     string `json:"roleKey"`     // 权限字符串
    Status      int    `json:"status"`      // 账号启用状态:1-启用;2-禁用
    Description string `json:"description"` // 描述
}

// UpdateSysRoleDto 新增角色参数
type UpdateSysRoleDto struct {
    ID          uint   `json:"id"`          // ID
    RoleName    string `json:"roleName"`    // 角色名称
    RoleKey     string `json:"roleKey"`     // 权限字符串
    Status      int    `json:"status"`      // 账号启用状态:1-启用;2-禁用
    Description string `json:"description"` // 描述
}

// SysRoleIdDto ID参数
type SysRoleIdDto struct {
    ID uint `json:"id"` // ID
}

// UpdateSysRoleStatusDto 设置角色启用状态
type UpdateSysRoleStatusDto struct {
    ID     uint `json:"id"`     // ID
    Status int  `json:"status"` // 账号启用状态:1-启用;2-禁用
}

// SysRoleVo 角色下拉列表
type SysRoleVo struct {
    ID       uint   `json:"id"`       // ID
    RoleName string `json:"roleName"` // 角色名称
}

// IdVo 当前角色分配的菜单权限ID
type IdVo struct {
    ID int `json:"id"` // ID
}

// RoleMenuDto 角色ID和菜单ID列表参数对象
type RoleMenuDto struct {
    ID      uint   `json:"id" binding:"required"`       // 角色ID
    MenuIds []uint `json:"menu_ids" binding:"required"` // 菜单ID列表
}

回到 /api/sysRole.go 中定义接口:

// 角色相关接口
// @author DaBaiLuoBo

package api

import (
    "github.com/gin-gonic/gin"
    "goblog-admin/core"
    "goblog-admin/model"
    "goblog-admin/result"
    "goblog-admin/utils"
    "strconv"
    "time"
)

// CreateSysRole 新增角色
// @Summary 新增角色
// @Tags 角色相关接口
// @Produce json
// @Description 新增角色
// @Param data body model.AddSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/add [post]
func CreateSysRole(c *gin.Context) {
    var dto model.AddSysRoleDto
    _ = c.BindJSON(&dto)
    sysRoleByName := GetSysRoleByName(dto.RoleName)
    if sysRoleByName.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    sysRoleByKey := GetSysRoleByKey(dto.RoleKey)
    if sysRoleByKey.ID > 0 {
        result.Failed(c, int(result.ApiCode.RoleAlreadExists), result.ApiCode.GetMessage(result.ApiCode.RoleAlreadExists))
        return
    }
    // 新增角色
    addSysRole := model.SysRole{
        RoleName:    dto.RoleName,
        RoleKey:     dto.RoleKey,
        Description: dto.Description,
        Status:      dto.Status,
        CreatTime:   utils.HTime{Time: time.Now()},
    }
    // 判断是否操作成功
    tx := core.Db.Create(&addSysRole)
    if tx.RowsAffected > 0 {
        result.Success(c, true)
        return
    } else {
        result.Failed(c, int(result.ApiCode.Failed), result.ApiCode.GetMessage(result.ApiCode.Failed))
        return
    }
}

// GetSysRoleList 分页查询角色列表
// @Summary 分页查询角色列表
// @Tags 角色相关接口
// @Produce json
// @Description 分页查询角色列表
// @Param pageNum query int false "分页数"
// @Param pageSize query int false "每页数"
// @Param roleName query string false "角色名称"
// @Param status query string false "账号启用状态:1-启用;2-禁用"
// @Param beginTime query string false "开始时间"
// @Param endTime query string false "结束时间"
// @Success 200 {object} result.Result
// @router /api/sysRole/list [get]
func GetSysRoleList(c *gin.Context) {
    PageNum, _ := strconv.Atoi(c.Query("pageNum"))
    PageSize, _ := strconv.Atoi(c.Query("pageSize"))
    RoleName := c.Query("roleName")
    Status := c.Query("status")
    BeginTime := c.Query("beginTime")
    EndTime := c.Query("endTime")
    if PageSize < 1 {
        PageSize = 10
    }
    if PageNum < 1 {
        PageNum = 1
    }
    var sysRoles []model.SysRole
    var count int64
    curDb := core.Db.Table("sys_role")
    if RoleName != "" {
        curDb = curDb.Where("role_name = ?", RoleName)
    }
    if BeginTime != "" && EndTime != "" {
        curDb = curDb.Where("create_time BETWEEN ? AND ?", BeginTime, EndTime)
    }
    if Status != "" {
        curDb = curDb.Where("status = ?", Status)
    }
    curDb.Count(&count).Limit(PageSize).Offset((PageNum - 1) * PageSize).Order("create_time DESC").Find(&sysRoles)
    result.Success(c, map[string]interface{}{"total": count, "pageSize": PageSize, "pageNum": PageNum, "list": sysRoles})
}

// GetSysRole 根据ID查询角色
// @Summary 根据ID查询角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID查询角色
// @Param id query int true "角色ID"
// @Success 200 {object} result.Result
// @router /api/sysRole/info [get]
func GetSysRole(c *gin.Context) {
    Id, _ := strconv.Atoi(c.Query("id"))
    var sysRole model.SysRole
    core.Db.First(&sysRole, Id)
    result.Success(c, sysRole)
}

// UpdateSysRole 修改角色信息
// @Summary 修改角色信息
// @Tags 角色相关接口
// @Produce json
// @Description 修改角色信息
// @Param data body model.UpdateSysRoleDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/update [put]
func UpdateSysRole(c *gin.Context) {
    var dto model.UpdateSysRoleDto
    _ = c.BindJSON(&dto)
    var sysRole model.SysRole
    core.Db.First(&sysRole, dto.ID)
    sysRole.RoleName = dto.RoleName
    sysRole.RoleKey = dto.RoleKey
    sysRole.Status = dto.Status
    if dto.Description != "" {
        sysRole.Description = dto.Description
    }
    core.Db.Save(&sysRole)
    result.Success(c, true)
}

// DeleteSysRole 根据ID删除角色
// @Summary 根据ID删除角色
// @Tags 角色相关接口
// @Produce json
// @Description 根据ID删除角色
// @Param data body model.SysRoleIdDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/delete [delete]
func DeleteSysRole(c *gin.Context) {
    var dto model.SysRoleIdDto
    _ = c.BindJSON(&dto)
    sysRoleById := GetSysAdminRole(dto.ID)
    // 如果查询到已绑定了角色,则返回删除失败
    if sysRoleById.RoleId > 0 {
        result.Failed(c, int(result.ApiCode.DelSysRoleFailed), result.ApiCode.GetMessage(result.ApiCode.DelSysRoleFailed))
        return
    }
    core.Db.Table("sys_role").Delete(&model.SysRole{}, dto.ID)
    core.Db.Table("sys_role_menu").Where("role_id = ?", dto.ID).Delete(&model.SysRoleMenu{})
    result.Success(c, true)
}

// UpdateSysRoleStatus 设置角色启用状态
// @Summary 设置角色启用状态
// @Tags 角色相关接口
// @Produce json
// @Description 设置角色启用状态
// @Param data body model.UpdateSysRoleStatusDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/updateStatus [put]
func UpdateSysRoleStatus(c *gin.Context) {
    var dto model.UpdateSysRoleStatusDto
    _ = c.BindJSON(&dto)
    var sysRole model.SysRole
    core.Db.First(&sysRole, dto.ID)
    sysRole.Status = dto.Status
    core.Db.Save(&sysRole)
    result.Success(c, true)
}

// GetSysRoleVoList 查询角色下拉列表
// @Summary 查询角色下拉列表
// @Tags 角色相关接口
// @Produce json
// @Description 查询角色下拉列表
// @Success 200 {object} result.Result
// @router /api/sysRole/vo/list [get]
func GetSysRoleVoList(c *gin.Context) {
    var sysRoleVo []model.SysRoleVo
    core.Db.Table("sys_role").Select("id, role_name").Scan(&sysRoleVo)
    result.Success(c, sysRoleVo)
}

// QueryRoleMenuIdList 根据角色ID查询菜单权限
// @Summary 根据角色ID查询菜单权限
// @Tags 角色相关接口
// @Produce json
// @Description 根据角色ID查询菜单权限
// @Param id query int true "ID"
// @Success 200 {object} result.Result
// @router /api/sysRole/vo/idList [get]
func QueryRoleMenuIdList(c *gin.Context) {
    Id, _ := strconv.Atoi(c.Query("id"))
    var idVo []model.IdVo
    const menuType = 3 // 查询深度等于三级,目录级>菜单级>按钮级
    core.Db.Table("sys_menu").
        Select("sys_menu.id").Joins("LEFT JOIN sys_role_menu ON sys_role_menu.menu_id = sys_menu.id").
        Joins("LEFT JOIN sys_role ON sys_role.id = sys_role_menu.role_id").
        Where("sys_menu.menu_type = ?", menuType).
        Where("sys_role.id = ?", Id).
        Scan(&idVo)
    var idList = make([]int, 0, 10)
    for _, id := range idVo {
        idList = append(idList, id.ID)
    }
    result.Success(c, idList)
}

// AssignPermission 分配权限
// @Summary 分配权限
// @Tags 角色相关接口
// @Produce json
// @Description 分配权限
// @Param data body model.RoleMenuDto true "data"
// @Success 200 {object} result.Result
// @router /api/sysRole/assignPermission [put]
func AssignPermission(c *gin.Context) {
    var roleMenu model.RoleMenuDto
    _ = c.BindJSON(&roleMenu)
    core.Db.Table("sys_role_menu").
        Where("role_id = ?", roleMenu.ID).
        Delete(&model.SysRoleMenu{})
    for _, value := range roleMenu.MenuIds {
        var sysRoleMenu model.SysRoleMenu
        sysRoleMenu.RoleId = roleMenu.ID
        sysRoleMenu.MenuId = value
        core.Db.Create(&value)
    }
    result.Success(c, true)
}

// GetSysRoleByName 根据角色名称查询角色数据
func GetSysRoleByName(roleName string) (sysRole model.SysRole) {
    core.Db.Where("role_name = ?", roleName).First(&sysRole)
    return sysRole
}

// GetSysRoleByKey 根据角色Key查询角色数据
func GetSysRoleByKey(roleKey string) (sysRole model.SysRole) {
    core.Db.Where("role_key = ?", roleKey).First(&sysRole)
    return sysRole
}

// GetSysAdminRole 查询是否分配角色
func GetSysAdminRole(id uint) (sysAdminRole model.SysAdminRole) {
    core.Db.Where("role_id = ?", id).First(&sysAdminRole)
    return sysAdminRole
}

下一步在 /router/router.go 中增加路由:

router.PUT("/api/sysRole/assignPermission", api.AssignPermission)

初始化swag,测试一下:

赋予一个空的权限值,然后再用刚才的查询权限的 api 测试:

数据为空,表明 id 为2的角色没有被分配任何权限,再测试一下增加权限:

再使用查询,发现查询结果是空,看来是有bug了,查看一下数据库,发现数据没有被保存进去:

再次查看代码,发现是 api 这里写错了:

for _, value := range roleMenu.MenuIds {
        var sysRoleMenu model.SysRoleMenu
        sysRoleMenu.RoleId = roleMenu.ID
        sysRoleMenu.MenuId = value
        core.Db.Create(&sysRoleMenu)
}

之前是把数据存入 &value 了,实际上应该存入到角色和菜单关系表 &sysRoleMenu

重新执行一下刚才的分配权限 api,可以看到数据库已经有数据了:

再使用查询 api 测试一下:

也能查询到数据了。