refactor(server): decouple services and improve architecture
All checks were successful
Build Backend / build (push) Successful in 4m55s
Build Backend / build-docker (push) Successful in 10m34s

- Introduce interfaces for all major services (JWT, PostAI, Comment, Message, Notification, QRCodeLogin, Upload, Vote, etc.) to support dependency inversion.
- Move query parameters from `internal/dto` to a new `internal/query` package to separate request payloads from data transfer objects.
- Refactor `internal/router` to use embedded `RouterDeps` for cleaner dependency management.
- Decouple handlers from repositories by injecting services instead of direct repository access, ensuring proper layering.
- Improve database initialization by moving it from `internal/model` to `internal/database`.
- Optimize message decryption by implementing a more efficient `BatchDecrypt` method in `MessageEncryptor` using a worker pool.
- Enhance error handling and security by implementing fail-fast checks for encryption key length during startup.
- Clean up unused code, including the `avatar` package and several unused DTOs.
This commit is contained in:
2026-06-15 03:41:59 +08:00
parent 9951043034
commit d9aa4b46c3
78 changed files with 2156 additions and 1640 deletions

View File

@@ -51,19 +51,30 @@ type QRCodeSession struct {
ExpiresAt int64 `json:"expires_at"`
}
// QRCodeLoginService 二维码登录服务
type QRCodeLoginService struct {
// QRCodeLoginService 二维码登录服务接口
type QRCodeLoginService interface {
CreateSession(ctx context.Context) (*QRCodeSession, error)
GetSession(ctx context.Context, sessionID string) (*QRCodeSession, error)
Scan(ctx context.Context, sessionID, userID string) error
Confirm(ctx context.Context, sessionID, userID string, ip, userAgent string) (*LoginResponse, error)
Cancel(ctx context.Context, sessionID, userID string) error
GetWSHub() *ws.Hub
GetUserService() UserService
}
// qrcodeLoginService 二维码登录服务实现
type qrcodeLoginService struct {
redis *redis.Client
wsHub ws.MessagePublisher
jwtService *JWTService
jwtService JWTService
userService UserService
activityService UserActivityService
logService *LogService
}
// NewQRCodeLoginService 创建二维码登录服务
func NewQRCodeLoginService(redis *redis.Client, publisher ws.MessagePublisher, jwtService *JWTService, userService UserService, activityService UserActivityService, logService *LogService) *QRCodeLoginService {
return &QRCodeLoginService{
func NewQRCodeLoginService(redis *redis.Client, publisher ws.MessagePublisher, jwtService JWTService, userService UserService, activityService UserActivityService, logService *LogService) QRCodeLoginService {
return &qrcodeLoginService{
redis: redis,
wsHub: publisher,
jwtService: jwtService,
@@ -74,7 +85,7 @@ func NewQRCodeLoginService(redis *redis.Client, publisher ws.MessagePublisher, j
}
// CreateSession 创建二维码会话
func (s *QRCodeLoginService) CreateSession(ctx context.Context) (*QRCodeSession, error) {
func (s *qrcodeLoginService) CreateSession(ctx context.Context) (*QRCodeSession, error) {
sessionID := uuid.New().String()
now := time.Now()
expiresAt := now.Add(qrcodeSessionTTL)
@@ -106,7 +117,7 @@ func (s *QRCodeLoginService) CreateSession(ctx context.Context) (*QRCodeSession,
}
// GetSession 获取会话
func (s *QRCodeLoginService) GetSession(ctx context.Context, sessionID string) (*QRCodeSession, error) {
func (s *qrcodeLoginService) GetSession(ctx context.Context, sessionID string) (*QRCodeSession, error) {
key := qrcodeSessionPrefix + sessionID
data, err := s.redis.HGetAll(ctx, key)
if err != nil {
@@ -140,7 +151,7 @@ func (s *QRCodeLoginService) GetSession(ctx context.Context, sessionID string) (
}
// Scan 扫描二维码
func (s *QRCodeLoginService) Scan(ctx context.Context, sessionID, userID string) error {
func (s *qrcodeLoginService) Scan(ctx context.Context, sessionID, userID string) error {
key := qrcodeSessionPrefix + sessionID
// 使用 Lua 脚本实现原子性检查和更新,避免竞态条件
@@ -176,7 +187,7 @@ func (s *QRCodeLoginService) Scan(ctx context.Context, sessionID, userID string)
}
// Confirm 确认登录
func (s *QRCodeLoginService) Confirm(ctx context.Context, sessionID, userID string, ip, userAgent string) (*LoginResponse, error) {
func (s *qrcodeLoginService) Confirm(ctx context.Context, sessionID, userID string, ip, userAgent string) (*LoginResponse, error) {
session, err := s.GetSession(ctx, sessionID)
if err != nil {
return nil, err
@@ -255,7 +266,7 @@ type LoginResponse struct {
}
// Cancel 取消登录
func (s *QRCodeLoginService) Cancel(ctx context.Context, sessionID, userID string) error {
func (s *qrcodeLoginService) Cancel(ctx context.Context, sessionID, userID string) error {
session, err := s.GetSession(ctx, sessionID)
if err != nil {
return err
@@ -281,7 +292,7 @@ func (s *QRCodeLoginService) Cancel(ctx context.Context, sessionID, userID strin
}
// GetWSHub 获取底层 WS Hub用于 Subscribe 等本地操作)
func (s *QRCodeLoginService) GetWSHub() *ws.Hub {
func (s *qrcodeLoginService) GetWSHub() *ws.Hub {
switch p := s.wsHub.(type) {
case *ws.Bus:
return p.Hub()
@@ -293,6 +304,6 @@ func (s *QRCodeLoginService) GetWSHub() *ws.Hub {
}
// GetUserService 获取用户服务
func (s *QRCodeLoginService) GetUserService() UserService {
func (s *qrcodeLoginService) GetUserService() UserService {
return s.userService
}