feat: 添加日志管理和敏感词过滤功能
- 新增日志管理模块:操作日志、登录日志、数据变更日志 - 新增敏感词过滤器 (sanitizer) - 新增日志异步写入管理器 - 新增日志定时清理服务 - 优化帖子相关服务和上传服务
This commit is contained in:
@@ -2,6 +2,8 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -17,6 +19,7 @@ type UserHandler struct {
|
||||
userService service.UserService
|
||||
activityService service.UserActivityService // 用户活跃统计服务
|
||||
jwtService *service.JWTService
|
||||
logService *service.LogService
|
||||
}
|
||||
|
||||
// NewUserHandler 创建用户处理器
|
||||
@@ -27,6 +30,28 @@ func NewUserHandler(userService service.UserService, activityService service.Use
|
||||
}
|
||||
}
|
||||
|
||||
// SetJWTService 设置JWT服务
|
||||
func (h *UserHandler) SetJWTService(jwtService *service.JWTService) {
|
||||
h.jwtService = jwtService
|
||||
}
|
||||
|
||||
// SetActivityService 设置活跃统计服务
|
||||
func (h *UserHandler) SetActivityService(activityService service.UserActivityService) {
|
||||
h.activityService = activityService
|
||||
}
|
||||
|
||||
// SetLogService 设置日志服务
|
||||
func (h *UserHandler) SetLogService(logService *service.LogService) {
|
||||
h.logService = logService
|
||||
}
|
||||
|
||||
// generateTokenID 生成Token ID
|
||||
func generateTokenID(token string) string {
|
||||
h := sha256.New()
|
||||
h.Write([]byte(token))
|
||||
return fmt.Sprintf("%x", h.Sum(nil))[:16]
|
||||
}
|
||||
|
||||
// Register 用户注册
|
||||
func (h *UserHandler) Register(c *gin.Context) {
|
||||
type RegisterRequest struct {
|
||||
@@ -54,6 +79,35 @@ func (h *UserHandler) Register(c *gin.Context) {
|
||||
accessToken, _ := h.jwtService.GenerateAccessToken(user.ID, user.Username)
|
||||
refreshToken, _ := h.jwtService.GenerateRefreshToken(user.ID, user.Username)
|
||||
|
||||
ip := c.ClientIP()
|
||||
userAgent := c.GetHeader("User-Agent")
|
||||
|
||||
// 记录用户活跃
|
||||
if h.activityService != nil {
|
||||
go func() {
|
||||
ctx := context.Background()
|
||||
loginType := model.LoginTypeLogin
|
||||
h.activityService.RecordUserActive(ctx, user.ID, loginType, ip, userAgent)
|
||||
}()
|
||||
}
|
||||
|
||||
// 记录注册后首次登录
|
||||
if h.logService != nil {
|
||||
go func() {
|
||||
h.logService.LoginLog.RecordLogin(&model.LoginLog{
|
||||
UserID: user.ID,
|
||||
UserName: user.Username,
|
||||
NickName: user.Nickname,
|
||||
LoginType: string(model.LoginTypePassword),
|
||||
Event: string(model.LoginEventLogin),
|
||||
IP: ip,
|
||||
UserAgent: userAgent,
|
||||
Result: string(model.LoginResultSuccess),
|
||||
TokenID: generateTokenID(refreshToken),
|
||||
})
|
||||
}()
|
||||
}
|
||||
|
||||
response.Success(c, gin.H{
|
||||
"user": dto.ConvertUserToResponse(user),
|
||||
"token": accessToken,
|
||||
@@ -94,17 +148,36 @@ func (h *UserHandler) Login(c *gin.Context) {
|
||||
accessToken, _ := h.jwtService.GenerateAccessToken(user.ID, user.Username)
|
||||
refreshToken, _ := h.jwtService.GenerateRefreshToken(user.ID, user.Username)
|
||||
|
||||
ip := c.ClientIP()
|
||||
userAgent := c.GetHeader("User-Agent")
|
||||
|
||||
// 记录用户活跃
|
||||
if h.activityService != nil {
|
||||
go func() {
|
||||
ctx := context.Background()
|
||||
loginType := model.LoginTypeLogin
|
||||
ip := c.ClientIP()
|
||||
userAgent := c.GetHeader("User-Agent")
|
||||
h.activityService.RecordUserActive(ctx, user.ID, loginType, ip, userAgent)
|
||||
}()
|
||||
}
|
||||
|
||||
// 更新登录日志(补充IP和UserAgent)
|
||||
if h.logService != nil {
|
||||
ip := c.ClientIP()
|
||||
userAgent := c.GetHeader("User-Agent")
|
||||
go func() {
|
||||
h.logService.LoginLog.RecordLogin(&model.LoginLog{
|
||||
UserID: user.ID,
|
||||
UserName: user.Username,
|
||||
NickName: user.Nickname,
|
||||
LoginType: string(model.LoginTypePassword),
|
||||
Event: string(model.LoginEventLogin),
|
||||
IP: ip,
|
||||
UserAgent: userAgent,
|
||||
Result: string(model.LoginResultSuccess),
|
||||
})
|
||||
}()
|
||||
}
|
||||
|
||||
response.Success(c, gin.H{
|
||||
"user": dto.ConvertUserToResponse(user),
|
||||
"token": accessToken,
|
||||
@@ -364,18 +437,43 @@ func (h *UserHandler) RefreshToken(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
user, err := h.userService.GetUserByID(c.Request.Context(), claims.UserID)
|
||||
if err != nil {
|
||||
response.InternalServerError(c, "user not found")
|
||||
return
|
||||
}
|
||||
|
||||
// 生成新 token
|
||||
accessToken, _ := h.jwtService.GenerateAccessToken(claims.UserID, claims.Username)
|
||||
refreshToken, _ := h.jwtService.GenerateRefreshToken(claims.UserID, claims.Username)
|
||||
accessToken, _ := h.jwtService.GenerateAccessToken(user.ID, user.Username)
|
||||
refreshToken, _ := h.jwtService.GenerateRefreshToken(user.ID, user.Username)
|
||||
|
||||
ip := c.ClientIP()
|
||||
userAgent := c.GetHeader("User-Agent")
|
||||
|
||||
// 记录用户活跃
|
||||
if h.activityService != nil {
|
||||
go func() {
|
||||
ctx := context.Background()
|
||||
loginType := model.LoginTypeRefresh
|
||||
ip := c.ClientIP()
|
||||
userAgent := c.GetHeader("User-Agent")
|
||||
h.activityService.RecordUserActive(ctx, claims.UserID, loginType, ip, userAgent)
|
||||
h.activityService.RecordUserActive(ctx, user.ID, loginType, ip, userAgent)
|
||||
}()
|
||||
}
|
||||
|
||||
// 记录Token刷新日志
|
||||
if h.logService != nil {
|
||||
go func() {
|
||||
h.logService.LoginLog.RecordLogin(&model.LoginLog{
|
||||
UserID: user.ID,
|
||||
UserName: user.Username,
|
||||
NickName: user.Nickname,
|
||||
LoginType: string(model.LoginTypePassword),
|
||||
Event: string(model.LoginEventRefresh),
|
||||
IP: ip,
|
||||
UserAgent: userAgent,
|
||||
Result: string(model.LoginResultSuccess),
|
||||
TokenID: generateTokenID(req.RefreshToken),
|
||||
})
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -385,16 +483,6 @@ func (h *UserHandler) RefreshToken(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// SetJWTService 设置JWT服务
|
||||
func (h *UserHandler) SetJWTService(jwtSvc *service.JWTService) {
|
||||
h.jwtService = jwtSvc
|
||||
}
|
||||
|
||||
// SetActivityService 设置活跃统计服务
|
||||
func (h *UserHandler) SetActivityService(activityService service.UserActivityService) {
|
||||
h.activityService = activityService
|
||||
}
|
||||
|
||||
// FollowUser 关注用户
|
||||
func (h *UserHandler) FollowUser(c *gin.Context) {
|
||||
userID := c.Param("id")
|
||||
@@ -657,6 +745,40 @@ func (h *UserHandler) SendChangePasswordCode(c *gin.Context) {
|
||||
response.Success(c, gin.H{"success": true})
|
||||
}
|
||||
|
||||
// Logout 用户登出
|
||||
func (h *UserHandler) Logout(c *gin.Context) {
|
||||
currentUserID := c.GetString("user_id")
|
||||
if currentUserID == "" {
|
||||
response.Unauthorized(c, "not logged in")
|
||||
return
|
||||
}
|
||||
|
||||
ip := c.ClientIP()
|
||||
userAgent := c.GetHeader("User-Agent")
|
||||
|
||||
// 获取用户信息
|
||||
user, err := h.userService.GetUserByID(c.Request.Context(), currentUserID)
|
||||
if err != nil {
|
||||
response.InternalServerError(c, "user not found")
|
||||
return
|
||||
}
|
||||
|
||||
// 记录登出日志
|
||||
if h.logService != nil {
|
||||
h.logService.LoginLog.RecordLogin(&model.LoginLog{
|
||||
UserID: user.ID,
|
||||
UserName: user.Username,
|
||||
NickName: user.Nickname,
|
||||
Event: string(model.LoginEventLogout),
|
||||
IP: ip,
|
||||
UserAgent: userAgent,
|
||||
Result: string(model.LoginResultSuccess),
|
||||
})
|
||||
}
|
||||
|
||||
response.Success(c, gin.H{"success": true})
|
||||
}
|
||||
|
||||
// Search 搜索用户
|
||||
func (h *UserHandler) Search(c *gin.Context) {
|
||||
keyword := c.Query("keyword")
|
||||
|
||||
Reference in New Issue
Block a user