package main import ( "backend/common" "backend/controller" config "backend/global" "backend/middleware" "backend/middleware/feishu/server" "backend/model" "backend/monitor" "backend/util" "fmt" "io" "log" "os" "time" "github.com/gin-gonic/gin" rotatelogs "github.com/lestrrat-go/file-rotatelogs" ) // GOOS=linux GOARCH=amd64 go build -o /data/backend/release/backend main.go var ( rl *rotatelogs.RotateLogs logWriter io.Writer errWriter io.Writer ) func init() { // 确保日志目录存在 if err := os.MkdirAll("./log", 0755); err != nil { log.Fatalf("failed to create log dir: %v", err) } // 使用按天轮转的日志文件,保留最近 30 个文件 var err error rl, err = rotatelogs.New( "./log/backend.%Y-%m-%d.log", rotatelogs.WithRotationTime(24*time.Hour), rotatelogs.WithRotationCount(30), ) if err != nil { log.Fatalf("failed to initialize log rotator: %v", err) } // 打开一个普通的最新日志文件(不使用 symlink),用于提供固定路径的最新日志 currFile, err := os.OpenFile("./log/backend.log", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { // 如果打开失败,仍然继续使用轮转器+控制台 log.Printf("warning: failed to open current log file: %v", err) logWriter = io.MultiWriter(rl, os.Stdout) errWriter = io.MultiWriter(rl, os.Stderr) } else { // 同时输出到轮转日志、固定最新日志文件和控制台 logWriter = io.MultiWriter(rl, currFile) errWriter = io.MultiWriter(rl, currFile, os.Stderr) } log.SetOutput(logWriter) // 保持全局默认 writer(以兼容其他调用) gin.DefaultWriter = logWriter gin.DefaultErrorWriter = errWriter util.InitBBolt() common.Init() common.InitTranlater() } func main() { defer func() { if err := recover(); err != nil { log.Printf("Recovered from panic: %v", err) // 这里可以添加更多的错误 handling 逻辑,比如发送通知等 // 重新启动服务器 fmt.Print("Restarting server...") os.Exit(1) } }() r := gin.Default() openApi := r.Group("/api/open") { openApi.POST("/apk/upload", controller.UploadApkPackage) } loginApi := r.Group("/api/auth") { // 认证 loginApi.POST("/login", controller.Login) loginApi.GET("/Codes", controller.Codes) loginApi.POST("/phoneCode", controller.PhoneCode) loginApi.POST("/phoneLogin", controller.LoginCode) } feishuApi := r.Group("/api/feishu") { // 飞书 feishuApi.POST("/sendInfo", controller.FeishuSendInfo) feishuApi.POST("/sendInfo2", controller.FeishuSendInfo2) // US 运营数据 feishuApi.POST("/sendWeekInfo", controller.FeishuSendWeekInfo) feishuApi.POST("/updateApp", controller.FeishuUpdateApp) feishuApi.POST("/serverInfo", controller.FeishuServerInfo) feishuApi.POST("/notify", controller.FeishuNotify) // 系统报警 feishuApi.POST("/notify/client", controller.FeishuNotifyClient) // 客户端报警 feishuApi.POST("/notify/order", controller.FeishuNotifyOrder) // 订单通知 } alibabaApi := r.Group("/api/alibaba") { // 阿里云 alibabaApi.POST("/zabbix/notify", controller.AlibabaNotify) // 系统报警 alibabaApi.POST("/zabbix/recovery", controller.AlibabaRecovery) // 系统报警 alibabaApi.POST("/game/notify", controller.AlibabaGameNotify) // 游戏报警 alibabaApi.POST("/notify/order", controller.AlibabaNotifyOrder) // 订单通知 } abtestApi := r.Group("/api/v1", middleware.ValidateToken()) { experiments := abtestApi.Group("/experiments") { experiments.GET("", controller.ExperimentList) experiments.POST("", controller.ExperimentCreate) experiments.PUT("/:id", controller.ExperimentUpdate) experiments.DELETE("/:id", controller.ExperimentDelete) experiments.GET("/:id/variants", controller.ExperimentVariantList) experiments.POST("/:id/variants", controller.ExperimentVariantCreate) experiments.PUT("/:id/variants/:variantId", controller.ExperimentVariantUpdate) experiments.DELETE("/:id/variants/:variantId", controller.ExperimentVariantDelete) experiments.GET("/:id/whitelist", controller.ExperimentWhitelistList) experiments.POST("/:id/whitelist", controller.ExperimentWhitelistCreate) experiments.POST("/:id/whitelist/batch", controller.ExperimentWhitelistBatchCreate) experiments.DELETE("/:id/whitelist/:userId", controller.ExperimentWhitelistDelete) experiments.GET("/:id/results", controller.ExperimentResult) } abtestApi.GET("/users/:userId/groups", controller.UserExperimentGroups) } api := r.Group("/api", middleware.ValidateToken()) { // 以下路由只校验 token,不校验权限 r.GET("/api/user/info", middleware.ValidateTokenOnly(), controller.UserInfo) r.POST("/api/statistics/info", middleware.ValidateTokenOnly(), controller.StatisticsInfo) r.POST("/api/statistics/level", middleware.ValidateTokenOnly(), controller.StatisticsLevel) r.POST("/api/statistics/order", middleware.ValidateTokenOnly(), controller.StatisticsOrder) r.POST("/api/statistics/heat", middleware.ValidateTokenOnly(), controller.StatisticsHeat) // 账号管理 api.POST("/admin/list", controller.AdminList) api.POST("/admin/add", controller.AdminAdd) api.POST("/admin/edit", controller.AdminEdit) api.POST("/admin/delete", controller.AdminDelete) api.POST("/admin/log/list", controller.AdminLogList) api.POST("/admin/config/list", controller.AdminConfigList) api.POST("/admin/config/add", controller.AdminConfigAdd) api.POST("/admin/config/edit", controller.AdminConfigEdit) api.POST("/admin/usergroup/list", controller.PermissionUserGroupList) api.POST("/admin/usergroup/add", controller.PermissionUserGroupAdd) api.POST("/admin/usergroup/edit", controller.PermissionUserGroupEdit) api.POST("/admin/usergroup/delete", controller.PermissionUserGroupDelete) api.POST("/admin/usergroup/role/set", controller.PermissionGroupRoleSet) api.POST("/admin/usergroup/role/list", controller.PermissionGroupRoleList) api.POST("/admin/role/list", controller.PermissionRoleList) api.POST("/admin/role/add", controller.PermissionRoleAdd) api.POST("/admin/role/edit", controller.PermissionRoleEdit) api.POST("/admin/role/delete", controller.PermissionRoleDelete) api.POST("/admin/role/permission/set", controller.PermissionRolePermissionSet) api.POST("/admin/role/permission/list", controller.PermissionRolePermissionList) api.POST("/admin/permission/list", controller.PermissionPointList) api.POST("/admin/permission/add", controller.PermissionPointAdd) api.POST("/admin/permission/edit", controller.PermissionPointEdit) api.POST("/admin/permission/delete", controller.PermissionPointDelete) api.POST("/admin/user/group/list", controller.PermissionUserGroupRelList) api.POST("/admin/user/group/set", controller.PermissionUserGroupRelSet) api.POST("/admin/user/permission/list", controller.PermissionUserPermissionList) api.POST("/admin/user/permission/set", controller.PermissionUserPermissionSet) api.POST("/admin/user/role/list", controller.PermissionUserRoleList) api.POST("/admin/user/role/batch-list", controller.PermissionUserRoleBatchList) // 玩家日志 api.POST("/log/user", controller.UserDetail) api.POST("/log/asset", controller.Asset) api.POST("/log/event", controller.Event) api.POST("/log/loginCountByMonth", controller.LoginCountByMonth) api.POST("/log/order", controller.Order) api.POST("/log/order/reissue/apply", controller.OrderReissueApply) api.POST("/log/order/reissue/approve", controller.OrderReissueApprove) api.POST("/log/order/reissue/reject", controller.OrderReissueReject) // 玩家数据 api.POST("/user/list", controller.UserList) api.POST("/user/gm", controller.UserGM) api.POST("/user/ban", controller.UserBan) api.POST("/server/list", controller.AppList) api.POST("/server/serverList", controller.ServerList) api.POST("/server/addServer", controller.AddServer) api.POST("/server/nodeList", controller.NodeList) api.POST("/server/addNode", controller.AddNode) api.POST("/server/editServer", controller.EditServer) api.POST("/server/updateApp", controller.UpdateApp) api.POST("/server/updateAppReview", controller.UpdateAppReview) api.POST("/server/updateAppFeishu", controller.UpdateAppFeishu) api.POST("/server/restart", controller.RestartServer) api.POST("/server/reload", controller.ReloadServer) //活动 api.POST("/activity/list", controller.ActivityList) api.POST("/activity/edit", controller.ActivityEdit) api.POST("/activity/add", controller.ActivityAdd) api.POST("/activity/delete", controller.ActivityDelete) api.POST("/activity/sync", controller.ActivitySync) // 邮件 api.POST("/mail/send", controller.SendMail) api.POST("/mail/list", controller.MailList) api.POST("/mail/approve", controller.MailApprove) api.POST("/mail/reject", controller.MailReject) api.POST("/mail/delete", controller.MailDelete) // 运营功能 api.POST("/operation/copyUser", controller.CopyUser) api.GET("/apk/packages", controller.GetApkPackages) api.GET("/apk/download/:env", controller.DownloadApkPackage) // 翻译 api.POST("/language/list", controller.Language) api.POST("/language/export", controller.LanguageExport) api.POST("/language/save", controller.LanguageSave) api.POST("/language/add", controller.LanguageAdd) api.POST("/language/delete", controller.LanguageDelete) api.GET("/config/notification", controller.NotificationConfigGet) api.PUT("/config/notification/update", controller.NotificationConfigSave) } knowledgeApi := r.Group("/api/knowledge", middleware.ValidateToken()) { knowledgeApi.POST("/chat", controller.KnowledgeChat) } scripts := r.Group("/api/scripts", middleware.ValidateToken()) { scripts.POST("/copywriting", controller.Copywriting) // 下载文案文件 scripts.POST("/copyonline", controller.CopyOnline) // 复制线上环境到QA scripts.POST("/clientImageGitPull", controller.ClientImageGitPull) // 复制线下环境到QA } config.InitConfig() //go util.ScheduleDailyTask() go server.Server() go model.InitToken() // 初始化 Token 列表 if common.GetEnv() == "prod" { // 生产环境才启动监控 go monitor.UserAliveMonitor(0) // 用户存活监控 go monitor.ServerInfoMonitor() // 服务器信息监控 } go util.MonitorServerList() // 启动定时任务发送信息 defer func() { if err := recover(); err != nil { log.Printf("Recovered from panic: %v", err) // 这里可以添加更多的错误处理逻辑,比如发送通知等 // 重新启动服务器 fmt.Print("Restarting server...") os.Exit(1) } }() // 启动 Gin 服务器 r.Run(":5320") // 在 0.0.0.0:5320 上监听并服务 }