Files
billai/server/main.go
2026-01-08 23:42:01 +08:00

114 lines
3.2 KiB
Go

package main
import (
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"github.com/gin-gonic/gin"
"billai-server/config"
"billai-server/database"
"billai-server/handler"
)
func main() {
// 加载配置
config.Load()
// 解析路径
uploadDirAbs := config.ResolvePath(config.Global.UploadDir)
outputDirAbs := config.ResolvePath(config.Global.OutputDir)
pythonPathAbs := config.ResolvePath(config.Global.PythonPath)
// 确保目录存在
os.MkdirAll(uploadDirAbs, 0755)
os.MkdirAll(outputDirAbs, 0755)
// 打印配置信息
printBanner(pythonPathAbs, uploadDirAbs, outputDirAbs)
// 检查 Python 是否存在
if _, err := os.Stat(pythonPathAbs); os.IsNotExist(err) {
fmt.Printf("⚠️ 警告: Python 路径不存在: %s\n", pythonPathAbs)
fmt.Println(" 请在配置文件中指定正确的 Python 路径")
}
// 连接 MongoDB
if err := database.Connect(); err != nil {
fmt.Printf("⚠️ 警告: MongoDB 连接失败: %v\n", err)
fmt.Println(" 账单数据将不会存储到数据库")
os.Exit(1)
} else {
// 优雅关闭时断开连接
defer database.Disconnect()
}
// 创建路由
r := gin.Default()
// 注册路由
setupRoutes(r, outputDirAbs, pythonPathAbs)
// 监听系统信号
go func() {
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
fmt.Println("\n🛑 正在关闭服务...")
database.Disconnect()
os.Exit(0)
}()
// 启动服务
printAPIInfo()
r.Run(":" + config.Global.Port)
}
// setupRoutes 设置路由
func setupRoutes(r *gin.Engine, outputDirAbs, pythonPathAbs string) {
// 健康检查
r.GET("/health", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
"python_path": pythonPathAbs,
})
})
// API 路由
api := r.Group("/api")
{
api.POST("/upload", handler.Upload)
api.GET("/review", handler.Review)
}
// 静态文件下载
r.Static("/download", outputDirAbs)
}
// printBanner 打印启动横幅
func printBanner(pythonPath, uploadDir, outputDir string) {
fmt.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
fmt.Println("📦 BillAI 账单分析服务")
fmt.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
fmt.Printf("📁 项目根目录: %s\n", config.Global.ProjectRoot)
fmt.Printf("🐍 Python路径: %s\n", pythonPath)
fmt.Printf("📂 上传目录: %s\n", uploadDir)
fmt.Printf("📂 输出目录: %s\n", outputDir)
fmt.Printf("🍃 MongoDB: %s/%s\n", config.Global.MongoURI, config.Global.MongoDatabase)
fmt.Println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
}
// printAPIInfo 打印 API 信息
func printAPIInfo() {
fmt.Printf("\n🚀 服务已启动: http://localhost:%s\n", config.Global.Port)
fmt.Println("📝 API 接口:")
fmt.Println(" POST /api/upload - 上传并分析账单")
fmt.Println(" GET /api/review - 获取需要复核的记录")
fmt.Println(" GET /download/* - 下载结果文件")
fmt.Println(" GET /health - 健康检查")
fmt.Println()
}