refactor(server): decouple services and improve architecture
- 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:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user