From 2c714e288bb1d10864966f9a625a29a0c4f89c0c Mon Sep 17 00:00:00 2001
From: pixel <303176530@qq.com>
Date: Thu, 22 Jul 2021 16:46:09 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=A4=9A=E8=A7=92=E8=89=B2?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=92=8C=E8=A7=92=E8=89=B2=E5=88=87=E6=8D=A2?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD=20=E8=B0=83=E6=95=B4=E5=89=8D=E7=AB=AF?=
=?UTF-8?q?=E8=8E=B7=E5=8F=96=E7=94=A8=E6=88=B7=E4=BF=A1=E6=81=AF=E6=96=B9?=
=?UTF-8?q?=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
server/api/v1/system/sys_user.go | 62 ++++++++++++++++++-
server/model/system/request/sys_casbin.go | 11 +++-
server/model/system/request/sys_user.go | 22 ++++---
server/model/system/sys_user.go | 21 ++++---
server/model/system/sys_user_authority.go | 10 +++
server/router/system/sys_user.go | 14 +++--
server/service/system/sys_authority.go | 1 +
server/service/system/sys_initdb.go | 4 +-
server/service/system/sys_user.go | 50 ++++++++++++++-
server/source/api.go | 16 ++---
server/source/casbin.go | 4 ++
server/source/user_authority.go.go | 34 ++++++++++
server/utils/clamis.go | 18 +++++-
server/utils/verify.go | 2 +-
web/src/api/user.js | 30 +++++++++
web/src/permission.js | 1 +
web/src/store/module/user.js | 9 ++-
web/src/view/layout/index.vue | 23 +++++--
.../view/superAdmin/authority/authority.vue | 1 +
web/src/view/superAdmin/user/user.vue | 58 +++++++++++------
20 files changed, 323 insertions(+), 68 deletions(-)
create mode 100644 server/model/system/sys_user_authority.go
create mode 100644 server/source/user_authority.go.go
diff --git a/server/api/v1/system/sys_user.go b/server/api/v1/system/sys_user.go
index 45d008ac..f627aa5c 100644
--- a/server/api/v1/system/sys_user.go
+++ b/server/api/v1/system/sys_user.go
@@ -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)
+ }
+}
diff --git a/server/model/system/request/sys_casbin.go b/server/model/system/request/sys_casbin.go
index 40ac21cd..d0031dcf 100644
--- a/server/model/system/request/sys_casbin.go
+++ b/server/model/system/request/sys_casbin.go
@@ -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"},
+ }
}
diff --git a/server/model/system/request/sys_user.go b/server/model/system/request/sys_user.go
index f2b147ed..84ab1ef4 100644
--- a/server/model/system/request/sys_user.go
+++ b/server/model/system/request/sys_user.go
@@ -1,14 +1,13 @@
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
}
diff --git a/server/model/system/sys_user.go b/server/model/system/sys_user.go
index aeb2acd6..1fccf157 100644
--- a/server/model/system/sys_user.go
+++ b/server/model/system/sys_user.go
@@ -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;"`
}
diff --git a/server/model/system/sys_user_authority.go b/server/model/system/sys_user_authority.go
new file mode 100644
index 00000000..ba37605a
--- /dev/null
+++ b/server/model/system/sys_user_authority.go
@@ -0,0 +1,10 @@
+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"
+}
diff --git a/server/router/system/sys_user.go b/server/router/system/sys_user.go
index 24aef143..25455d6b 100644
--- a/server/router/system/sys_user.go
+++ b/server/router/system/sys_user.go
@@ -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) // 获取自身信息
}
}
diff --git a/server/service/system/sys_authority.go b/server/service/system/sys_authority.go
index 33138e1a..8881ffcc 100644
--- a/server/service/system/sys_authority.go
+++ b/server/service/system/sys_authority.go
@@ -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
}
diff --git a/server/service/system/sys_initdb.go b/server/service/system/sys_initdb.go
index 265f0075..91ac5ba5 100644
--- a/server/service/system/sys_initdb.go
+++ b/server/service/system/sys_initdb.go
@@ -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
diff --git a/server/service/system/sys_user.go b/server/service/system/sys_user.go
index e3b44992..894c3e56 100644
--- a/server/service/system/sys_user.go
+++ b/server/service/system/sys_user.go
@@ -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获取用户信息
diff --git a/server/source/api.go b/server/source/api.go
index e97e952c..d46d7668 100644
--- a/server/source/api.go
+++ b/server/source/api.go
@@ -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)
diff --git a/server/source/casbin.go b/server/source/casbin.go
index 59036c24..909bb2d2 100644
--- a/server/source/casbin.go
+++ b/server/source/casbin.go
@@ -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)
diff --git a/server/source/user_authority.go.go b/server/source/user_authority.go.go
new file mode 100644
index 00000000..197675c9
--- /dev/null
+++ b/server/source/user_authority.go.go
@@ -0,0 +1,34 @@
+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
+ })
+}
diff --git a/server/utils/clamis.go b/server/utils/clamis.go
index 1238331b..71deb93d 100644
--- a/server/utils/clamis.go
+++ b/server/utils/clamis.go
@@ -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
+ }
+}
diff --git a/server/utils/verify.go b/server/utils/verify.go
index 9e5796f7..2725d473 100644
--- a/server/utils/verify.go
+++ b/server/utils/verify.go
@@ -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()}}
)
diff --git a/web/src/api/user.js b/web/src/api/user.js
index a833888c..32ee55c1 100644
--- a/web/src/api/user.js
+++ b/web/src/api/user.js
@@ -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'
+ })
+}
diff --git a/web/src/permission.js b/web/src/permission.js
index eef9e364..676240a8 100644
--- a/web/src/permission.js
+++ b/web/src/permission.js
@@ -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 })
diff --git a/web/src/store/module/user.js b/web/src/store/module/user.js
index 82ee944b..0e7908f9 100644
--- a/web/src/store/module/user.js
+++ b/web/src/store/module/user.js
@@ -1,4 +1,4 @@
-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) {
diff --git a/web/src/view/layout/index.vue b/web/src/view/layout/index.vue
index ae2a965d..7bb7d08b 100644
--- a/web/src/view/layout/index.vue
+++ b/web/src/view/layout/index.vue
@@ -45,11 +45,17 @@
-
- 更多信息
-
+
+ 当前角色:{{ userInfo.authority.authorityName }}
+
+
+
+ 切换为:{{ item.authorityName }}
+
+
+
个人信息
登 出
@@ -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(() => {
diff --git a/web/src/view/superAdmin/authority/authority.vue b/web/src/view/superAdmin/authority/authority.vue
index a04cedc4..8497af11 100644
--- a/web/src/view/superAdmin/authority/authority.vue
+++ b/web/src/view/superAdmin/authority/authority.vue
@@ -43,6 +43,7 @@
+ 注:右上角头像下拉可切换角色
diff --git a/web/src/view/superAdmin/user/user.vue b/web/src/view/superAdmin/user/user.vue
index 169f2342..7ecdc717 100644
--- a/web/src/view/superAdmin/user/user.vue
+++ b/web/src/view/superAdmin/user/user.vue
@@ -17,12 +17,14 @@
{changeAuthority(scope.row,flag)}"
+ @remove-tag="()=>{changeAuthority(scope.row,false)}"
/>
@@ -39,6 +41,7 @@
+ 注:右上角头像下拉可切换角色
@@ -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: '角色设置成功' })
+ }
+ })
}
}
}