任务三

This commit is contained in:
Yvan
2026-01-07 11:53:56 +08:00
parent 05e12a2e2a
commit a017d93dbf
10 changed files with 1082 additions and 119 deletions
+2
View File
@@ -28,6 +28,8 @@ type SysUser struct {
Email *string `gorm:"column:email;type:varchar(191);comment:用户邮箱" json:"email"` // 用户邮箱
Enable *int64 `gorm:"column:enable;type:bigint(20);default:1;comment:用户是否被冻结 1正常 2冻结" json:"enable"` // 用户是否被冻结 1正常 2冻结
OriginSetting *string `gorm:"column:origin_setting;type:text;comment:配置" json:"origin_setting"` // 配置
Authority SysAuthority `gorm:"foreignKey:AuthorityID;references:AuthorityID" json:"authority"`
Authorities []SysAuthority `gorm:"joinForeignKey:SysUserID;joinReferences:SysAuthorityAuthorityID;many2many:sys_user_authority" json:"authorities"`
}
// TableName SysUser's table name
+184 -1
View File
@@ -42,6 +42,17 @@ func newSysUser(db *gorm.DB, opts ...gen.DOOption) sysUser {
_sysUser.Email = field.NewString(tableName, "email")
_sysUser.Enable = field.NewInt64(tableName, "enable")
_sysUser.OriginSetting = field.NewString(tableName, "origin_setting")
_sysUser.Authority = sysUserHasOneAuthority{
db: db.Session(&gorm.Session{}),
RelationField: field.NewRelation("Authority", "model.SysAuthority"),
}
_sysUser.Authorities = sysUserManyToManyAuthorities{
db: db.Session(&gorm.Session{}),
RelationField: field.NewRelation("Authorities", "model.SysAuthority"),
}
_sysUser.fillFieldMap()
@@ -66,6 +77,9 @@ type sysUser struct {
Email field.String // 用户邮箱
Enable field.Int64 // 用户是否被冻结 1正常 2冻结
OriginSetting field.String // 配置
Authority sysUserHasOneAuthority
Authorities sysUserManyToManyAuthorities
fieldMap map[string]field.Expr
}
@@ -120,7 +134,7 @@ func (s *sysUser) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (s *sysUser) fillFieldMap() {
s.fieldMap = make(map[string]field.Expr, 14)
s.fieldMap = make(map[string]field.Expr, 16)
s.fieldMap["id"] = s.ID
s.fieldMap["created_at"] = s.CreatedAt
s.fieldMap["updated_at"] = s.UpdatedAt
@@ -135,18 +149,187 @@ func (s *sysUser) fillFieldMap() {
s.fieldMap["email"] = s.Email
s.fieldMap["enable"] = s.Enable
s.fieldMap["origin_setting"] = s.OriginSetting
}
func (s sysUser) clone(db *gorm.DB) sysUser {
s.sysUserDo.ReplaceConnPool(db.Statement.ConnPool)
s.Authority.db = db.Session(&gorm.Session{Initialized: true})
s.Authority.db.Statement.ConnPool = db.Statement.ConnPool
s.Authorities.db = db.Session(&gorm.Session{Initialized: true})
s.Authorities.db.Statement.ConnPool = db.Statement.ConnPool
return s
}
func (s sysUser) replaceDB(db *gorm.DB) sysUser {
s.sysUserDo.ReplaceDB(db)
s.Authority.db = db.Session(&gorm.Session{})
s.Authorities.db = db.Session(&gorm.Session{})
return s
}
type sysUserHasOneAuthority struct {
db *gorm.DB
field.RelationField
}
func (a sysUserHasOneAuthority) Where(conds ...field.Expr) *sysUserHasOneAuthority {
if len(conds) == 0 {
return &a
}
exprs := make([]clause.Expression, 0, len(conds))
for _, cond := range conds {
exprs = append(exprs, cond.BeCond().(clause.Expression))
}
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
return &a
}
func (a sysUserHasOneAuthority) WithContext(ctx context.Context) *sysUserHasOneAuthority {
a.db = a.db.WithContext(ctx)
return &a
}
func (a sysUserHasOneAuthority) Session(session *gorm.Session) *sysUserHasOneAuthority {
a.db = a.db.Session(session)
return &a
}
func (a sysUserHasOneAuthority) Model(m *model.SysUser) *sysUserHasOneAuthorityTx {
return &sysUserHasOneAuthorityTx{a.db.Model(m).Association(a.Name())}
}
func (a sysUserHasOneAuthority) Unscoped() *sysUserHasOneAuthority {
a.db = a.db.Unscoped()
return &a
}
type sysUserHasOneAuthorityTx struct{ tx *gorm.Association }
func (a sysUserHasOneAuthorityTx) Find() (result *model.SysAuthority, err error) {
return result, a.tx.Find(&result)
}
func (a sysUserHasOneAuthorityTx) Append(values ...*model.SysAuthority) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Append(targetValues...)
}
func (a sysUserHasOneAuthorityTx) Replace(values ...*model.SysAuthority) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Replace(targetValues...)
}
func (a sysUserHasOneAuthorityTx) Delete(values ...*model.SysAuthority) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Delete(targetValues...)
}
func (a sysUserHasOneAuthorityTx) Clear() error {
return a.tx.Clear()
}
func (a sysUserHasOneAuthorityTx) Count() int64 {
return a.tx.Count()
}
func (a sysUserHasOneAuthorityTx) Unscoped() *sysUserHasOneAuthorityTx {
a.tx = a.tx.Unscoped()
return &a
}
type sysUserManyToManyAuthorities struct {
db *gorm.DB
field.RelationField
}
func (a sysUserManyToManyAuthorities) Where(conds ...field.Expr) *sysUserManyToManyAuthorities {
if len(conds) == 0 {
return &a
}
exprs := make([]clause.Expression, 0, len(conds))
for _, cond := range conds {
exprs = append(exprs, cond.BeCond().(clause.Expression))
}
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
return &a
}
func (a sysUserManyToManyAuthorities) WithContext(ctx context.Context) *sysUserManyToManyAuthorities {
a.db = a.db.WithContext(ctx)
return &a
}
func (a sysUserManyToManyAuthorities) Session(session *gorm.Session) *sysUserManyToManyAuthorities {
a.db = a.db.Session(session)
return &a
}
func (a sysUserManyToManyAuthorities) Model(m *model.SysUser) *sysUserManyToManyAuthoritiesTx {
return &sysUserManyToManyAuthoritiesTx{a.db.Model(m).Association(a.Name())}
}
func (a sysUserManyToManyAuthorities) Unscoped() *sysUserManyToManyAuthorities {
a.db = a.db.Unscoped()
return &a
}
type sysUserManyToManyAuthoritiesTx struct{ tx *gorm.Association }
func (a sysUserManyToManyAuthoritiesTx) Find() (result []*model.SysAuthority, err error) {
return result, a.tx.Find(&result)
}
func (a sysUserManyToManyAuthoritiesTx) Append(values ...*model.SysAuthority) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Append(targetValues...)
}
func (a sysUserManyToManyAuthoritiesTx) Replace(values ...*model.SysAuthority) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Replace(targetValues...)
}
func (a sysUserManyToManyAuthoritiesTx) Delete(values ...*model.SysAuthority) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Delete(targetValues...)
}
func (a sysUserManyToManyAuthoritiesTx) Clear() error {
return a.tx.Clear()
}
func (a sysUserManyToManyAuthoritiesTx) Count() int64 {
return a.tx.Count()
}
func (a sysUserManyToManyAuthoritiesTx) Unscoped() *sysUserManyToManyAuthoritiesTx {
a.tx = a.tx.Unscoped()
return &a
}
type sysUserDo struct{ gen.DO }
type ISysUserDo interface {
+38 -62
View File
@@ -73,11 +73,9 @@ func (r *userRepo) UpdateSelfSetting(ctx context.Context, id uint, setting json.
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
}
@@ -94,16 +92,15 @@ func (r *userRepo) FindByID(ctx context.Context, id uint) (*system.User, error)
}
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
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
return toModelUserWithAuthorities(m), nil
}
func (r *userRepo) FindByUUID(ctx context.Context, uuidStr string) (*system.User, error) {
@@ -115,16 +112,15 @@ func (r *userRepo) FindByUUID(ctx context.Context, uuidStr string) (*system.User
}
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
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
return toModelUserWithAuthorities(m), nil
}
func (r *userRepo) FindByUsername(ctx context.Context, username string) (*system.User, error) {
@@ -136,49 +132,48 @@ func (r *userRepo) FindByUsername(ctx context.Context, username string) (*system
}
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
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
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{})
u := query.SysUser
q := u.WithContext(ctx)
if v, ok := filters["username"]; ok && v != "" {
db = db.Where("username LIKE ?", "%"+v+"%")
q = q.Where(u.Username.Like("%" + v + "%"))
}
if v, ok := filters["nick_name"]; ok && v != "" {
db = db.Where("nick_name LIKE ?", "%"+v+"%")
q = q.Where(u.NickName.Like("%" + v + "%"))
}
if v, ok := filters["phone"]; ok && v != "" {
db = db.Where("phone LIKE ?", "%"+v+"%")
q = q.Where(u.Phone.Like("%" + v + "%"))
}
if v, ok := filters["email"]; ok && v != "" {
db = db.Where("email LIKE ?", "%"+v+"%")
q = q.Where(u.Email.Like("%" + v + "%"))
}
var total int64
if err := db.Count(&total).Error; err != nil {
total, err := q.Count()
if 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
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])
users[i] = toModelUserWithAuthorities(list[i])
}
return users, total, nil
}
@@ -193,20 +188,16 @@ func (r *userRepo) UpdateAuthorityID(ctx context.Context, id uint, authorityId u
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
}
@@ -219,7 +210,6 @@ func (r *userRepo) SetUserAuthorities(ctx context.Context, adminAuthorityID, use
}
}
// 更新用户默认角色
if len(authorityIds) > 0 {
if err := tx.Model(&model.SysUser{}).Where("id = ?", userId).Update("authority_id", authorityIds[0]).Error; err != nil {
return err
@@ -229,13 +219,10 @@ func (r *userRepo) SetUserAuthorities(ctx context.Context, adminAuthorityID, use
})
}
// 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) {
@@ -255,7 +242,6 @@ func (r *userRepo) CheckUserHasAuthority(ctx context.Context, userId, authorityI
}
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
@@ -265,13 +251,11 @@ func (r *userRepo) GetAuthorityMenuRouters(ctx context.Context, authorityId uint
return []string{}, nil
}
// 获取菜单ID
menuIDs := make([]string, len(authorityMenus))
menuIDs := make([]int64, len(authorityMenus))
for i, am := range authorityMenus {
menuIDs[i] = am.MenuID
menuIDs[i] = am.SysBaseMenuID
}
// 获取菜单的name(路由)
var menus []model.SysBaseMenu
if err := r.db.WithContext(ctx).Where("id IN ?", menuIDs).Find(&menus).Error; err != nil {
return nil, err
@@ -337,15 +321,9 @@ func toModelUser(m *model.SysUser) *system.User {
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)
}
@@ -374,16 +352,14 @@ 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
}
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