完善角色与消息权限:收紧板管内容处置,彻底删除仅站长,并统一管理删帖/评弹窗。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-20 14:30:08 +08:00
parent 1f2e4b2a33
commit c0462a3500
37 changed files with 1340 additions and 472 deletions

View File

@@ -44,23 +44,24 @@ func NewAdminUserService(db *gorm.DB) *AdminUserService {
// AdminUserItem 后台用户列表项:email / last_seen / 登录 IP 在 User 模型上 json:"-",
// 仅管理员接口通过此 DTO 显式带出
type AdminUserItem struct {
ID uint `json:"id"`
Username string `json:"username"`
Nickname string `json:"nickname"`
Email string `json:"email"`
Avatar string `json:"avatar"`
Signature string `json:"signature"`
Role string `json:"role"`
BoardIDs []uint `json:"board_ids"`
Banned bool `json:"banned"`
PostCount int64 `json:"post_count"`
CommentCount int64 `json:"comment_count"`
Points int `json:"points"`
CreatedAt time.Time `json:"created_at"`
LastSeenAt *time.Time `json:"last_seen_at"`
Online bool `json:"online"`
LastLoginIP string `json:"last_login_ip"`
LastLoginAt *time.Time `json:"last_login_at"`
ID uint `json:"id"`
Username string `json:"username"`
Nickname string `json:"nickname"`
Email string `json:"email"`
Avatar string `json:"avatar"`
Signature string `json:"signature"`
Role string `json:"role"`
BoardIDs []uint `json:"board_ids"`
Banned bool `json:"banned"`
CanManageMessages bool `json:"can_manage_messages"`
PostCount int64 `json:"post_count"`
CommentCount int64 `json:"comment_count"`
Points int `json:"points"`
CreatedAt time.Time `json:"created_at"`
LastSeenAt *time.Time `json:"last_seen_at"`
Online bool `json:"online"`
LastLoginIP string `json:"last_login_ip"`
LastLoginAt *time.Time `json:"last_login_at"`
}
// AdminUserSummary 列表顶部汇总
@@ -222,18 +223,19 @@ func (s *AdminUserService) toItems(users []model.User) []AdminUserItem {
for _, u := range users {
ids = append(ids, u.ID)
item := AdminUserItem{
ID: u.ID,
Username: u.Username,
Nickname: u.Nickname,
Email: u.Email,
Avatar: u.Avatar,
Signature: u.Signature,
Role: string(u.Role),
BoardIDs: []uint{},
Banned: u.Banned,
Points: u.Points,
CreatedAt: u.CreatedAt,
LastSeenAt: u.LastSeenAt,
ID: u.ID,
Username: u.Username,
Nickname: u.Nickname,
Email: u.Email,
Avatar: u.Avatar,
Signature: u.Signature,
Role: string(u.Role),
BoardIDs: []uint{},
Banned: u.Banned,
CanManageMessages: u.CanManageMessages,
Points: u.Points,
CreatedAt: u.CreatedAt,
LastSeenAt: u.LastSeenAt,
}
if u.LastSeenAt != nil && now.Sub(*u.LastSeenAt) <= onlineThreshold {
item.Online = true
@@ -407,6 +409,38 @@ func (s *AdminUserService) SetStaff(operator *Actor, targetID uint, role model.R
return s.getItem(s.db, targetID)
}
// SetCanManageMessages 站长授予/撤销站点消息管理权限(不可操作站长账号与自己)
func (s *AdminUserService) SetCanManageMessages(operator *Actor, targetID uint, enabled bool) (*AdminUserItem, error) {
if operator == nil || operator.Role != model.RoleOwner {
return nil, ErrOwnerOnly
}
if operator.ID == targetID {
return nil, ErrAdminSelfAction
}
err := s.db.Transaction(func(tx *gorm.DB) error {
var u model.User
if err := tx.First(&u, targetID).Error; err != nil {
return err
}
if u.Role == model.RoleOwner {
return ErrProtectedOwner
}
// 超管固有全站监管,flag 无意义;强制保持 false 以免误导
if u.Role == model.RoleSuperAdmin {
enabled = false
}
if u.CanManageMessages == enabled {
return nil
}
// GORM bool 零值省略:强制 Select 写入
return tx.Model(&u).Select("can_manage_messages").Update("can_manage_messages", enabled).Error
})
if err != nil {
return nil, err
}
return s.getItem(s.db, targetID)
}
// SetBanned 封禁/解封用户。站长账号不可封禁;封禁时同事务使登录态立即失效
func (s *AdminUserService) SetBanned(operator *Actor, targetID uint, banned bool) (*AdminUserItem, error) {
if operator == nil {