110 lines
3.3 KiB
Go
110 lines
3.3 KiB
Go
package main
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"log"
|
||
"net/http"
|
||
|
||
"kfz-goods-pricing/internal/config"
|
||
"kfz-goods-pricing/internal/database"
|
||
"kfz-goods-pricing/internal/handler"
|
||
"kfz-goods-pricing/internal/repository"
|
||
"kfz-goods-pricing/internal/service"
|
||
)
|
||
|
||
func main() {
|
||
// 日志同时输出到GUI窗口和本地文件
|
||
log.SetOutput(io.MultiWriter(&guiLogWriter{}, initFileLog()))
|
||
|
||
log.Printf("孔网商品定价 %s 启动中...", version)
|
||
|
||
// 加载配置
|
||
cfg, err := config.Load("./config/config.yaml")
|
||
if err != nil {
|
||
fatalExit("加载配置文件失败: %v", err)
|
||
}
|
||
config.SetGlobal(cfg)
|
||
log.Printf("配置加载成功: port=%s, timer=%ds, rate_limit=%ds", cfg.Port, cfg.TimerInterval, cfg.APIRateLimit)
|
||
|
||
global := config.GetGlobal()
|
||
marshal, _ := json.Marshal(global)
|
||
log.Printf("config: %s", string(marshal))
|
||
|
||
// 初始化数据库
|
||
if err := database.InitDB("./data/goods_pricing.db"); err != nil {
|
||
fatalExit("初始化数据库失败: %v", err)
|
||
}
|
||
defer database.CloseDB()
|
||
log.Println("数据库初始化成功")
|
||
|
||
// 初始化服务
|
||
proxy := ""
|
||
tokenRepo := repository.NewTokenRepository()
|
||
goodsService := service.NewGoodsService(proxy, cfg.APIRateLimit, cfg.CallbackURL, tokenRepo)
|
||
goodsHandler := handler.NewGoodsHandler(goodsService)
|
||
|
||
// Token相关
|
||
tokenHandler := handler.NewTokenHandler(tokenRepo)
|
||
|
||
// Kfz登录
|
||
kfzHandler := handler.NewKfzHandler()
|
||
|
||
// 配置相关
|
||
configHandler := handler.NewConfigHandler("./config/config.yaml")
|
||
|
||
// 注册路由(带 CORS 中间件)
|
||
http.HandleFunc("/api/goods/query", corsMiddleware(goodsHandler.QueryGoods))
|
||
|
||
// Token路由
|
||
http.HandleFunc("/api/token/add", corsMiddleware(tokenHandler.BatchAddTokens))
|
||
http.HandleFunc("/api/token/list", corsMiddleware(tokenHandler.GetAllTokens))
|
||
http.HandleFunc("/api/token/delete", corsMiddleware(tokenHandler.DeleteToken))
|
||
http.HandleFunc("/api/token/update", corsMiddleware(tokenHandler.UpdateToken))
|
||
http.HandleFunc("/api/token/enabled", corsMiddleware(tokenHandler.GetEnabledTokens))
|
||
|
||
// Kfz登录路由
|
||
http.HandleFunc("/api/kfz/login", corsMiddleware(kfzHandler.KfzLogin))
|
||
|
||
// 配置路由
|
||
http.HandleFunc("/api/config/price/get", corsMiddleware(configHandler.GetConfigPrice))
|
||
http.HandleFunc("/api/config/price/set", corsMiddleware(configHandler.SetConfigPrice))
|
||
|
||
// 启动定时器
|
||
goodsService.StartTimerScheduler(cfg.TimerInterval)
|
||
log.Printf("定时器已启动,%d秒后开始首次同步", cfg.TimerInterval)
|
||
|
||
// 启动HTTP服务(后台)
|
||
go func() {
|
||
log.Printf("服务器正在启动 %s", cfg.Port)
|
||
if err := http.ListenAndServe(fmt.Sprintf(":%s", cfg.Port), nil); err != nil {
|
||
fatalExit("启动服务器失败: %v", err)
|
||
}
|
||
}()
|
||
|
||
// 启动GUI窗口(阻塞直到窗口关闭)
|
||
runGUI()
|
||
}
|
||
|
||
// corsMiddleware CORS 跨域中间件
|
||
func corsMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
||
return func(w http.ResponseWriter, r *http.Request) {
|
||
// 允许所有来源
|
||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||
// 允许的方法
|
||
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
||
// 允许的请求头
|
||
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")
|
||
|
||
// 预检请求直接返回
|
||
if r.Method == http.MethodOptions {
|
||
w.WriteHeader(http.StatusOK)
|
||
return
|
||
}
|
||
|
||
// 调用实际处理函数
|
||
next(w, r)
|
||
}
|
||
}
|