328 lines
10 KiB
Go
328 lines
10 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"github.com/duke-git/lancet/v2/convertor"
|
|
"go.uber.org/zap"
|
|
v1 "nunu-layout-admin/api/v1"
|
|
"nunu-layout-admin/internal/model"
|
|
"strings"
|
|
)
|
|
|
|
type AdminRepository interface {
|
|
GetAdminUsers(ctx context.Context, req *v1.GetAdminUsersRequest) ([]model.AdminUser, int64, error)
|
|
GetAdminUser(ctx context.Context, uid uint) (model.AdminUser, error)
|
|
GetAdminUserByUsername(ctx context.Context, username string) (model.AdminUser, error)
|
|
AdminUserUpdate(ctx context.Context, m *model.AdminUser) error
|
|
AdminUserCreate(ctx context.Context, m *model.AdminUser) error
|
|
AdminUserDelete(ctx context.Context, id uint) error
|
|
|
|
GetUserPermissions(ctx context.Context, uid uint) ([][]string, error)
|
|
GetUserRoles(ctx context.Context, uid uint) ([]string, error)
|
|
GetRolePermissions(ctx context.Context, role string) ([][]string, error)
|
|
UpdateRolePermission(ctx context.Context, role string, permissions map[string]struct{}) error
|
|
UpdateUserRoles(ctx context.Context, uid uint, roles []string) error
|
|
DeleteUserRoles(ctx context.Context, uid uint) error
|
|
|
|
GetMenuList(ctx context.Context) ([]model.Menu, error)
|
|
MenuUpdate(ctx context.Context, m *model.Menu) error
|
|
MenuCreate(ctx context.Context, m *model.Menu) error
|
|
MenuDelete(ctx context.Context, id uint) error
|
|
|
|
GetRoles(ctx context.Context, req *v1.GetRoleListRequest) ([]model.Role, int64, error)
|
|
RoleUpdate(ctx context.Context, m *model.Role) error
|
|
RoleCreate(ctx context.Context, m *model.Role) error
|
|
RoleDelete(ctx context.Context, id uint) error
|
|
CasbinRoleDelete(ctx context.Context, role string) error
|
|
GetRole(ctx context.Context, id uint) (model.Role, error)
|
|
GetRoleBySid(ctx context.Context, sid string) (model.Role, error)
|
|
|
|
GetApis(ctx context.Context, req *v1.GetApisRequest) ([]model.Api, int64, error)
|
|
GetApiGroups(ctx context.Context) ([]string, error)
|
|
ApiUpdate(ctx context.Context, m *model.Api) error
|
|
ApiCreate(ctx context.Context, m *model.Api) error
|
|
ApiDelete(ctx context.Context, id uint) error
|
|
}
|
|
|
|
func NewAdminRepository(
|
|
repository *Repository,
|
|
) AdminRepository {
|
|
return &adminRepository{
|
|
Repository: repository,
|
|
}
|
|
}
|
|
|
|
type adminRepository struct {
|
|
*Repository
|
|
}
|
|
|
|
func (r *adminRepository) CasbinRoleDelete(ctx context.Context, role string) error {
|
|
_, err := r.e.DeleteRole(role)
|
|
return err
|
|
}
|
|
|
|
func (r *adminRepository) GetRole(ctx context.Context, id uint) (model.Role, error) {
|
|
m := model.Role{}
|
|
return m, r.DB(ctx).Where("id = ?", id).First(&m).Error
|
|
}
|
|
func (r *adminRepository) GetRoleBySid(ctx context.Context, sid string) (model.Role, error) {
|
|
m := model.Role{}
|
|
return m, r.DB(ctx).Where("sid = ?", sid).First(&m).Error
|
|
}
|
|
|
|
func (r *adminRepository) DeleteUserRoles(ctx context.Context, uid uint) error {
|
|
_, err := r.e.DeleteRolesForUser(convertor.ToString(uid))
|
|
return err
|
|
}
|
|
func (r *adminRepository) UpdateUserRoles(ctx context.Context, uid uint, roles []string) error {
|
|
if len(roles) == 0 {
|
|
_, err := r.e.DeleteRolesForUser(convertor.ToString(uid))
|
|
return err
|
|
}
|
|
old, err := r.e.GetRolesForUser(convertor.ToString(uid))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
oldMap := make(map[string]struct{})
|
|
newMap := make(map[string]struct{})
|
|
for _, v := range old {
|
|
oldMap[v] = struct{}{}
|
|
}
|
|
for _, v := range roles {
|
|
newMap[v] = struct{}{}
|
|
}
|
|
addRoles := make([]string, 0)
|
|
delRoles := make([]string, 0)
|
|
|
|
for key, _ := range oldMap {
|
|
if _, exists := newMap[key]; !exists {
|
|
delRoles = append(delRoles, key)
|
|
}
|
|
}
|
|
for key, _ := range newMap {
|
|
if _, exists := oldMap[key]; !exists {
|
|
addRoles = append(addRoles, key)
|
|
}
|
|
}
|
|
if len(addRoles) == 0 && len(delRoles) == 0 {
|
|
return nil
|
|
}
|
|
for _, role := range delRoles {
|
|
if _, err := r.e.DeleteRoleForUser(convertor.ToString(uid), role); err != nil {
|
|
r.logger.WithContext(ctx).Error("DeleteRoleForUser error", zap.Error(err))
|
|
return err
|
|
}
|
|
}
|
|
|
|
_, err = r.e.AddRolesForUser(convertor.ToString(uid), addRoles)
|
|
return err
|
|
}
|
|
|
|
func (r *adminRepository) GetAdminUserByUsername(ctx context.Context, username string) (model.AdminUser, error) {
|
|
m := model.AdminUser{}
|
|
return m, r.DB(ctx).Where("username = ?", username).First(&m).Error
|
|
}
|
|
|
|
func (r *adminRepository) GetAdminUsers(ctx context.Context, req *v1.GetAdminUsersRequest) ([]model.AdminUser, int64, error) {
|
|
var list []model.AdminUser
|
|
var total int64
|
|
scope := r.DB(ctx).Model(&model.AdminUser{})
|
|
if req.Username != "" {
|
|
scope = scope.Where("username LIKE ?", "%"+req.Username+"%")
|
|
}
|
|
if req.Nickname != "" {
|
|
scope = scope.Where("nickname LIKE ?", "%"+req.Nickname+"%")
|
|
}
|
|
if req.Email != "" {
|
|
scope = scope.Where("email LIKE ?", "%"+req.Email+"%")
|
|
}
|
|
if req.Phone != "" {
|
|
scope = scope.Where("phone LIKE ?", "%"+req.Phone+"%")
|
|
}
|
|
if err := scope.Count(&total).Error; err != nil {
|
|
return nil, total, err
|
|
}
|
|
if err := scope.Offset((req.Page - 1) * req.PageSize).Limit(req.PageSize).Order("id DESC").Find(&list).Error; err != nil {
|
|
return nil, total, err
|
|
}
|
|
return list, total, nil
|
|
}
|
|
|
|
func (r *adminRepository) GetAdminUser(ctx context.Context, uid uint) (model.AdminUser, error) {
|
|
m := model.AdminUser{}
|
|
return m, r.DB(ctx).Where("id = ?", uid).First(&m).Error
|
|
}
|
|
|
|
func (r *adminRepository) AdminUserUpdate(ctx context.Context, m *model.AdminUser) error {
|
|
return r.DB(ctx).Where("id = ?", m.ID).Save(m).Error
|
|
}
|
|
|
|
func (r *adminRepository) AdminUserCreate(ctx context.Context, m *model.AdminUser) error {
|
|
return r.DB(ctx).Create(m).Error
|
|
}
|
|
|
|
func (r *adminRepository) AdminUserDelete(ctx context.Context, id uint) error {
|
|
return r.DB(ctx).Where("id = ?", id).Delete(&model.AdminUser{}).Error
|
|
}
|
|
|
|
func (r *adminRepository) UpdateRolePermission(ctx context.Context, role string, newPermSet map[string]struct{}) error {
|
|
if len(newPermSet) == 0 {
|
|
return nil
|
|
}
|
|
// 获取当前角色的所有权限
|
|
oldPermissions, err := r.e.GetPermissionsForUser(role)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 将旧权限转换为 map 方便查找
|
|
oldPermSet := make(map[string]struct{})
|
|
for _, perm := range oldPermissions {
|
|
if len(perm) == 3 {
|
|
oldPermSet[strings.Join([]string{perm[1], perm[2]}, model.PermSep)] = struct{}{}
|
|
}
|
|
}
|
|
|
|
// 找出需要删除的权限
|
|
var removePermissions [][]string
|
|
for key, _ := range oldPermSet {
|
|
if _, exists := newPermSet[key]; !exists {
|
|
removePermissions = append(removePermissions, strings.Split(key, model.PermSep))
|
|
}
|
|
}
|
|
|
|
// 找出需要添加的权限
|
|
var addPermissions [][]string
|
|
for key, _ := range newPermSet {
|
|
if _, exists := oldPermSet[key]; !exists {
|
|
addPermissions = append(addPermissions, strings.Split(key, model.PermSep))
|
|
}
|
|
|
|
}
|
|
|
|
// 先移除多余的权限(使用 DeletePermissionForUser 逐条删除)
|
|
for _, perm := range removePermissions {
|
|
_, err := r.e.DeletePermissionForUser(role, perm...)
|
|
if err != nil {
|
|
return fmt.Errorf("移除权限失败: %v", err)
|
|
}
|
|
}
|
|
|
|
// 再添加新的权限
|
|
if len(addPermissions) > 0 {
|
|
_, err = r.e.AddPermissionsForUser(role, addPermissions...)
|
|
if err != nil {
|
|
return fmt.Errorf("添加新权限失败: %v", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *adminRepository) GetApiGroups(ctx context.Context) ([]string, error) {
|
|
res := make([]string, 0)
|
|
if err := r.DB(ctx).Model(&model.Api{}).Group("`group`").Pluck("`group`", &res).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
func (r *adminRepository) GetApis(ctx context.Context, req *v1.GetApisRequest) ([]model.Api, int64, error) {
|
|
var list []model.Api
|
|
var total int64
|
|
scope := r.DB(ctx).Model(&model.Api{})
|
|
if req.Name != "" {
|
|
scope = scope.Where("name LIKE ?", "%"+req.Name+"%")
|
|
}
|
|
if req.Group != "" {
|
|
scope = scope.Where("`group` LIKE ?", "%"+req.Group+"%")
|
|
}
|
|
if req.Path != "" {
|
|
scope = scope.Where("path LIKE ?", "%"+req.Path+"%")
|
|
}
|
|
if req.Method != "" {
|
|
scope = scope.Where("method = ?", req.Method)
|
|
}
|
|
if err := scope.Count(&total).Error; err != nil {
|
|
return nil, total, err
|
|
}
|
|
if err := scope.Offset((req.Page - 1) * req.PageSize).Limit(req.PageSize).Order("`group` ASC").Find(&list).Error; err != nil {
|
|
return nil, total, err
|
|
}
|
|
return list, total, nil
|
|
}
|
|
|
|
func (r *adminRepository) ApiUpdate(ctx context.Context, m *model.Api) error {
|
|
return r.DB(ctx).Where("id = ?", m.ID).Save(m).Error
|
|
}
|
|
|
|
func (r *adminRepository) ApiCreate(ctx context.Context, m *model.Api) error {
|
|
return r.DB(ctx).Create(m).Error
|
|
}
|
|
|
|
func (r *adminRepository) ApiDelete(ctx context.Context, id uint) error {
|
|
return r.DB(ctx).Where("id = ?", id).Delete(&model.Api{}).Error
|
|
}
|
|
|
|
func (r *adminRepository) GetUserPermissions(ctx context.Context, uid uint) ([][]string, error) {
|
|
return r.e.GetImplicitPermissionsForUser(convertor.ToString(uid))
|
|
|
|
}
|
|
func (r *adminRepository) GetRolePermissions(ctx context.Context, role string) ([][]string, error) {
|
|
return r.e.GetPermissionsForUser(role)
|
|
}
|
|
func (r *adminRepository) GetUserRoles(ctx context.Context, uid uint) ([]string, error) {
|
|
return r.e.GetRolesForUser(convertor.ToString(uid))
|
|
}
|
|
func (r *adminRepository) MenuUpdate(ctx context.Context, m *model.Menu) error {
|
|
return r.DB(ctx).Where("id = ?", m.ID).Save(m).Error
|
|
}
|
|
|
|
func (r *adminRepository) MenuCreate(ctx context.Context, m *model.Menu) error {
|
|
return r.DB(ctx).Save(m).Error
|
|
}
|
|
|
|
func (r *adminRepository) MenuDelete(ctx context.Context, id uint) error {
|
|
return r.DB(ctx).Where("id = ?", id).Delete(&model.Menu{}).Error
|
|
}
|
|
|
|
func (r *adminRepository) GetMenuList(ctx context.Context) ([]model.Menu, error) {
|
|
var menuList []model.Menu
|
|
if err := r.DB(ctx).Order("weight DESC").Find(&menuList).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return menuList, nil
|
|
}
|
|
|
|
func (r *adminRepository) RoleUpdate(ctx context.Context, m *model.Role) error {
|
|
return r.DB(ctx).Where("id = ?", m.ID).UpdateColumn("name", m.Name).Error
|
|
}
|
|
|
|
func (r *adminRepository) RoleCreate(ctx context.Context, m *model.Role) error {
|
|
return r.DB(ctx).Create(m).Error
|
|
}
|
|
|
|
func (r *adminRepository) RoleDelete(ctx context.Context, id uint) error {
|
|
return r.DB(ctx).Where("id = ?", id).Delete(&model.Role{}).Error
|
|
}
|
|
|
|
func (r *adminRepository) GetRoles(ctx context.Context, req *v1.GetRoleListRequest) ([]model.Role, int64, error) {
|
|
var list []model.Role
|
|
var total int64
|
|
scope := r.DB(ctx).Model(&model.Role{})
|
|
if req.Name != "" {
|
|
scope = scope.Where("name LIKE ?", "%"+req.Name+"%")
|
|
}
|
|
if req.Sid != "" {
|
|
scope = scope.Where("sid = ?", req.Sid)
|
|
}
|
|
if err := scope.Count(&total).Error; err != nil {
|
|
return nil, total, err
|
|
}
|
|
if err := scope.Offset((req.Page - 1) * req.PageSize).Limit(req.PageSize).Find(&list).Error; err != nil {
|
|
return nil, total, err
|
|
}
|
|
return list, total, nil
|
|
}
|