topfans/backend/services/taskService/main.go
zerosaturation c5bf9df955 feat: 经济系统重构 - 任务服务与画廊服务解耦
- galleryService 独立启动,配置 task-service-url
- 新增 taskService 到 galleryService 的 RPC 调用
- 更新 proto 文件并重新生成代码
- 新增展览唯一约束迁移脚本
- 修复多个 service 的配置和依赖关系

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 23:12:02 +08:00

157 lines
5.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"flag"
"fmt"
"os"
"os/signal"
"syscall"
dubboclient "dubbo.apache.org/dubbo-go/v3/client"
_ "dubbo.apache.org/dubbo-go/v3/imports"
"dubbo.apache.org/dubbo-go/v3/protocol"
"dubbo.apache.org/dubbo-go/v3/server"
"github.com/topfans/backend/pkg/database"
"github.com/topfans/backend/pkg/logger"
pb "github.com/topfans/backend/pkg/proto/task"
pbGallery "github.com/topfans/backend/pkg/proto/gallery"
pbUser "github.com/topfans/backend/pkg/proto/user"
"github.com/topfans/backend/services/taskService/client"
"github.com/topfans/backend/services/taskService/config"
"github.com/topfans/backend/services/taskService/model"
"github.com/topfans/backend/services/taskService/provider"
"github.com/topfans/backend/services/taskService/repository"
"github.com/topfans/backend/services/taskService/service"
"github.com/topfans/backend/services/taskService/worker"
)
var port = flag.Int("port", 20006, "Dubbo service port")
func main() {
// 1. Init logger必须最前
env := os.Getenv("ENV")
if env == "" {
env = "development"
}
if err := logger.Init(logger.Config{ServiceName: "task-service", Environment: env, LogLevel: os.Getenv("LOG_LEVEL")}); err != nil {
panic(fmt.Sprintf("Failed to init logger: %v", err))
}
defer logger.Sync()
logger.Logger.Info("Starting taskService...")
// 2. Init config读取 flags/env
config.InitConfig()
// 3. Init database + auto-migrate
dbConfig := database.Config{
Host: config.DBConfig.Host,
Port: config.DBConfig.Port,
User: config.DBConfig.User,
Password: config.DBConfig.Password,
DBName: config.DBConfig.DBName,
SSLMode: config.DBConfig.SSLMode,
TimeZone: "Asia/Shanghai",
}
if err := database.Init(dbConfig); err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to init DB: %v", err))
}
db := database.GetDB()
if err := db.AutoMigrate(
&model.TaskDefinition{},
&model.UserDailyTaskProgress{},
&model.UserOnboardingProgress{},
&model.UserOnboardingStatus{},
&model.OnboardingStageConfig{},
&model.ExhibitionRevenueRecord{},
&model.TaskResetLog{},
); err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to migrate tables: %v", err))
}
logger.Logger.Info("Database initialized")
// 4. Init repositories
dailyRepo := repository.NewDailyTaskRepository(db)
onboardingRepo := repository.NewOnboardingRepository(db)
revenueRepo := repository.NewRevenueRepository(db)
logger.Logger.Info("Repositories initialized")
// 5. Init userService Dubbo client + RPC client
userCli, err := dubboclient.NewClient(
dubboclient.WithClientURL(config.ServiceURLsConfig.UserService),
)
if err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to create userService client: %v", err))
}
userServiceClient, err := pbUser.NewUserSocialService(userCli)
if err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to get userService: %v", err))
}
userRPCClient := client.NewUserServiceClient(userServiceClient)
logger.Logger.Info("User RPC client initialized")
// 5.1 Init galleryService Dubbo client + RPC client
galleryCli, err := dubboclient.NewClient(
dubboclient.WithClientURL(config.ServiceURLsConfig.GalleryService),
)
if err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to create galleryService client: %v", err))
}
galleryServiceClient, err := pbGallery.NewGalleryService(galleryCli)
if err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to get galleryService: %v", err))
}
galleryRPCClient := client.NewGalleryServiceClient(galleryServiceClient)
logger.Logger.Info("Gallery RPC client initialized")
// 6. Init services
dailySvc := service.NewDailyTaskService(dailyRepo, userRPCClient)
onboardingSvc := service.NewOnboardingService(onboardingRepo, dailyRepo, userRPCClient)
revenueSvc := service.NewRevenueService(revenueRepo, userRPCClient, galleryRPCClient)
logger.Logger.Info("Services initialized")
// 7. Init workergoroutine 中启动)
resetWorker := worker.NewDailyResetWorker(dailyRepo, revenueRepo, userRPCClient)
go resetWorker.Start()
logger.Logger.Info("Reset worker started")
// 8. Init providers
mobileProvider := provider.NewTaskMobileProvider(dailySvc, onboardingSvc, revenueSvc)
internalProvider := provider.NewTaskInternalProvider(onboardingSvc, revenueSvc)
logger.Logger.Info("Providers initialized")
// 9. Create Dubbo server on port 20006
srv, err := server.NewServer(
server.WithServerProtocol(
protocol.WithPort(*port),
protocol.WithTriple(),
),
)
if err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to create server: %v", err))
}
// 注册 Dubbo 服务
if err := pb.RegisterTaskMobileServiceHandler(srv, mobileProvider); err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to register TaskMobileService: %v", err))
}
if err := pb.RegisterTaskInternalServiceHandler(srv, internalProvider); err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to register TaskInternalService: %v", err))
}
// 10. Start server (non-blocking)
go func() {
if err := srv.Serve(); err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to serve: %v", err))
}
}()
logger.Logger.Info(fmt.Sprintf("taskService listening on port %d", *port))
// Graceful shutdown
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
logger.Logger.Info("Shutting down taskService...")
resetWorker.Stop()
}