diff --git a/api/handler/admin/admin_role_handler.go b/api/handler/admin/admin_role_handler.go new file mode 100644 index 00000000..9d7605a8 --- /dev/null +++ b/api/handler/admin/admin_role_handler.go @@ -0,0 +1,145 @@ +package admin + +import ( + "chatplus/core" + "chatplus/core/types" + "chatplus/handler" + "chatplus/store/model" + "chatplus/store/vo" + "chatplus/utils" + "chatplus/utils/resp" + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type SysRoleHandler struct { + handler.BaseHandler + db *gorm.DB +} + +func NewSysRoleHandler(app *core.AppServer, db *gorm.DB) *SysRoleHandler { + h := SysRoleHandler{db: db} + h.App = app + return &h +} + +type permission struct { + Id int `json:"id"` + Name string `json:"name"` +} + +func (h *SysRoleHandler) List(c *gin.Context) { + var items []model.AdminRole + var data = make([]vo.AdminRole, 0) + res := h.db.Find(&items) + if res.Error != nil { + resp.ERROR(c, "暂无数据") + return + } + for _, item := range items { + adminRoleVo := vo.AdminRole{} + err := utils.CopyObject(item, &adminRoleVo) + if err == nil { + var permissions []permission + h.db.Raw("SELECT p.id,p.name "+ + "FROM chatgpt_admin_role_permissions as rp "+ + "LEFT JOIN chatgpt_admin_permissions as p ON rp.permission_id = p.id "+ + "WHERE rp.role_id = ?", item.Id).Scan(&permissions) + adminRoleVo.Permissions = permissions + adminRoleVo.CreatedAt = item.CreatedAt.Format("2006-01-02 15:04:05") + data = append(data, adminRoleVo) + } + } + resp.SUCCESS(c, data) +} + +func (h *SysRoleHandler) Save(c *gin.Context) { + var data struct { + Id int + Name string + Description string + Permissions []int + } + if err := c.ShouldBindJSON(&data); err != nil { + resp.ERROR(c, types.InvalidArgs) + return + } + + var role = model.AdminRole{} + var res *gorm.DB + tx := h.db.Begin() + if data.Id > 0 { // 更新 + role.Id = data.Id + //删除角色对应的权限 + err := tx.Where("role_id = ?", role.Id).Delete(model.AdminRolePermission{}) + if err.Error != nil { + tx.Rollback() + resp.ERROR(c, "更新数据库失败") + return + } + //更新角色名 + res = tx.Model(&role).Updates(map[string]interface{}{ + "name": data.Name, + "description": data.Description, + }) + } else { + //新建角色 + role.Name = data.Name + role.Description = data.Description + res = tx.Create(&role) + } + + if res.Error != nil { + tx.Rollback() + resp.ERROR(c, "更新数据库失败") + return + } + + rp := make([]model.AdminRolePermission, 0) + if len(data.Permissions) > 0 { + for _, per := range data.Permissions { + rp = append(rp, model.AdminRolePermission{ + RoleId: role.Id, + PermissionId: per, + }) + } + res2 := tx.CreateInBatches(rp, len(rp)) + if res2.Error != nil { + tx.Rollback() + resp.ERROR(c, "更新数据库失败") + return + } + } + + tx.Commit() + + resp.SUCCESS(c) +} + +func (h *SysRoleHandler) Remove(c *gin.Context) { + var data struct { + Id int + } + if err := c.ShouldBindJSON(&data); err != nil { + resp.ERROR(c, types.InvalidArgs) + return + } + + if data.Id > 0 { + tx := h.db.Begin() + res := tx.Where("id = ?", data.Id).Delete(&model.AdminRole{}) + if res.Error != nil { + tx.Rollback() + resp.ERROR(c, "删除失败") + return + } + res = tx.Where("role_id = ?", data.Id).Delete(&model.AdminRolePermission{}) + if res.Error != nil { + tx.Rollback() + resp.ERROR(c, "删除失败") + return + } + tx.Commit() + } + resp.SUCCESS(c) +} diff --git a/api/handler/admin/admin_user_handler.go b/api/handler/admin/admin_user_handler.go index 4a951ec3..2a50c203 100644 --- a/api/handler/admin/admin_user_handler.go +++ b/api/handler/admin/admin_user_handler.go @@ -23,6 +23,11 @@ func NewSysUserHandler(app *core.AppServer, db *gorm.DB) *SysUserHandler { return &h } +type role struct { + Id int `json:"id"` + Name string `json:"name"` +} + // List 用户列表 func (h *SysUserHandler) List(c *gin.Context) { page := h.GetInt(c, "page", 1) @@ -48,9 +53,16 @@ func (h *SysUserHandler) List(c *gin.Context) { var userVo vo.AdminUser err := utils.CopyObject(item, &userVo) if err == nil { + var roles []role + h.db.Raw("SELECT r.id,r.name "+ + "FROM chatgpt_admin_user_roles as ur "+ + "LEFT JOIN chatgpt_admin_roles as r ON ur.role_id = r.id "+ + "WHERE ur.admin_id = ?", item.Id).Scan(&roles) + userVo.Id = item.Id userVo.CreatedAt = item.CreatedAt.Unix() userVo.UpdatedAt = item.UpdatedAt.Unix() + userVo.RoleIds = roles users = append(users, userVo) } else { logger.Error(err) @@ -68,6 +80,7 @@ func (h *SysUserHandler) Save(c *gin.Context) { Password string `json:"password"` Username string `json:"username"` Status bool `json:"status"` + RoleIds []int `json:"role_ids"` } if err := c.ShouldBindJSON(&data); err != nil { resp.ERROR(c, types.InvalidArgs) @@ -83,31 +96,58 @@ func (h *SysUserHandler) Save(c *gin.Context) { var user = model.AdminUser{} var res *gorm.DB var userVo vo.AdminUser + + tx := h.db.Begin() + if data.Id > 0 { // 更新 user.Id = data.Id + err := tx.Where("admin_id = ?", user.Id).Delete(&model.AdminUserRole{}) + if err.Error != nil { + tx.Rollback() + resp.ERROR(c, "更新数据库失败") + return + } // 此处需要用 map 更新,用结构体无法更新 0 值 - res = h.db.Model(&user).Updates(map[string]interface{}{ + res = tx.Model(&user).Updates(map[string]interface{}{ "username": data.Username, "status": data.Status, }) } else { salt := utils.RandString(8) - u := model.AdminUser{ - Username: data.Username, - Password: utils.GenPassword(data.Password, salt), - Salt: salt, - Status: true, - } - res = h.db.Create(&u) - _ = utils.CopyObject(u, &userVo) - userVo.Id = u.Id - userVo.CreatedAt = u.CreatedAt.Unix() - userVo.UpdatedAt = u.UpdatedAt.Unix() + + user.Username = data.Username + user.Password = utils.GenPassword(data.Password, salt) + user.Salt = salt + user.Status = true + + res = tx.Create(&user) + _ = utils.CopyObject(user, &userVo) + userVo.Id = user.Id + userVo.CreatedAt = user.CreatedAt.Unix() + userVo.UpdatedAt = user.UpdatedAt.Unix() } if res.Error != nil { + tx.Rollback() resp.ERROR(c, "更新数据库失败") return } + // 添加角色 + userRole := make([]model.AdminUserRole, 0) + if len(data.RoleIds) > 0 { + for _, roleId := range data.RoleIds { + userRole = append(userRole, model.AdminUserRole{ + AdminId: user.Id, + RoleId: roleId, + }) + } + err := tx.CreateInBatches(userRole, len(userRole)) + if err.Error != nil { + tx.Rollback() + resp.ERROR(c, "更新数据库失败") + return + } + } + tx.Commit() resp.SUCCESS(c, userVo) } @@ -155,11 +195,20 @@ func (h *SysUserHandler) Remove(c *gin.Context) { return } if data.Id > 0 { - res := h.db.Where("id = ?", data.Id).Delete(&model.AdminUser{}) + tx := h.db.Begin() + res := tx.Where("id = ?", data.Id).Delete(&model.AdminUser{}) if res.Error != nil { + tx.Rollback() resp.ERROR(c, "删除失败") return } + res2 := tx.Where("admin_id = ?", data.Id).Delete(&model.AdminUserRole{}) + if res2.Error != nil { + tx.Rollback() + resp.ERROR(c, "删除失败") + return + } + tx.Commit() } resp.SUCCESS(c) } diff --git a/api/main.go b/api/main.go index 7f995a21..cc194f60 100644 --- a/api/main.go +++ b/api/main.go @@ -392,6 +392,7 @@ func main() { group.POST("remove", h.Remove) group.POST("resetPass", h.ResetPass) }), + // 权限 fx.Provide(admin.NewSysPermissionHandler), fx.Invoke(func(s *core.AppServer, h *admin.SysPermissionHandler) { group := s.Engine.Group("/api/admin/sysPermission/") @@ -399,6 +400,14 @@ func main() { group.POST("save", h.Save) group.POST("remove", h.Remove) }), + // 角色 + fx.Provide(admin.NewSysRoleHandler), + fx.Invoke(func(s *core.AppServer, h *admin.SysRoleHandler) { + group := s.Engine.Group("/api/admin/sysRole/") + group.GET("list", h.List) + group.POST("save", h.Save) + group.POST("remove", h.Remove) + }), fx.Provide(handler.NewFunctionHandler), fx.Invoke(func(s *core.AppServer, h *handler.FunctionHandler) { diff --git a/api/store/model/admin_role.go b/api/store/model/admin_role.go new file mode 100644 index 00000000..ce633545 --- /dev/null +++ b/api/store/model/admin_role.go @@ -0,0 +1,11 @@ +package model + +import "time" + +type AdminRole struct { + Id int `gorm:"primarykey;column:id"` + Name string + Description string + CreatedAt time.Time + UpdatedAt time.Time +} diff --git a/api/store/model/admin_role_permission.go b/api/store/model/admin_role_permission.go new file mode 100644 index 00000000..a436e594 --- /dev/null +++ b/api/store/model/admin_role_permission.go @@ -0,0 +1,11 @@ +package model + +import "time" + +type AdminRolePermission struct { + Id int `gorm:"primarykey;column:id"` + RoleId int + PermissionId int + CreatedAt time.Time + UpdatedAt time.Time +} diff --git a/api/store/model/admin_user_role.go b/api/store/model/admin_user_role.go new file mode 100644 index 00000000..93b010a4 --- /dev/null +++ b/api/store/model/admin_user_role.go @@ -0,0 +1,11 @@ +package model + +import "time" + +type AdminUserRole struct { + Id int `gorm:"primarykey;column:id"` + AdminId uint + RoleId int + CreatedAt time.Time + UpdatedAt time.Time +} diff --git a/api/store/vo/admin_role.go b/api/store/vo/admin_role.go new file mode 100644 index 00000000..c378f701 --- /dev/null +++ b/api/store/vo/admin_role.go @@ -0,0 +1,9 @@ +package vo + +type AdminRole struct { + Id int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Permissions interface{} `json:"permissions"` + CreatedAt string `json:"created_at"` +} diff --git a/api/store/vo/admin_user.go b/api/store/vo/admin_user.go index 70c4a9ea..24403be5 100644 --- a/api/store/vo/admin_user.go +++ b/api/store/vo/admin_user.go @@ -2,8 +2,9 @@ package vo type AdminUser struct { BaseVo - Username string `json:"username"` - Status bool `json:"status"` // 当前状态 - LastLoginAt int64 `json:"last_login_at"` // 最后登录时间 - LastLoginIp string `json:"last_login_ip"` // 最后登录 IP + Username string `json:"username"` + Status bool `json:"status"` // 当前状态 + LastLoginAt int64 `json:"last_login_at"` // 最后登录时间 + LastLoginIp string `json:"last_login_ip"` // 最后登录 IP + RoleIds interface{} `json:"role_ids"` //角色ids }