148 lines
4.4 KiB
Go
148 lines
4.4 KiB
Go
package main
|
||
|
||
import (
|
||
"cid/controller/app"
|
||
"cid/controller/data"
|
||
"cid/controller/dataengine"
|
||
"cid/controller/mapping"
|
||
"cid/controller/yidun"
|
||
controllerYidun "cid/controller/yidun"
|
||
serviceDataengine "cid/service/dataengine"
|
||
serviceYidun "cid/service/yidun"
|
||
"context"
|
||
"fmt"
|
||
"os"
|
||
"path/filepath"
|
||
"time"
|
||
|
||
_ "gitea.com/red-future/common/consul"
|
||
"gitea.com/red-future/common/http"
|
||
"gitea.com/red-future/common/jaeger"
|
||
_ "github.com/gogf/gf/contrib/drivers/pgsql/v2"
|
||
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
||
"github.com/gogf/gf/v2/frame/g"
|
||
"github.com/gogf/gf/v2/net/ghttp"
|
||
)
|
||
|
||
func main() {
|
||
ctx := context.Background()
|
||
defer jaeger.ShutDown(ctx)
|
||
|
||
// 设置时区为东八区
|
||
loc, err := time.LoadLocation("Asia/Shanghai")
|
||
if err == nil {
|
||
time.Local = loc
|
||
}
|
||
// 关键:设置 PGTZ 环境变量,lib/pq 驱动在连接 pg 时会自动设置 session timezone
|
||
// 确保从数据库读取 TIMESTAMPTZ 时返回的是东八区时间,gtime.Time 序列化输出北京时间
|
||
os.Setenv("PGTZ", "Asia/Shanghai")
|
||
|
||
// 初始化易盾客户端
|
||
if err := serviceYidun.InitYidunClients(ctx); err != nil {
|
||
panic(fmt.Sprintf("初始化易盾客户端失败: %v", err))
|
||
}
|
||
|
||
g.Log().Info(ctx, "易盾客户端初始化成功")
|
||
|
||
// 启动内容送检定时任务
|
||
startContentCheckService(ctx)
|
||
|
||
// 获取前端目录
|
||
frontendDir := getFrontendDir()
|
||
|
||
// 注册前端静态文件路由(在使用 http.Httpserver 之前)
|
||
registerFrontendRoutes(frontendDir)
|
||
|
||
// 注册 API 路由并启动服务器
|
||
http.RouteRegister([]interface{}{
|
||
data.Platform,
|
||
data.ApiInterface,
|
||
data.DataFetch,
|
||
mapping.DataMapping,
|
||
app.Application,
|
||
controllerYidun.YidunController,
|
||
controllerYidun.YidunCallback,
|
||
yidun.ContentCheck,
|
||
dataengine.MaterialVerify,
|
||
})
|
||
|
||
// 打印前端访问地址
|
||
port := g.Cfg().MustGet(ctx, "server.address", ":3001").String()
|
||
g.Log().Info(ctx, "============================================")
|
||
g.Log().Infof(ctx, "🌐 前端访问地址: http://localhost%s", port)
|
||
g.Log().Info(ctx, "============================================")
|
||
|
||
select {}
|
||
}
|
||
|
||
// getFrontendDir 获取前端目录路径
|
||
func getFrontendDir() string {
|
||
execPath, _ := os.Executable()
|
||
execDir := filepath.Dir(execPath)
|
||
frontendDir := filepath.Join(execDir, "resource", "frontend")
|
||
|
||
if _, err := os.Stat(frontendDir); os.IsNotExist(err) {
|
||
cwd, _ := os.Getwd()
|
||
frontendDir = filepath.Join(cwd, "resource", "frontend")
|
||
}
|
||
|
||
return frontendDir
|
||
}
|
||
|
||
// registerFrontendRoutes 注册前端静态文件路由
|
||
func registerFrontendRoutes(frontendDir string) {
|
||
if _, err := os.Stat(frontendDir); os.IsNotExist(err) {
|
||
g.Log().Warningf(context.Background(), "前端目录不存在: %s", frontendDir)
|
||
return
|
||
}
|
||
|
||
s := http.Httpserver
|
||
|
||
// 静态资源路由
|
||
s.BindHandler("/frontend/{file}", func(r *ghttp.Request) {
|
||
file := r.Get("file").String()
|
||
filePath := filepath.Join(frontendDir, file)
|
||
if _, err := os.Stat(filePath); err == nil {
|
||
r.Response.ServeFile(filePath)
|
||
} else {
|
||
r.Response.WriteStatus(404)
|
||
}
|
||
})
|
||
|
||
// 首页/主入口
|
||
s.BindHandler("/", func(r *ghttp.Request) {
|
||
indexFile := filepath.Join(frontendDir, "material-verify.html")
|
||
if _, err := os.Stat(indexFile); err == nil {
|
||
r.Response.ServeFile(indexFile)
|
||
} else {
|
||
r.Response.Write("<html><body><h1>CID Backend Service</h1><p>前端页面未找到</p></body></html>")
|
||
}
|
||
})
|
||
}
|
||
|
||
// startContentCheckService 启动内容送检服务
|
||
func startContentCheckService(ctx context.Context) {
|
||
// 检查是否启用定时送检任务
|
||
schedulerEnabled := g.Cfg().MustGet(ctx, "content_check.scheduler_enabled", true).Bool()
|
||
if !schedulerEnabled {
|
||
g.Log().Info(ctx, "定时送检任务已禁用(scheduler_enabled=false),仅支持API手动送检")
|
||
return
|
||
}
|
||
|
||
// 配置送检服务参数
|
||
config := serviceDataengine.ContentCheckConfig{
|
||
BatchSize: g.Cfg().MustGet(ctx, "content_check.batch_size", 10).Int(),
|
||
ImageEnabled: g.Cfg().MustGet(ctx, "content_check.image_enabled", true).Bool(),
|
||
VideoEnabled: g.Cfg().MustGet(ctx, "content_check.video_enabled", true).Bool(),
|
||
IntervalSeconds: g.Cfg().MustGet(ctx, "content_check.interval_seconds", 30).Int(),
|
||
}
|
||
serviceDataengine.TencentContentCheck.SetConfig(config)
|
||
|
||
// 启动服务
|
||
if err := serviceDataengine.TencentContentCheck.Start(ctx); err != nil {
|
||
g.Log().Errorf(ctx, "启动内容送检服务失败: %v", err)
|
||
} else {
|
||
g.Log().Info(ctx, "内容送检服务启动成功")
|
||
}
|
||
}
|