feat: 实时消息与管理端运营能力

新增群聊/私信与公共 WebSocket 总线,站长用户内容档案,并将通知与待审角标改为推送驱动;同步精简管理仪表盘并修复主题换肤 DOM 冲突。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-15 22:58:16 +08:00
parent 29db9ae9b5
commit 42c395a864
55 changed files with 7607 additions and 346 deletions

View File

@@ -1,6 +1,8 @@
package service
import (
"strings"
"github.com/freefire/jiang13-bbs/model"
)
@@ -107,9 +109,53 @@ func (s *AuthService) GetUserBoardIDs(id uint) ([]uint, error) {
// GetUserIDByUsername 按用户名查 ID(登录失败审计用),用户不存在返回 0
func (s *AuthService) GetUserIDByUsername(username string) uint {
username = strings.TrimSpace(username)
if username == "" {
return 0
}
var u model.User
if err := s.db.Select("id").Where("username = ?", username).First(&u).Error; err != nil {
return 0
}
return u.ID
}
// ListBoardModeratorIDs 可审核指定板块的用户 ID:
// 站长/超管/全站管理员 + 被授权该板的板块管理员(未封禁、未删除)
func (s *AuthService) ListBoardModeratorIDs(boardID uint) ([]uint, error) {
var ids []uint
// 全站可审:admin / super_admin / owner
if err := s.db.Model(&model.User{}).
Where("deleted_at IS NULL AND banned = ? AND role IN ?", false,
[]string{string(model.RoleAdmin), string(model.RoleSuperAdmin), string(model.RoleOwner)}).
Pluck("id", &ids).Error; err != nil {
return nil, err
}
// 板块管理员(授权该板)
var boardAdminIDs []uint
if err := s.db.Model(&model.UserBoard{}).
Select("user_boards.user_id").
Joins("JOIN users ON users.id = user_boards.user_id").
Where("user_boards.board_id = ? AND users.deleted_at IS NULL AND users.banned = ? AND users.role = ?",
boardID, false, string(model.RoleBoardAdmin)).
Pluck("user_boards.user_id", &boardAdminIDs).Error; err != nil {
return nil, err
}
seen := make(map[uint]struct{}, len(ids)+len(boardAdminIDs))
out := make([]uint, 0, len(ids)+len(boardAdminIDs))
for _, id := range ids {
if _, ok := seen[id]; ok {
continue
}
seen[id] = struct{}{}
out = append(out, id)
}
for _, id := range boardAdminIDs {
if _, ok := seen[id]; ok {
continue
}
seen[id] = struct{}{}
out = append(out, id)
}
return out, nil
}