feat(admin): 管理端在线监控 + 好友关系管理后端
- admin/service/online_service.go: 在线用户列表/计数 - admin/controller/online_controller.go: GET /admin/online/users|count - admin/service/contact_manage_service.go: 好友关系分页查询/管理员删除 - admin/controller/contact_manage_controller.go: GET|DELETE /admin/contacts - 更新 admin router/provider/wire 集成新控制器 Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/echochat/backend/app/admin/service"
|
||||
"github.com/echochat/backend/pkg/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ContactManageController struct {
|
||||
contactManageService *service.ContactManageService
|
||||
}
|
||||
|
||||
func NewContactManageController(contactManageService *service.ContactManageService) *ContactManageController {
|
||||
return &ContactManageController{contactManageService: contactManageService}
|
||||
}
|
||||
|
||||
// GetAllContacts GET /api/v1/admin/contacts
|
||||
func (ctl *ContactManageController) GetAllContacts(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||||
|
||||
contacts, total, err := ctl.contactManageService.GetAllFriendships(ctx, page, pageSize)
|
||||
if err != nil {
|
||||
utils.ResponseError(c, "获取好友关系列表失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, gin.H{
|
||||
"list": contacts,
|
||||
"total": total,
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteContact DELETE /api/v1/admin/contacts/:id
|
||||
func (ctl *ContactManageController) DeleteContact(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
utils.ResponseBadRequest(c, "ID 格式错误")
|
||||
return
|
||||
}
|
||||
|
||||
if err := ctl.contactManageService.DeleteFriendship(ctx, id); err != nil {
|
||||
utils.ResponseError(c, "删除好友关系失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, nil)
|
||||
}
|
||||
37
backend/go-service/app/admin/controller/online_controller.go
Normal file
37
backend/go-service/app/admin/controller/online_controller.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/echochat/backend/app/admin/service"
|
||||
"github.com/echochat/backend/pkg/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type OnlineController struct {
|
||||
onlineManageService *service.OnlineManageService
|
||||
}
|
||||
|
||||
func NewOnlineController(onlineManageService *service.OnlineManageService) *OnlineController {
|
||||
return &OnlineController{onlineManageService: onlineManageService}
|
||||
}
|
||||
|
||||
// GetOnlineUsers GET /api/v1/admin/online/users
|
||||
func (ctl *OnlineController) GetOnlineUsers(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
userIDs, err := ctl.onlineManageService.GetOnlineUsers(ctx)
|
||||
if err != nil {
|
||||
utils.ResponseError(c, "获取在线用户列表失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, userIDs)
|
||||
}
|
||||
|
||||
// GetOnlineCount GET /api/v1/admin/online/count
|
||||
func (ctl *OnlineController) GetOnlineCount(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
count, err := ctl.onlineManageService.GetOnlineCount(ctx)
|
||||
if err != nil {
|
||||
utils.ResponseError(c, "获取在线用户数失败")
|
||||
return
|
||||
}
|
||||
utils.ResponseOK(c, gin.H{"count": count})
|
||||
}
|
||||
@@ -14,4 +14,8 @@ var AdminSet = wire.NewSet(
|
||||
dao.NewUserManageDAO,
|
||||
service.NewUserManageService,
|
||||
controller.NewUserManageController,
|
||||
service.NewOnlineManageService,
|
||||
controller.NewOnlineController,
|
||||
service.NewContactManageService,
|
||||
controller.NewContactManageController,
|
||||
)
|
||||
|
||||
@@ -12,7 +12,9 @@ import (
|
||||
// 所有管理端 API 需要 JWT + admin 角色双重中间件
|
||||
func RegisterRoutes(
|
||||
r *gin.Engine,
|
||||
ctrl *controller.UserManageController,
|
||||
userCtrl *controller.UserManageController,
|
||||
onlineCtrl *controller.OnlineController,
|
||||
contactManageCtrl *controller.ContactManageController,
|
||||
jwtAuth gin.HandlerFunc,
|
||||
) {
|
||||
// 管理端路由组:JWT 认证 + admin/super_admin 角色检查
|
||||
@@ -20,13 +22,21 @@ func RegisterRoutes(
|
||||
adminGroup.Use(jwtAuth, middleware.RequireRole(constants.RoleAdmin, constants.RoleSuperAdmin))
|
||||
{
|
||||
// 用户管理
|
||||
adminGroup.GET("/users", ctrl.GetUserList)
|
||||
adminGroup.GET("/users/:id", ctrl.GetUserDetail)
|
||||
adminGroup.PUT("/users/:id/status", ctrl.UpdateUserStatus)
|
||||
adminGroup.PUT("/users/:id/roles", ctrl.SetRoles)
|
||||
adminGroup.POST("/users", ctrl.CreateUser)
|
||||
adminGroup.GET("/users", userCtrl.GetUserList)
|
||||
adminGroup.GET("/users/:id", userCtrl.GetUserDetail)
|
||||
adminGroup.PUT("/users/:id/status", userCtrl.UpdateUserStatus)
|
||||
adminGroup.PUT("/users/:id/roles", userCtrl.SetRoles)
|
||||
adminGroup.POST("/users", userCtrl.CreateUser)
|
||||
|
||||
// 角色管理
|
||||
adminGroup.GET("/roles", ctrl.GetAllRoles)
|
||||
adminGroup.GET("/roles", userCtrl.GetAllRoles)
|
||||
|
||||
// 在线监控
|
||||
adminGroup.GET("/online/users", onlineCtrl.GetOnlineUsers)
|
||||
adminGroup.GET("/online/count", onlineCtrl.GetOnlineCount)
|
||||
|
||||
// 好友关系管理
|
||||
adminGroup.GET("/contacts", contactManageCtrl.GetAllContacts)
|
||||
adminGroup.DELETE("/contacts/:id", contactManageCtrl.DeleteContact)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/echochat/backend/app/contact/model"
|
||||
"github.com/echochat/backend/pkg/logs"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ContactManageService struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewContactManageService(db *gorm.DB) *ContactManageService {
|
||||
return &ContactManageService{db: db}
|
||||
}
|
||||
|
||||
type AdminFriendship struct {
|
||||
ID int64 `json:"id"`
|
||||
UserID int64 `json:"user_id"`
|
||||
UserUsername string `json:"user_username"`
|
||||
FriendID int64 `json:"friend_id"`
|
||||
FriendUsername string `json:"friend_username"`
|
||||
Status int `json:"status"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// GetAllFriendships 获取所有好友关系(分页)
|
||||
func (s *ContactManageService) GetAllFriendships(ctx context.Context, page, pageSize int) ([]AdminFriendship, int64, error) {
|
||||
funcName := "service.contact_manage_service.GetAllFriendships"
|
||||
logs.Debug(ctx, funcName, "管理端查询好友关系")
|
||||
|
||||
var total int64
|
||||
s.db.WithContext(ctx).Model(&model.Friendship{}).Count(&total)
|
||||
|
||||
var results []AdminFriendship
|
||||
offset := (page - 1) * pageSize
|
||||
err := s.db.WithContext(ctx).
|
||||
Table("contact_friendships f").
|
||||
Select("f.id, f.user_id, u1.username as user_username, f.friend_id, u2.username as friend_username, f.status, TO_CHAR(f.created_at, 'YYYY-MM-DD HH24:MI:SS') as created_at").
|
||||
Joins("JOIN auth_users u1 ON u1.id = f.user_id").
|
||||
Joins("JOIN auth_users u2 ON u2.id = f.friend_id").
|
||||
Order("f.created_at DESC").
|
||||
Offset(offset).Limit(pageSize).
|
||||
Scan(&results).Error
|
||||
|
||||
return results, total, err
|
||||
}
|
||||
|
||||
// DeleteFriendship 管理员删除好友关系(双向删除)
|
||||
func (s *ContactManageService) DeleteFriendship(ctx context.Context, friendshipID int64) error {
|
||||
funcName := "service.contact_manage_service.DeleteFriendship"
|
||||
logs.Info(ctx, funcName, "管理员删除好友关系", zap.Int64("friendship_id", friendshipID))
|
||||
|
||||
var f model.Friendship
|
||||
if err := s.db.WithContext(ctx).First(&f, friendshipID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
tx.Where("user_id = ? AND friend_id = ?", f.UserID, f.FriendID).Delete(&model.Friendship{})
|
||||
tx.Where("user_id = ? AND friend_id = ?", f.FriendID, f.UserID).Delete(&model.Friendship{})
|
||||
return nil
|
||||
})
|
||||
}
|
||||
26
backend/go-service/app/admin/service/online_service.go
Normal file
26
backend/go-service/app/admin/service/online_service.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
wsApp "github.com/echochat/backend/app/ws"
|
||||
"github.com/echochat/backend/pkg/logs"
|
||||
)
|
||||
|
||||
type OnlineManageService struct {
|
||||
onlineService *wsApp.OnlineService
|
||||
}
|
||||
|
||||
func NewOnlineManageService(onlineService *wsApp.OnlineService) *OnlineManageService {
|
||||
return &OnlineManageService{onlineService: onlineService}
|
||||
}
|
||||
|
||||
func (s *OnlineManageService) GetOnlineUsers(ctx context.Context) ([]int64, error) {
|
||||
funcName := "service.online_manage_service.GetOnlineUsers"
|
||||
logs.Debug(ctx, funcName, "获取在线用户列表")
|
||||
return s.onlineService.GetOnlineUserIDs(ctx)
|
||||
}
|
||||
|
||||
func (s *OnlineManageService) GetOnlineCount(ctx context.Context) (int64, error) {
|
||||
return s.onlineService.GetOnlineCount(ctx)
|
||||
}
|
||||
Reference in New Issue
Block a user