Files
soul-yongping/soul-api/cmd/server/main.go
Alex-larget 0d12ab1d07 Update project documentation and enhance user interaction features
- Added a new entry for user interaction habit analysis based on agent transcripts, summarizing key insights into communication styles and preferences.
- Updated project indices to reflect the latest developments, including the addition of a wallet balance feature and enhancements to the mini program's user interface for better user experience.
- Improved the handling of loading states in the chapters page, ensuring a smoother user experience during data retrieval.
- Implemented a gift payment sharing feature, allowing users to share payment requests with friends for collaborative purchases.
2026-03-17 11:44:36 +08:00

100 lines
2.6 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 (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"soul-api/internal/config"
"soul-api/internal/database"
"soul-api/internal/handler"
"soul-api/internal/redis"
"soul-api/internal/router"
"soul-api/internal/wechat"
)
func main() {
cfg, err := config.Load()
if err != nil {
log.Fatal("load config: ", err)
}
config.SetCurrent(cfg)
if err := database.Init(cfg.DBDSN); err != nil {
log.Fatal("database: ", err)
}
if err := wechat.Init(cfg); err != nil {
log.Fatal("wechat: ", err)
}
if err := wechat.InitTransfer(cfg); err != nil {
log.Fatal("wechat transfer: ", err)
}
if cfg.RedisURL != "" && cfg.RedisURL != "disable" {
if err := redis.Init(cfg.RedisURL); err != nil {
log.Printf("redis: 连接失败,跳过(%v", err)
} else {
defer redis.Close()
}
}
r := router.Setup(cfg)
srv := &http.Server{
Addr: ":" + cfg.Port,
Handler: r,
}
// 预热 all-chapters、book/parts 缓存,避免首请求冷启动 502
go func() {
time.Sleep(2 * time.Second) // 等 DB 完全就绪
handler.WarmAllChaptersCache()
handler.WarmBookPartsCache()
}()
go func() {
log.Printf("soul-api listen on :%s (mode=%s)", cfg.Port, cfg.Mode)
log.Printf(" -> 访问地址: http://localhost:%s (健康检查: http://localhost:%s/health)", cfg.Port, cfg.Port)
if cfg.UploadDir != "" {
log.Printf(" -> 上传目录: %s", cfg.UploadDir)
}
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal("listen: ", err)
}
}()
// 内置订单对账定时任务SYNC_ORDERS_INTERVAL_MINUTES > 0 时启动)
if cfg.SyncOrdersIntervalMinutes > 0 {
interval := time.Duration(cfg.SyncOrdersIntervalMinutes) * time.Minute
go func() {
// 启动后延迟 1 分钟执行第一次,避免与启动流程抢资源
time.Sleep(1 * time.Minute)
ticker := time.NewTicker(interval)
defer ticker.Stop()
handler.SyncOrdersLogf("内置定时任务已启动,间隔 %d 分钟", cfg.SyncOrdersIntervalMinutes)
for {
ctx := context.Background()
synced, total, err := handler.RunSyncOrders(ctx, 7)
if err != nil {
handler.SyncOrdersLogf("对账失败: %v", err)
} else if total > 0 {
handler.SyncOrdersLogf("本轮检查 %d 笔,补齐 %d 笔漏单", total, synced)
}
<-ticker.C
}
}()
}
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("shutting down...")
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("server shutdown: ", err)
}
log.Println("bye")
}