390 lines
10 KiB
Go
390 lines
10 KiB
Go
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) {
|
|
m, err := query.SysUser.WithContext(ctx).
|
|
Preload(query.SysUser.Authority).
|
|
Preload(query.SysUser.Authorities).
|
|
Where(query.SysUser.ID.Eq(int64(id))).
|
|
First()
|
|
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) {
|
|
m, err := query.SysUser.WithContext(ctx).
|
|
Preload(query.SysUser.Authority).
|
|
Preload(query.SysUser.Authorities).
|
|
Where(query.SysUser.UUID.Eq(uuidStr)).
|
|
First()
|
|
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) {
|
|
m, err := query.SysUser.WithContext(ctx).
|
|
Preload(query.SysUser.Authority).
|
|
Preload(query.SysUser.Authorities).
|
|
Where(query.SysUser.Username.Eq(username)).
|
|
First()
|
|
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) {
|
|
u := query.SysUser
|
|
q := u.WithContext(ctx)
|
|
|
|
if v, ok := filters["username"]; ok && v != "" {
|
|
q = q.Where(u.Username.Like("%" + v + "%"))
|
|
}
|
|
if v, ok := filters["nick_name"]; ok && v != "" {
|
|
q = q.Where(u.NickName.Like("%" + v + "%"))
|
|
}
|
|
if v, ok := filters["phone"]; ok && v != "" {
|
|
q = q.Where(u.Phone.Like("%" + v + "%"))
|
|
}
|
|
if v, ok := filters["email"]; ok && v != "" {
|
|
q = q.Where(u.Email.Like("%" + v + "%"))
|
|
}
|
|
|
|
total, err := q.Count()
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
offset := (page - 1) * pageSize
|
|
list, err := q.Preload(u.Authority).Preload(u.Authorities).Offset(offset).Limit(pageSize).Find()
|
|
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
|
|
})
|
|
}
|
|
|
|
func checkAuthorityIDAuth(tx *gorm.DB, adminAuthorityID, targetAuthorityID uint) error {
|
|
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) {
|
|
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
|
|
}
|
|
|
|
menuIDs := make([]int64, len(authorityMenus))
|
|
for i, am := range authorityMenus {
|
|
menuIDs[i] = am.SysBaseMenuID
|
|
}
|
|
|
|
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.HeaderImg != nil {
|
|
u.HeaderImg = *m.HeaderImg
|
|
}
|
|
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
|
|
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
|
|
}
|