feat(server): implement chat file TTL cleanup and enhance JPush vendor channel support
Add FileCleanupWorker for automatic expiration of chat files with configurable retention period and batch processing. Files uploaded via `/api/v1/uploads/files` are tracked in `uploaded_files` table with expiration timestamps, then deleted from S3 and database upon expiry. Expired file URLs are injected as `"expired": true` in message responses. Extend JPush push notification configuration with vendor-specific channel_id support (xiaomi, huawei, oppo, vivo, meizu, honor, fcm) for differentiating system vs chat notifications. Add iOS APNs thread-id grouping configuration for notification categorization.
This commit is contained in:
@@ -18,17 +18,18 @@ import (
|
||||
|
||||
// App 应用程序结构体
|
||||
type App struct {
|
||||
Config *config.Config
|
||||
DB *gorm.DB
|
||||
Router *router.Router
|
||||
PushService service.PushService
|
||||
HotRankWorker *service.HotRankWorker
|
||||
GRPCServer *runner.Server
|
||||
Server *http.Server
|
||||
Publisher ws.MessagePublisher
|
||||
TaskDispatcher runner.TaskDispatcher
|
||||
Logger *zap.Logger
|
||||
PushWorker *service.PushWorker
|
||||
Config *config.Config
|
||||
DB *gorm.DB
|
||||
Router *router.Router
|
||||
PushService service.PushService
|
||||
HotRankWorker *service.HotRankWorker
|
||||
FileCleanupWorker *service.FileCleanupWorker
|
||||
GRPCServer *runner.Server
|
||||
Server *http.Server
|
||||
Publisher ws.MessagePublisher
|
||||
TaskDispatcher runner.TaskDispatcher
|
||||
Logger *zap.Logger
|
||||
PushWorker *service.PushWorker
|
||||
}
|
||||
|
||||
// NewApp 创建应用程序
|
||||
@@ -38,6 +39,7 @@ func NewApp(
|
||||
r *router.Router,
|
||||
pushService service.PushService,
|
||||
hotRankWorker *service.HotRankWorker,
|
||||
fileCleanupWorker *service.FileCleanupWorker,
|
||||
grpcServer *runner.Server,
|
||||
publisher ws.MessagePublisher,
|
||||
taskDispatcher runner.TaskDispatcher,
|
||||
@@ -45,16 +47,17 @@ func NewApp(
|
||||
pushWorker *service.PushWorker,
|
||||
) *App {
|
||||
return &App{
|
||||
Config: cfg,
|
||||
DB: db,
|
||||
Router: r,
|
||||
PushService: pushService,
|
||||
HotRankWorker: hotRankWorker,
|
||||
GRPCServer: grpcServer,
|
||||
Publisher: publisher,
|
||||
TaskDispatcher: taskDispatcher,
|
||||
Logger: logger,
|
||||
PushWorker: pushWorker,
|
||||
Config: cfg,
|
||||
DB: db,
|
||||
Router: r,
|
||||
PushService: pushService,
|
||||
HotRankWorker: hotRankWorker,
|
||||
FileCleanupWorker: fileCleanupWorker,
|
||||
GRPCServer: grpcServer,
|
||||
Publisher: publisher,
|
||||
TaskDispatcher: taskDispatcher,
|
||||
Logger: logger,
|
||||
PushWorker: pushWorker,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +79,11 @@ func (a *App) Start(ctx context.Context) error {
|
||||
a.HotRankWorker.Start(ctx)
|
||||
}
|
||||
|
||||
// 2.1.1 聊天文件过期清理
|
||||
if a.FileCleanupWorker != nil {
|
||||
a.FileCleanupWorker.Start(ctx)
|
||||
}
|
||||
|
||||
// 2.2 启动 PushWorker(Redis Stream 异步推送)
|
||||
if a.PushWorker != nil {
|
||||
a.PushWorker.Start(ctx)
|
||||
@@ -156,6 +164,11 @@ func (a *App) Stop(ctx context.Context) error {
|
||||
a.HotRankWorker.Stop()
|
||||
}
|
||||
|
||||
if a.FileCleanupWorker != nil {
|
||||
a.Logger.Info("Stopping file cleanup worker")
|
||||
a.FileCleanupWorker.Stop()
|
||||
}
|
||||
|
||||
// 5.1 停止 PushWorker
|
||||
if a.PushWorker != nil {
|
||||
a.Logger.Info("Stopping push worker (stream)")
|
||||
|
||||
@@ -35,7 +35,7 @@ func InitializeApp() (*App, error) {
|
||||
messagePublisher := wire.ProvideWSMessagePublisher(config, client)
|
||||
logger := wire.ProvideLogger()
|
||||
jpushClient := wire.ProvideJPushClient(config, logger)
|
||||
pushService := wire.ProvidePushService(pushRecordRepository, deviceTokenRepository, messageRepository, messagePublisher, jpushClient)
|
||||
pushService := wire.ProvidePushService(pushRecordRepository, deviceTokenRepository, messageRepository, messagePublisher, jpushClient, config)
|
||||
postRepository := repository.NewPostRepository(db)
|
||||
cache := wire.ProvideCache(config, client)
|
||||
systemMessageService := wire.ProvideSystemMessageService(systemNotificationRepository, pushService, userRepository, postRepository, cache)
|
||||
@@ -77,7 +77,8 @@ func InitializeApp() (*App, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uploadService := wire.ProvideUploadService(s3Client, userService)
|
||||
uploadedFileRepository := repository.NewUploadedFileRepository(db)
|
||||
uploadService := wire.ProvideUploadService(s3Client, userService, uploadedFileRepository)
|
||||
seqBufferManager := wire.ProvideSeqBufferManager(config, client, cache)
|
||||
pushWorker := wire.ProvidePushWorker(config, client, messagePublisher, pushService, messageRepository, userRepository)
|
||||
conversationVersionLogRepository := repository.NewConversationVersionLogRepository(db)
|
||||
@@ -86,7 +87,7 @@ func InitializeApp() (*App, error) {
|
||||
groupRepository := repository.NewGroupRepository(db)
|
||||
groupJoinRequestRepository := repository.NewGroupJoinRequestRepository(db)
|
||||
groupService := wire.ProvideGroupService(groupRepository, userRepository, messageRepository, groupJoinRequestRepository, systemNotificationRepository, messagePublisher, cache)
|
||||
messageHandler := wire.ProvideMessageHandler(chatService, messageService, userService, groupService, messagePublisher)
|
||||
messageHandler := wire.ProvideMessageHandler(chatService, messageService, userService, groupService, uploadService, messagePublisher)
|
||||
notificationRepository := repository.NewNotificationRepository(db)
|
||||
notificationService := wire.ProvideNotificationService(notificationRepository, cache)
|
||||
notificationHandler := handler.NewNotificationHandler(notificationService)
|
||||
@@ -163,10 +164,11 @@ func InitializeApp() (*App, error) {
|
||||
liveKitHandler := wire.ProvideLiveKitHandler(liveKitService, callService, config, logger)
|
||||
router := ProvideRouter(userRepository, userHandler, postHandler, commentHandler, messageHandler, notificationHandler, uploadHandler, jwtService, pushHandler, systemMessageHandler, groupHandler, stickerHandler, voteHandler, channelHandler, scheduleHandler, gradeHandler, examHandler, emptyClassroomHandler, roleHandler, adminUserHandler, adminPostHandler, adminCommentHandler, adminGroupHandler, adminDashboardHandler, adminLogHandler, qrCodeHandler, materialHandler, callHandler, reportHandler, adminReportHandler, verificationHandler, adminVerificationHandler, adminProfileAuditHandler, setupHandler, tradeHandler, logService, userActivityService, casbinService, userService, wsHandler, liveKitHandler)
|
||||
hotRankWorker := wire.ProvideHotRankWorker(config, postRepository, channelRepository, cache, client)
|
||||
fileCleanupWorker := wire.ProvideFileCleanupWorker(config, uploadedFileRepository, s3Client, client)
|
||||
server := wire.ProvideGRPCServer(config, logger, runnerHub)
|
||||
runnerRegistry := wire.ProvideRunnerRegistry(config, client)
|
||||
taskDispatcher := wire.ProvideTaskDispatcher(runnerHub, runnerRegistry, config, client, logger)
|
||||
app := NewApp(config, db, router, pushService, hotRankWorker, server, messagePublisher, taskDispatcher, logger, pushWorker)
|
||||
app := NewApp(config, db, router, pushService, hotRankWorker, fileCleanupWorker, server, messagePublisher, taskDispatcher, logger, pushWorker)
|
||||
return app, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user