任务三
This commit is contained in:
@@ -0,0 +1,413 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"kra/internal/biz/system"
|
||||
"kra/internal/data/model"
|
||||
"kra/internal/data/query"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type userRepo struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewUserRepo 创建用户仓储
|
||||
func NewUserRepo(db *gorm.DB) system.UserRepo {
|
||||
query.SetDefault(db)
|
||||
return &userRepo{db: db}
|
||||
}
|
||||
|
||||
func (r *userRepo) Create(ctx context.Context, user *system.User) error {
|
||||
m := toBizUser(user)
|
||||
return query.SysUser.WithContext(ctx).Create(m)
|
||||
}
|
||||
|
||||
func (r *userRepo) Update(ctx context.Context, user *system.User) error {
|
||||
_, err := query.SysUser.WithContext(ctx).Where(query.SysUser.ID.Eq(int64(user.ID))).Updates(map[string]any{
|
||||
"nick_name": user.NickName,
|
||||
"header_img": user.HeaderImg,
|
||||
"phone": user.Phone,
|
||||
"email": user.Email,
|
||||
"enable": user.Enable,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *userRepo) UpdateSelf(ctx context.Context, user *system.User) error {
|
||||
updates := map[string]any{}
|
||||
if user.NickName != "" {
|
||||
updates["nick_name"] = user.NickName
|
||||
}
|
||||
if user.HeaderImg != "" {
|
||||
updates["header_img"] = user.HeaderImg
|
||||
}
|
||||
if user.Phone != "" {
|
||||
updates["phone"] = user.Phone
|
||||
}
|
||||
if user.Email != "" {
|
||||
updates["email"] = user.Email
|
||||
}
|
||||
if user.SideMode != "" {
|
||||
updates["side_mode"] = user.SideMode
|
||||
}
|
||||
if user.BaseColor != "" {
|
||||
updates["base_color"] = user.BaseColor
|
||||
}
|
||||
if len(updates) == 0 {
|
||||
return nil
|
||||
}
|
||||
_, err := query.SysUser.WithContext(ctx).Where(query.SysUser.ID.Eq(int64(user.ID))).Updates(updates)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *userRepo) UpdateSelfSetting(ctx context.Context, id uint, setting json.RawMessage) error {
|
||||
_, err := query.SysUser.WithContext(ctx).Where(query.SysUser.ID.Eq(int64(id))).Update(query.SysUser.OriginSetting, string(setting))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *userRepo) Delete(ctx context.Context, id uint) error {
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
// 删除用户
|
||||
if err := tx.Where("id = ?", id).Delete(&model.SysUser{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 删除用户角色关联
|
||||
if err := tx.Where("sys_user_id = ?", id).Delete(&model.SysUserAuthority{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *userRepo) FindByID(ctx context.Context, id uint) (*system.User, error) {
|
||||
m, err := query.SysUser.WithContext(ctx).Where(query.SysUser.ID.Eq(int64(id))).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toModelUser(m), nil
|
||||
}
|
||||
|
||||
func (r *userRepo) FindByIDWithAuthorities(ctx context.Context, id uint) (*system.User, error) {
|
||||
var m model.SysUser
|
||||
err := r.db.WithContext(ctx).
|
||||
Preload("Authorities").
|
||||
Preload("Authority").
|
||||
Where("id = ?", id).
|
||||
First(&m).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toModelUserWithAuthorities(&m), nil
|
||||
}
|
||||
|
||||
func (r *userRepo) FindByUUID(ctx context.Context, uuidStr string) (*system.User, error) {
|
||||
m, err := query.SysUser.WithContext(ctx).Where(query.SysUser.UUID.Eq(uuidStr)).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toModelUser(m), nil
|
||||
}
|
||||
|
||||
func (r *userRepo) FindByUUIDWithAuthorities(ctx context.Context, uuidStr string) (*system.User, error) {
|
||||
var m model.SysUser
|
||||
err := r.db.WithContext(ctx).
|
||||
Preload("Authorities").
|
||||
Preload("Authority").
|
||||
Where("uuid = ?", uuidStr).
|
||||
First(&m).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toModelUserWithAuthorities(&m), nil
|
||||
}
|
||||
|
||||
func (r *userRepo) FindByUsername(ctx context.Context, username string) (*system.User, error) {
|
||||
m, err := query.SysUser.WithContext(ctx).Where(query.SysUser.Username.Eq(username)).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toModelUser(m), nil
|
||||
}
|
||||
|
||||
func (r *userRepo) FindByUsernameWithAuthorities(ctx context.Context, username string) (*system.User, error) {
|
||||
var m model.SysUser
|
||||
err := r.db.WithContext(ctx).
|
||||
Preload("Authorities").
|
||||
Preload("Authority").
|
||||
Where("username = ?", username).
|
||||
First(&m).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toModelUserWithAuthorities(&m), nil
|
||||
}
|
||||
|
||||
func (r *userRepo) List(ctx context.Context, page, pageSize int, filters map[string]string) ([]*system.User, int64, error) {
|
||||
db := r.db.WithContext(ctx).Model(&model.SysUser{})
|
||||
|
||||
if v, ok := filters["username"]; ok && v != "" {
|
||||
db = db.Where("username LIKE ?", "%"+v+"%")
|
||||
}
|
||||
if v, ok := filters["nick_name"]; ok && v != "" {
|
||||
db = db.Where("nick_name LIKE ?", "%"+v+"%")
|
||||
}
|
||||
if v, ok := filters["phone"]; ok && v != "" {
|
||||
db = db.Where("phone LIKE ?", "%"+v+"%")
|
||||
}
|
||||
if v, ok := filters["email"]; ok && v != "" {
|
||||
db = db.Where("email LIKE ?", "%"+v+"%")
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := db.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
var list []model.SysUser
|
||||
offset := (page - 1) * pageSize
|
||||
err := db.Preload("Authorities").Preload("Authority").Offset(offset).Limit(pageSize).Find(&list).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
users := make([]*system.User, len(list))
|
||||
for i := range list {
|
||||
users[i] = toModelUserWithAuthorities(&list[i])
|
||||
}
|
||||
return users, total, nil
|
||||
}
|
||||
|
||||
func (r *userRepo) UpdatePassword(ctx context.Context, id uint, password string) error {
|
||||
return r.db.WithContext(ctx).Model(&model.SysUser{}).Where("id = ?", id).Update("password", password).Error
|
||||
}
|
||||
|
||||
func (r *userRepo) UpdateAuthorityID(ctx context.Context, id uint, authorityId uint) error {
|
||||
return r.db.WithContext(ctx).Model(&model.SysUser{}).Where("id = ?", id).Update("authority_id", authorityId).Error
|
||||
}
|
||||
|
||||
func (r *userRepo) SetUserAuthorities(ctx context.Context, adminAuthorityID, userId uint, authorityIds []uint) error {
|
||||
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
// 查询用户是否存在
|
||||
var user model.SysUser
|
||||
if err := tx.Where("id = ?", userId).First(&user).Error; err != nil {
|
||||
return errors.New("查询用户数据失败")
|
||||
}
|
||||
|
||||
// 删除旧的用户角色关联
|
||||
if err := tx.Where("sys_user_id = ?", userId).Delete(&model.SysUserAuthority{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查管理员权限并创建新的用户角色关联
|
||||
for _, aid := range authorityIds {
|
||||
// 检查管理员是否有权限分配该角色
|
||||
if err := checkAuthorityIDAuth(tx, adminAuthorityID, aid); err != nil {
|
||||
return err
|
||||
}
|
||||
ua := &model.SysUserAuthority{
|
||||
SysUserID: int64(userId),
|
||||
SysAuthorityAuthorityID: int64(aid),
|
||||
}
|
||||
if err := tx.Create(ua).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 更新用户默认角色
|
||||
if len(authorityIds) > 0 {
|
||||
if err := tx.Model(&model.SysUser{}).Where("id = ?", userId).Update("authority_id", authorityIds[0]).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// checkAuthorityIDAuth 检查管理员是否有权限分配该角色
|
||||
func checkAuthorityIDAuth(tx *gorm.DB, adminAuthorityID, targetAuthorityID uint) error {
|
||||
// 如果是超级管理员(888),直接通过
|
||||
if adminAuthorityID == 888 {
|
||||
return nil
|
||||
}
|
||||
// 检查目标角色是否是管理员的子角色
|
||||
var authority model.SysAuthority
|
||||
if err := tx.Where("authority_id = ? AND parent_id = ?", targetAuthorityID, adminAuthorityID).First(&authority).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New("您没有权限分配该角色")
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *userRepo) CheckUserHasAuthority(ctx context.Context, userId, authorityId uint) (bool, error) {
|
||||
var count int64
|
||||
err := r.db.WithContext(ctx).Model(&model.SysUserAuthority{}).
|
||||
Where("sys_user_id = ? AND sys_authority_authority_id = ?", userId, authorityId).
|
||||
Count(&count).Error
|
||||
return count > 0, err
|
||||
}
|
||||
|
||||
func (r *userRepo) GetAuthorityMenuRouters(ctx context.Context, authorityId uint) ([]string, error) {
|
||||
// 获取角色的菜单ID列表
|
||||
var authorityMenus []model.SysAuthorityMenu
|
||||
if err := r.db.WithContext(ctx).Where("sys_authority_authority_id = ?", authorityId).Find(&authorityMenus).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(authorityMenus) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
// 获取菜单ID
|
||||
menuIDs := make([]string, len(authorityMenus))
|
||||
for i, am := range authorityMenus {
|
||||
menuIDs[i] = am.MenuID
|
||||
}
|
||||
|
||||
// 获取菜单的name(路由)
|
||||
var menus []model.SysBaseMenu
|
||||
if err := r.db.WithContext(ctx).Where("id IN ?", menuIDs).Find(&menus).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
routers := make([]string, len(menus))
|
||||
for i, m := range menus {
|
||||
if m.Name != nil {
|
||||
routers[i] = *m.Name
|
||||
}
|
||||
}
|
||||
return routers, nil
|
||||
}
|
||||
|
||||
func (r *userRepo) GetAuthorityDefaultRouter(ctx context.Context, authorityId uint) (string, error) {
|
||||
var authority model.SysAuthority
|
||||
if err := r.db.WithContext(ctx).Where("authority_id = ?", authorityId).First(&authority).Error; err != nil {
|
||||
return "", err
|
||||
}
|
||||
if authority.DefaultRouter != nil {
|
||||
return *authority.DefaultRouter, nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// 转换函数
|
||||
func toBizUser(u *system.User) *model.SysUser {
|
||||
uuidStr := u.UUID.String()
|
||||
username := u.Username
|
||||
password := u.Password
|
||||
nickName := u.NickName
|
||||
headerImg := u.HeaderImg
|
||||
authorityID := int64(u.AuthorityId)
|
||||
phone := u.Phone
|
||||
email := u.Email
|
||||
enable := int64(u.Enable)
|
||||
|
||||
return &model.SysUser{
|
||||
ID: int64(u.ID),
|
||||
UUID: &uuidStr,
|
||||
Username: &username,
|
||||
Password: &password,
|
||||
NickName: &nickName,
|
||||
HeaderImg: &headerImg,
|
||||
AuthorityID: &authorityID,
|
||||
Phone: &phone,
|
||||
Email: &email,
|
||||
Enable: &enable,
|
||||
}
|
||||
}
|
||||
|
||||
func toModelUser(m *model.SysUser) *system.User {
|
||||
u := &system.User{ID: uint(m.ID)}
|
||||
if m.UUID != nil {
|
||||
u.UUID, _ = uuid.Parse(*m.UUID)
|
||||
}
|
||||
if m.Username != nil {
|
||||
u.Username = *m.Username
|
||||
}
|
||||
if m.Password != nil {
|
||||
u.Password = *m.Password
|
||||
}
|
||||
if m.NickName != nil {
|
||||
u.NickName = *m.NickName
|
||||
}
|
||||
if m.SideMode != nil {
|
||||
u.SideMode = *m.SideMode
|
||||
}
|
||||
if m.HeaderImg != nil {
|
||||
u.HeaderImg = *m.HeaderImg
|
||||
}
|
||||
if m.BaseColor != nil {
|
||||
u.BaseColor = *m.BaseColor
|
||||
}
|
||||
if m.AuthorityID != nil {
|
||||
u.AuthorityId = uint(*m.AuthorityID)
|
||||
}
|
||||
if m.Phone != nil {
|
||||
u.Phone = *m.Phone
|
||||
}
|
||||
if m.Email != nil {
|
||||
u.Email = *m.Email
|
||||
}
|
||||
if m.Enable != nil {
|
||||
u.Enable = int(*m.Enable)
|
||||
}
|
||||
if m.OriginSetting != nil {
|
||||
u.OriginSetting = json.RawMessage(*m.OriginSetting)
|
||||
}
|
||||
if m.CreatedAt != nil {
|
||||
u.CreatedAt = *m.CreatedAt
|
||||
}
|
||||
if m.UpdatedAt != nil {
|
||||
u.UpdatedAt = *m.UpdatedAt
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
func toModelUserWithAuthorities(m *model.SysUser) *system.User {
|
||||
u := toModelUser(m)
|
||||
|
||||
// 转换Authority
|
||||
if m.Authority != nil {
|
||||
u.Authority = &system.Authority{
|
||||
AuthorityId: uint(m.Authority.AuthorityID),
|
||||
AuthorityName: safeString(m.Authority.AuthorityName),
|
||||
DefaultRouter: safeString(m.Authority.DefaultRouter),
|
||||
}
|
||||
if m.Authority.ParentID != nil {
|
||||
pid := uint(*m.Authority.ParentID)
|
||||
u.Authority.ParentId = &pid
|
||||
}
|
||||
}
|
||||
|
||||
// 转换Authorities
|
||||
if len(m.Authorities) > 0 {
|
||||
u.Authorities = make([]*system.Authority, len(m.Authorities))
|
||||
for i, a := range m.Authorities {
|
||||
u.Authorities[i] = &system.Authority{
|
||||
AuthorityId: uint(a.AuthorityID),
|
||||
AuthorityName: safeString(a.AuthorityName),
|
||||
DefaultRouter: safeString(a.DefaultRouter),
|
||||
}
|
||||
if a.ParentID != nil {
|
||||
pid := uint(*a.ParentID)
|
||||
u.Authorities[i].ParentId = &pid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
func safeString(s *string) string {
|
||||
if s == nil {
|
||||
return ""
|
||||
}
|
||||
return *s
|
||||
}
|
||||
Reference in New Issue
Block a user