提交 2c714e28 编写于 作者: Mr.奇淼('s avatar Mr.奇淼(

增加多角色功能和角色切换功能

调整前端获取用户信息方式
上级 1c07b5e5
......@@ -9,6 +9,7 @@ import (
systemReq "gin-vue-admin/model/system/request"
systemRes "gin-vue-admin/model/system/response"
"gin-vue-admin/utils"
"strconv"
"time"
"github.com/dgrijalva/jwt-go"
......@@ -119,7 +120,13 @@ func (b *BaseApi) Register(c *gin.Context) {
response.FailWithMessage(err.Error(), c)
return
}
user := &system.SysUser{Username: r.Username, NickName: r.NickName, Password: r.Password, HeaderImg: r.HeaderImg, AuthorityId: r.AuthorityId}
var authorities []system.SysAuthority
for _, v := range r.AuthorityIds {
authorities = append(authorities, system.SysAuthority{
AuthorityId: v,
})
}
user := &system.SysUser{Username: r.Username, NickName: r.NickName, Password: r.Password, HeaderImg: r.HeaderImg, AuthorityId: r.AuthorityId, Authorities: authorities}
err, userReturn := userService.Register(*user)
if err != nil {
global.GVA_LOG.Error("注册失败!", zap.Any("err", err))
......@@ -181,7 +188,7 @@ func (b *BaseApi) GetUserList(c *gin.Context) {
}
// @Tags SysUser
// @Summary 设置用户权限
// @Summary 更改用户权限
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
......@@ -195,7 +202,39 @@ func (b *BaseApi) SetUserAuthority(c *gin.Context) {
response.FailWithMessage(UserVerifyErr.Error(), c)
return
}
if err := userService.SetUserAuthority(sua.UUID, sua.AuthorityId); err != nil {
userID := utils.GetUserID(c)
uuid := utils.GetUserUuid(c)
if err := userService.SetUserAuthority(userID, uuid, sua.AuthorityId); err != nil {
global.GVA_LOG.Error("修改失败!", zap.Any("err", err))
response.FailWithMessage(err.Error(), c)
} else {
claims := utils.GetUserInfo(c)
j := &middleware.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名
claims.AuthorityId = sua.AuthorityId
if token, err := j.CreateToken(*claims); err != nil {
global.GVA_LOG.Error("修改失败!", zap.Any("err", err))
response.FailWithMessage(err.Error(), c)
} else {
c.Header("new-token", token)
c.Header("new-expires-at", strconv.FormatInt(claims.ExpiresAt, 10))
response.OkWithMessage("修改成功", c)
}
}
}
// @Tags SysUser
// @Summary 设置用户权限
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.SetUserAuthorities true "用户UUID, 角色ID"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
// @Router /user/setUserAuthorities [post]
func (b *BaseApi) SetUserAuthorities(c *gin.Context) {
var sua systemReq.SetUserAuthorities
_ = c.ShouldBindJSON(&sua)
if err := userService.SetUserAuthorities(sua.ID, sua.AuthorityIds); err != nil {
global.GVA_LOG.Error("修改失败!", zap.Any("err", err))
response.FailWithMessage("修改失败", c)
} else {
......@@ -253,3 +292,20 @@ func (b *BaseApi) SetUserInfo(c *gin.Context) {
response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "设置成功", c)
}
}
// @Tags SysUser
// @Summary 获取用户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /user/getUserInfo [get]
func (b *BaseApi) GetUserInfo(c *gin.Context) {
uuid := utils.GetUserUuid(c)
if err, ReqUser := userService.GetUserInfo(uuid); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "获取成功", c)
}
}
......@@ -13,5 +13,14 @@ type CasbinInReceive struct {
}
func DefaultCasbin() []CasbinInfo {
return []CasbinInfo{{Path: "/menu/getMenu", Method: "POST"}, {Path: "/jwt/jsonInBlacklist", Method: "POST"}}
return []CasbinInfo{
{Path: "/menu/getMenu", Method: "POST"},
{Path: "/jwt/jsonInBlacklist", Method: "POST"},
{Path: "/base/login", Method: "POST"},
{Path: "/user/register", Method: "POST"},
{Path: "/user/changePassword", Method: "POST"},
{Path: "/user/setUserAuthority", Method: "POST"},
{Path: "/user/setUserInfo", Method: "PUT"},
{Path: "/user/getUserInfo", Method: "GET"},
}
}
package request
import uuid "github.com/satori/go.uuid"
// User register structure
type Register struct {
Username string `json:"userName"`
Password string `json:"passWord"`
NickName string `json:"nickName" gorm:"default:'QMPlusUser'"`
HeaderImg string `json:"headerImg" gorm:"default:'http://www.henrongyi.top/avatar/lufu.jpg'"`
AuthorityId string `json:"authorityId" gorm:"default:888"`
Username string `json:"userName"`
Password string `json:"passWord"`
NickName string `json:"nickName" gorm:"default:'QMPlusUser'"`
HeaderImg string `json:"headerImg" gorm:"default:'http://www.henrongyi.top/avatar/lufu.jpg'"`
AuthorityId string `json:"authorityId" gorm:"default:888"`
AuthorityIds []string `json:"authorityIds"`
}
// User login structure
......@@ -28,6 +27,11 @@ type ChangePasswordStruct struct {
// Modify user's auth structure
type SetUserAuth struct {
UUID uuid.UUID `json:"uuid"` // 用户UUID
AuthorityId string `json:"authorityId"` // 角色ID
AuthorityId string `json:"authorityId"` // 角色ID
}
// Modify user's auth structure
type SetUserAuthorities struct {
ID uint
AuthorityIds []string `json:"authorityIds"` // 角色ID
}
......@@ -7,14 +7,15 @@ import (
type SysUser struct {
global.GVA_MODEL
UUID uuid.UUID `json:"uuid" gorm:"comment:用户UUID"` // 用户UUID
Username string `json:"userName" gorm:"comment:用户登录名"` // 用户登录名
Password string `json:"-" gorm:"comment:用户登录密码"` // 用户登录密码
NickName string `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称
HeaderImg string `json:"headerImg" gorm:"default:http://qmplusimg.henrongyi.top/head.png;comment:用户头像"` // 用户头像
Authority SysAuthority `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"`
AuthorityId string `json:"authorityId" gorm:"default:888;comment:用户角色ID"` // 用户角色ID
SideMode string `json:"sideMode" gorm:"default:dark;comment:用户角色ID"` // 用户侧边主题
ActiveColor string `json:"activeColor" gorm:"default:#1890ff;comment:用户角色ID"` // 活跃颜色
BaseColor string `json:"baseColor" gorm:"default:#fff;comment:用户角色ID"` // 基础颜色
UUID uuid.UUID `json:"uuid" gorm:"comment:用户UUID"` // 用户UUID
Username string `json:"userName" gorm:"comment:用户登录名"` // 用户登录名
Password string `json:"-" gorm:"comment:用户登录密码"` // 用户登录密码
NickName string `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称
HeaderImg string `json:"headerImg" gorm:"default:http://qmplusimg.henrongyi.top/head.png;comment:用户头像"` // 用户头像
Authority SysAuthority `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"`
AuthorityId string `json:"authorityId" gorm:"default:888;comment:用户角色ID"` // 用户角色ID
SideMode string `json:"sideMode" gorm:"default:dark;comment:用户角色ID"` // 用户侧边主题
ActiveColor string `json:"activeColor" gorm:"default:#1890ff;comment:用户角色ID"` // 活跃颜色
BaseColor string `json:"baseColor" gorm:"default:#fff;comment:用户角色ID"` // 基础颜色
Authorities []SysAuthority `json:"authorities" gorm:"many2many:sys_user_authority;"`
}
package system
type SysUseAuthority struct {
SysUserId uint `gorm:"column:sys_user_id"`
SysAuthorityAuthorityId string `gorm:"column:sys_authority_authority_id"`
}
func (s *SysUseAuthority) TableName() string {
return "sys_user_authority"
}
......@@ -13,11 +13,13 @@ func (s *UserRouter) InitUserRouter(Router *gin.RouterGroup) {
userRouter := Router.Group("user").Use(middleware.OperationRecord())
var baseApi = v1.ApiGroupApp.SystemApiGroup.BaseApi
{
userRouter.POST("register", baseApi.Register) // 用户注册账号
userRouter.POST("changePassword", baseApi.ChangePassword) // 用户修改密码
userRouter.POST("getUserList", baseApi.GetUserList) // 分页获取用户列表
userRouter.POST("setUserAuthority", baseApi.SetUserAuthority) // 设置用户权限
userRouter.DELETE("deleteUser", baseApi.DeleteUser) // 删除用户
userRouter.PUT("setUserInfo", baseApi.SetUserInfo) // 设置用户信息
userRouter.POST("register", baseApi.Register) // 用户注册账号
userRouter.POST("changePassword", baseApi.ChangePassword) // 用户修改密码
userRouter.POST("getUserList", baseApi.GetUserList) // 分页获取用户列表
userRouter.POST("setUserAuthority", baseApi.SetUserAuthority) // 设置用户权限
userRouter.DELETE("deleteUser", baseApi.DeleteUser) // 删除用户
userRouter.PUT("setUserInfo", baseApi.SetUserInfo) // 设置用户信息
userRouter.POST("setUserAuthorities", baseApi.SetUserAuthorities) // 设置用户权限组
userRouter.GET("getUserInfo", baseApi.GetUserInfo) // 获取自身信息
}
}
......@@ -92,6 +92,7 @@ func (authorityService *AuthorityService) DeleteAuthority(auth *system.SysAuthor
} else {
err = db.Error
}
err = global.GVA_DB.Delete(&[]system.SysUseAuthority{}, "sys_authority_authority_id = ?", auth.AuthorityId).Error
CasbinServiceApp.ClearCasbin(0, auth.AuthorityId)
return err
}
......
......@@ -152,7 +152,9 @@ func (initDBService *InitDBService) InitDB(conf request.InitDB) error {
source.Dictionary,
source.DictionaryDetail,
source.File,
source.BaseMenu)
source.BaseMenu,
source.UserAuthority,
)
if err != nil {
global.GVA_DB = nil
return err
......
......@@ -40,7 +40,7 @@ func (userService *UserService) Register(u system.SysUser) (err error, userInter
func (userService *UserService) Login(u *system.SysUser) (err error, userInter *system.SysUser) {
var user system.SysUser
u.Password = utils.MD5V([]byte(u.Password))
err = global.GVA_DB.Where("username = ? AND password = ?", u.Username, u.Password).Preload("Authority").First(&user).Error
err = global.GVA_DB.Where("username = ? AND password = ?", u.Username, u.Password).Preload("Authorities").Preload("Authority").First(&user).Error
return err, &user
}
......@@ -69,7 +69,7 @@ func (userService *UserService) GetUserInfoList(info request.PageInfo) (err erro
db := global.GVA_DB.Model(&system.SysUser{})
var userList []system.SysUser
err = db.Count(&total).Error
err = db.Limit(limit).Offset(offset).Preload("Authority").Find(&userList).Error
err = db.Limit(limit).Offset(offset).Preload("Authorities").Preload("Authority").Find(&userList).Error
return err, userList, total
}
......@@ -79,11 +79,42 @@ func (userService *UserService) GetUserInfoList(info request.PageInfo) (err erro
//@param: uuid uuid.UUID, authorityId string
//@return: err error
func (userService *UserService) SetUserAuthority(uuid uuid.UUID, authorityId string) (err error) {
func (userService *UserService) SetUserAuthority(id uint, uuid uuid.UUID, authorityId string) (err error) {
assignErr := global.GVA_DB.Where("sys_user_id = ? AND sys_authority_authority_id = ?", id, authorityId).First(&system.SysUseAuthority{}).Error
if errors.Is(assignErr, gorm.ErrRecordNotFound) {
return errors.New("该用户无此角色")
}
err = global.GVA_DB.Where("uuid = ?", uuid).First(&system.SysUser{}).Update("authority_id", authorityId).Error
return err
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: SetUserAuthorities
//@description: 设置一个用户的权限
//@param: id uint, authorityIds []string
//@return: err error
func (userService *UserService) SetUserAuthorities(id uint, authorityIds []string) (err error) {
return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
TxErr := tx.Delete(&[]system.SysUseAuthority{}, "sys_user_id = ?", id).Error
if TxErr != nil {
return TxErr
}
useAuthority := []system.SysUseAuthority{}
for _, v := range authorityIds {
useAuthority = append(useAuthority, system.SysUseAuthority{
id, v,
})
}
TxErr = tx.Create(&useAuthority).Error
if TxErr != nil {
return TxErr
}
// 返回 nil 提交事务
return nil
})
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: DeleteUser
//@description: 删除用户
......@@ -93,6 +124,7 @@ func (userService *UserService) SetUserAuthority(uuid uuid.UUID, authorityId str
func (userService *UserService) DeleteUser(id float64) (err error) {
var user system.SysUser
err = global.GVA_DB.Where("id = ?", id).Delete(&user).Error
err = global.GVA_DB.Delete(&[]system.SysUseAuthority{}, "sys_user_id = ?", id).Error
return err
}
......@@ -107,6 +139,18 @@ func (userService *UserService) SetUserInfo(reqUser system.SysUser) (err error,
return err, reqUser
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: GetUserInfo
//@description: 获取用户信息
//@param: uuid uuid.UUID
//@return: err error, user system.SysUser
func (userService *UserService) GetUserInfo(uuid uuid.UUID) (err error, user system.SysUser) {
var reqUser system.SysUser
err = global.GVA_DB.Preload("Authorities").Preload("Authority").First(&reqUser, "uuid = ?", uuid).Error
return err, reqUser
}
//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: FindUserById
//@description: 通过id获取用户信息
......
......@@ -14,8 +14,8 @@ var Api = new(api)
type api struct{}
var apis = []system.SysApi{
{global.GVA_MODEL{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/base/login", "用户登录", "base", "POST"},
{global.GVA_MODEL{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/register", "用户注册", "user", "POST"},
{global.GVA_MODEL{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/base/login", "用户登录(必选)", "base", "POST"},
{global.GVA_MODEL{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/register", "用户注册(必选)", "user", "POST"},
{global.GVA_MODEL{ID: 3, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/api/createApi", "创建api", "api", "POST"},
{global.GVA_MODEL{ID: 4, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/api/getApiList", "获取api列表", "api", "POST"},
{global.GVA_MODEL{ID: 5, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/api/getApiById", "获取api详细信息", "api", "POST"},
......@@ -25,7 +25,7 @@ var apis = []system.SysApi{
{global.GVA_MODEL{ID: 9, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/authority/createAuthority", "创建角色", "authority", "POST"},
{global.GVA_MODEL{ID: 10, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/authority/deleteAuthority", "删除角色", "authority", "POST"},
{global.GVA_MODEL{ID: 11, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/authority/getAuthorityList", "获取角色列表", "authority", "POST"},
{global.GVA_MODEL{ID: 12, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/menu/getMenu", "获取菜单树", "menu", "POST"},
{global.GVA_MODEL{ID: 12, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/menu/getMenu", "获取菜单树(必选)", "menu", "POST"},
{global.GVA_MODEL{ID: 13, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/menu/getMenuList", "分页获取基础menu列表", "menu", "POST"},
{global.GVA_MODEL{ID: 14, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/menu/addBaseMenu", "新增菜单", "menu", "POST"},
{global.GVA_MODEL{ID: 15, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/menu/getBaseMenuTree", "获取用户动态路由", "menu", "POST"},
......@@ -34,15 +34,15 @@ var apis = []system.SysApi{
{global.GVA_MODEL{ID: 18, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/menu/deleteBaseMenu", "删除菜单", "menu", "POST"},
{global.GVA_MODEL{ID: 19, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/menu/updateBaseMenu", "更新菜单", "menu", "POST"},
{global.GVA_MODEL{ID: 20, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/menu/getBaseMenuById", "根据id获取菜单", "menu", "POST"},
{global.GVA_MODEL{ID: 21, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/changePassword", "修改密码", "user", "POST"},
{global.GVA_MODEL{ID: 21, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/changePassword", "修改密码(建议选择)", "user", "POST"},
{global.GVA_MODEL{ID: 23, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/getUserList", "获取用户列表", "user", "POST"},
{global.GVA_MODEL{ID: 24, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/setUserAuthority", "修改用户角色", "user", "POST"},
{global.GVA_MODEL{ID: 24, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/setUserAuthority", "修改用户角色(必选)", "user", "POST"},
{global.GVA_MODEL{ID: 25, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/fileUploadAndDownload/upload", "文件上传示例", "fileUploadAndDownload", "POST"},
{global.GVA_MODEL{ID: 26, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/fileUploadAndDownload/getFileList", "获取上传文件列表", "fileUploadAndDownload", "POST"},
{global.GVA_MODEL{ID: 27, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/casbin/updateCasbin", "更改角色api权限", "casbin", "POST"},
{global.GVA_MODEL{ID: 28, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/casbin/getPolicyPathByAuthorityId", "获取权限列表", "casbin", "POST"},
{global.GVA_MODEL{ID: 29, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/fileUploadAndDownload/deleteFile", "删除文件", "fileUploadAndDownload", "POST"},
{global.GVA_MODEL{ID: 30, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/jwt/jsonInBlacklist", "jwt加入黑名单(退出)", "jwt", "POST"},
{global.GVA_MODEL{ID: 30, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/jwt/jsonInBlacklist", "jwt加入黑名单(退出,必选)", "jwt", "POST"},
{global.GVA_MODEL{ID: 31, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/authority/setDataAuthority", "设置角色资源权限", "authority", "POST"},
{global.GVA_MODEL{ID: 32, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/system/getSystemConfig", "获取配置文件内容", "system", "POST"},
{global.GVA_MODEL{ID: 33, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/system/setSystemConfig", "设置配置文件内容", "system", "POST"},
......@@ -77,7 +77,7 @@ var apis = []system.SysApi{
{global.GVA_MODEL{ID: 62, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/simpleUploader/upload", "插件版分片上传", "simpleUploader", "POST"},
{global.GVA_MODEL{ID: 63, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/simpleUploader/checkFileMd5", "文件完整度验证", "simpleUploader", "GET"},
{global.GVA_MODEL{ID: 64, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/simpleUploader/mergeFileMd5", "上传完成合并文件", "simpleUploader", "GET"},
{global.GVA_MODEL{ID: 65, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/setUserInfo", "设置用户信息", "user", "PUT"},
{global.GVA_MODEL{ID: 65, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/setUserInfo", "设置用户信息(必选)", "user", "PUT"},
{global.GVA_MODEL{ID: 66, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/system/getServerInfo", "获取服务器信息", "system", "POST"},
{global.GVA_MODEL{ID: 67, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/email/emailTest", "发送测试邮件", "email", "POST"},
{global.GVA_MODEL{ID: 80, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/autoCode/preview", "预览自动化代码", "autoCode", "POST"},
......@@ -90,6 +90,8 @@ var apis = []system.SysApi{
{global.GVA_MODEL{ID: 87, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/autoCode/rollback", "回滚自动生成代码", "autoCode", "POST"},
{global.GVA_MODEL{ID: 88, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/autoCode/getMeta", "获取meta信息", "autoCode", "POST"},
{global.GVA_MODEL{ID: 89, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/autoCode/delSysHistory", "删除回滚记录", "autoCode", "POST"},
{global.GVA_MODEL{ID: 90, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/setUserAuthorities", "设置权限组", "user", "POST"},
{global.GVA_MODEL{ID: 91, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/getUserInfo", "获取自身信息(必选)", "user", "GET"},
}
//@author: [SliverHorn](https://github.com/SliverHorn)
......
......@@ -90,6 +90,8 @@ var carbines = []gormadapter.CasbinRule{
{PType: "p", V0: "888", V1: "/autoCode/rollback", V2: "POST"},
{PType: "p", V0: "888", V1: "/autoCode/getMeta", V2: "POST"},
{PType: "p", V0: "888", V1: "/autoCode/delSysHistory", V2: "POST"},
{PType: "p", V0: "888", V1: "/user/setUserAuthorities", V2: "POST"},
{PType: "p", V0: "888", V1: "/user/getUserInfo", V2: "GET"},
{PType: "p", V0: "8881", V1: "/base/login", V2: "POST"},
{PType: "p", V0: "8881", V1: "/user/register", V2: "POST"},
{PType: "p", V0: "8881", V1: "/api/createApi", V2: "POST"},
......@@ -127,6 +129,7 @@ var carbines = []gormadapter.CasbinRule{
{PType: "p", V0: "8881", V1: "/customer/customer", V2: "DELETE"},
{PType: "p", V0: "8881", V1: "/customer/customer", V2: "GET"},
{PType: "p", V0: "8881", V1: "/customer/customerList", V2: "GET"},
{PType: "p", V0: "8881", V1: "/user/getUserInfo", V2: "GET"},
{PType: "p", V0: "9528", V1: "/base/login", V2: "POST"},
{PType: "p", V0: "9528", V1: "/user/register", V2: "POST"},
{PType: "p", V0: "9528", V1: "/api/createApi", V2: "POST"},
......@@ -165,6 +168,7 @@ var carbines = []gormadapter.CasbinRule{
{PType: "p", V0: "9528", V1: "/customer/customer", V2: "GET"},
{PType: "p", V0: "9528", V1: "/customer/customerList", V2: "GET"},
{PType: "p", V0: "9528", V1: "/autoCode/createTemp", V2: "POST"},
{PType: "p", V0: "9528", V1: "/user/getUserInfo", V2: "GET"},
}
//@author: [SliverHorn](https://github.com/SliverHorn)
......
package source
import (
"gin-vue-admin/global"
"gin-vue-admin/model/system"
"github.com/gookit/color"
"gorm.io/gorm"
)
var UserAuthority = new(userAuthority)
type userAuthority struct{}
var userAuthorityModel = []system.SysUseAuthority{
{1, "888"},
{1, "8881"},
{1, "9528"},
{2, "888"},
}
//@description: user_authority 数据初始化
func (a *userAuthority) Init() error {
return global.GVA_DB.Model(&system.SysUseAuthority{}).Transaction(func(tx *gorm.DB) error {
if tx.Where("sys_user_id IN (1, 2)").Find(&[]AuthorityMenus{}).RowsAffected == 4 {
color.Danger.Println("\n[Mysql] --> sys_user_authority 表的初始数据已存在!")
return nil
}
if err := tx.Create(&userAuthorityModel).Error; err != nil { // 遇到错误时回滚事务
return err
}
color.Info.Println("\n[Mysql] --> sys_user_authority 表初始数据成功!")
return nil
})
}
......@@ -4,6 +4,7 @@ import (
"gin-vue-admin/global"
systemReq "gin-vue-admin/model/system/request"
"github.com/gin-gonic/gin"
uuid "github.com/satori/go.uuid"
)
// 从Gin的Context中获取从jwt解析出来的用户ID
......@@ -18,13 +19,13 @@ func GetUserID(c *gin.Context) uint {
}
// 从Gin的Context中获取从jwt解析出来的用户UUID
func GetUserUuid(c *gin.Context) string {
func GetUserUuid(c *gin.Context) uuid.UUID {
if claims, exists := c.Get("claims"); !exists {
global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!")
return ""
return uuid.UUID{}
} else {
waitUse := claims.(*systemReq.CustomClaims)
return waitUse.UUID.String()
return waitUse.UUID
}
}
......@@ -38,3 +39,14 @@ func GetUserAuthorityId(c *gin.Context) string {
return waitUse.AuthorityId
}
}
// 从Gin的Context中获取从jwt解析出来的用户角色id
func GetUserInfo(c *gin.Context) *systemReq.CustomClaims {
if claims, exists := c.Get("claims"); !exists {
global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!")
return nil
} else {
waitUse := claims.(*systemReq.CustomClaims)
return waitUse
}
}
......@@ -14,5 +14,5 @@ var (
AuthorityIdVerify = Rules{"AuthorityId": {NotEmpty()}}
OldAuthorityVerify = Rules{"OldAuthorityId": {NotEmpty()}}
ChangePasswordVerify = Rules{"Username": {NotEmpty()}, "Password": {NotEmpty()}, "NewPassword": {NotEmpty()}}
SetUserAuthorityVerify = Rules{"UUID": {NotEmpty()}, "AuthorityId": {NotEmpty()}}
SetUserAuthorityVerify = Rules{"AuthorityId": {NotEmpty()}}
)
......@@ -111,3 +111,33 @@ export const setUserInfo = (data) => {
data: data
})
}
// @Tags User
// @Summary 设置用户权限
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body api.setUserAuthorities true "设置用户权限"
// @Success 200 {string} json "{"success":true,"data":{},"msg":"修改成功"}"
// @Router /user/setUserAuthorities [post]
export const setUserAuthorities = (data) => {
return service({
url: '/user/setUserAuthorities',
method: 'post',
data: data
})
}
// @Tags User
// @Summary 获取用户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /user/getUserInfo [get]
export const getUserInfo = () => {
return service({
url: '/user/getUserInfo',
method: 'get'
})
}
......@@ -23,6 +23,7 @@ router.beforeEach(async(to, from, next) => {
if (!asyncRouterFlag && store.getters['router/asyncRouters'].length === 0) {
asyncRouterFlag++
await store.dispatch('router/SetAsyncRouter')
await store.dispatch('user/GetUserInfo')
const asyncRouters = store.getters['router/asyncRouters']
router.addRoutes(asyncRouters)
next({ ...to, replace: true })
......
import { login } from '@/api/user'
import { login, getUserInfo } from '@/api/user'
import { jsonInBlacklist } from '@/api/jwt'
import router from '@/router/index'
import { setUserInfo } from '@/api/user'
......@@ -56,6 +56,13 @@ export const user = {
}
},
actions: {
async GetUserInfo({ commit }) {
const res = await getUserInfo()
if (res.code === 0) {
commit('setUserInfo', res.data.userInfo)
}
return res
},
async LoginIn({ commit, dispatch, rootGetters, getters }, loginInfo) {
const res = await login(loginInfo)
if (res.code === 0) {
......
......@@ -45,11 +45,17 @@
</span>
<el-dropdown-menu slot="dropdown" class="dropdown-group">
<el-dropdown-item>
<span>
更多信息
<el-badge is-dot />
<span style="font-weight: 600;">
当前角色:{{ userInfo.authority.authorityName }}
</span>
</el-dropdown-item>
<template v-if="userInfo.authorities">
<el-dropdown-item v-for="item in userInfo.authorities.filter(i=>i.authorityId!==userInfo.authorityId)" :key="item.authorityId" @click.native="changeUserAuth(item.authorityId)">
<span>
切换为:{{ item.authorityName }}
</span>
</el-dropdown-item>
</template>
<el-dropdown-item icon="el-icon-s-custom" @click.native="toPerson">个人信息</el-dropdown-item>
<el-dropdown-item icon="el-icon-table-lamp" @click.native="LoginOut">登 出</el-dropdown-item>
</el-dropdown-menu>
......@@ -90,6 +96,7 @@ import BottomInfo from '@/view/layout/bottomInfo/bottomInfo'
import { mapGetters, mapActions } from 'vuex'
import CustomPic from '@/components/customPic'
import Setting from './setting'
import { setUserAuthority } from '@/api/user'
export default {
name: 'Layout',
components: {
......@@ -186,7 +193,15 @@ export default {
}
},
methods: {
...mapActions('user', ['LoginOut']),
...mapActions('user', ['LoginOut', 'GetUserInfo']),
async changeUserAuth(id) {
const res = await setUserAuthority({
authorityId: id
})
if (res.code === 0) {
window.location.reload()
}
},
reload() {
this.reloadFlag = false
this.$nextTick(() => {
......
......@@ -43,6 +43,7 @@
</template>
</el-table-column>
</el-table>
<span style="color: red;font-size: 12px">注:右上角头像下拉可切换角色</span>
<!-- 新增角色弹窗 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogFormVisible">
<el-form ref="authorityForm" :model="form" :rules="rules">
......
......@@ -17,12 +17,14 @@
<el-table-column label="用户角色" min-width="150">
<template slot-scope="scope">
<el-cascader
v-model="scope.row.authority.authorityId"
v-model="scope.row.authorityIds"
:options="authOptions"
:show-all-levels="false"
:props="{ checkStrictly: true,label:'authorityName',value:'authorityId',disabled:'disabled',emitPath:false}"
:props="{ multiple:true,checkStrictly: true,label:'authorityName',value:'authorityId',disabled:'disabled',emitPath:false}"
filterable
@change="changeAuthority(scope.row)"
:clearable="false"
@visible-change="(flag)=>{changeAuthority(scope.row,flag)}"
@remove-tag="()=>{changeAuthority(scope.row,false)}"
/>
</template>
</el-table-column>
......@@ -39,6 +41,7 @@
</template>
</el-table-column>
</el-table>
<span style="color: red;font-size: 12px">注:右上角头像下拉可切换角色</span>
<el-pagination
:current-page="page"
:page-size="pageSize"
......@@ -69,11 +72,12 @@
</el-form-item>
<el-form-item label="用户角色" label-width="80px" prop="authorityId">
<el-cascader
v-model="userInfo.authorityId"
v-model="userInfo.authorityIds"
:options="authOptions"
:show-all-levels="false"
:props="{ checkStrictly: true,label:'authorityName',value:'authorityId',disabled:'disabled',emitPath:false}"
:props="{ multiple:true,checkStrictly: true,label:'authorityName',value:'authorityId',disabled:'disabled',emitPath:false}"
filterable
:clearable="false"
/>
</el-form-item>
</el-form>
......@@ -91,7 +95,7 @@
const path = process.env.VUE_APP_BASE_API
import {
getUserList,
setUserAuthority,
setUserAuthorities,
register,
deleteUser
} from '@/api/user'
......@@ -115,7 +119,8 @@ export default {
password: '',
nickName: '',
headerImg: '',
authorityId: ''
authorityId: '',
authorityIds: []
},
rules: {
username: [
......@@ -139,11 +144,20 @@ export default {
...mapGetters('user', ['token'])
},
async created() {
this.getTableData()
await this.getTableData()
this.setAuthorityIds()
const res = await getAuthorityList({ page: 1, pageSize: 999 })
this.setOptions(res.data.list)
},
methods: {
setAuthorityIds() {
this.tableData && this.tableData.forEach((user) => {
const authorityIds = user.authorities && user.authorities.map(i => {
return i.authorityId
})
this.$set(user, 'authorityIds', authorityIds)
})
},
openHeaderChange() {
this.$refs.chooseImg.open()
},
......@@ -174,11 +188,14 @@ export default {
async deleteUser(row) {
const res = await deleteUser({ id: row.ID })
if (res.code === 0) {
this.getTableData()
this.$message.success('删除成功')
await this.getTableData()
this.setAuthorityIds()
row.visible = false
}
},
async enterAddUserDialog() {
this.userInfo.authorityId = this.userInfo.authorityIds[0]
this.$refs.userForm.validate(async valid => {
if (valid) {
const res = await register(this.userInfo)
......@@ -186,6 +203,7 @@ export default {
this.$message({ type: 'success', message: '创建成功' })
}
await this.getTableData()
this.setAuthorityIds()
this.closeAddUserDialog()
}
})
......@@ -194,20 +212,22 @@ export default {
this.$refs.userForm.resetFields()
this.addUserDialog = false
},
handleAvatarSuccess(res) {
this.userInfo.headerImg = res.data.file.url
},
addUser() {
this.addUserDialog = true
},
async changeAuthority(row) {
const res = await setUserAuthority({
uuid: row.uuid,
authorityId: row.authority.authorityId
})
if (res.code === 0) {
this.$message({ type: 'success', message: '角色设置成功' })
async changeAuthority(row, flag) {
if (flag) {
return
}
this.$nextTick(async() => {
const res = await setUserAuthorities({
ID: row.ID,
authorityIds: row.authorityIds
})
if (res.code === 0) {
this.$message({ type: 'success', message: '角色设置成功' })
}
})
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册