迁移 Flutter 端与训练脚本,模型/训练产物移出 git(遵循纯代码约定)
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
|
||||
"observer-server/biz/controller"
|
||||
"observer-server/common"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
initDatabase(ctx)
|
||||
|
||||
s := g.Server()
|
||||
// 客户端接口组:统一响应包装 {"code":0,"message":"ok","data":...}
|
||||
// 账号组公开(注册/登录),业务组(订单/授权)需登录态(Authorization: Bearer token)
|
||||
s.Group("/api/v1", func(group *ghttp.RouterGroup) {
|
||||
group.Middleware(common.UnifiedResponse)
|
||||
common.BindController(group, controller.Auth)
|
||||
})
|
||||
s.Group("/api/v1", func(group *ghttp.RouterGroup) {
|
||||
group.Middleware(common.UnifiedResponse, common.AuthRequired)
|
||||
common.BindController(group, controller.Order, controller.License)
|
||||
})
|
||||
// 支付回调组:不做统一包装,按渠道应答格式直接返回(微信 SUCCESS/FAIL JSON、支付宝 success/failure 文本)
|
||||
s.Group("/api/v1/payment", func(group *ghttp.RouterGroup) {
|
||||
common.BindController(group, controller.Payment)
|
||||
})
|
||||
// 管理端接口组:统一响应包装 + 静态 token 鉴权
|
||||
s.Group("/api/v1/admin", func(group *ghttp.RouterGroup) {
|
||||
group.Middleware(common.UnifiedResponse, common.AdminAuth)
|
||||
common.BindController(group, controller.Admin)
|
||||
})
|
||||
// 管理端静态页面托管:构建产物输出到 admin_dist(server_admin/ 构建),SPA history 路由回退 index.html;
|
||||
// 目录不存在(尚未构建前端)时跳过,不影响 API 启动
|
||||
if stat, err := os.Stat("./admin_dist"); err == nil && stat.IsDir() {
|
||||
s.AddStaticPath("/admin", "./admin_dist")
|
||||
s.BindMiddlewareDefault(common.SpaFallback("./admin_dist", "/admin"))
|
||||
} else {
|
||||
g.Log().Warningf(ctx, "admin_dist 不存在,跳过管理端静态托管(cd server_admin && npm run build)")
|
||||
}
|
||||
s.Run()
|
||||
}
|
||||
|
||||
// initDatabase 数据初始化:存量库以 PRAGMA user_version 版本化迁移;
|
||||
// v2 = 删 license.plan_id 列(无业务语义);v3 = 删 plan 表(套餐已配置化,清残留表)。
|
||||
func initDatabase(ctx context.Context) {
|
||||
res, err := g.DB().GetAll(ctx, "PRAGMA user_version")
|
||||
if err != nil {
|
||||
g.Log().Fatalf(ctx, "读取库版本失败: %+v", err)
|
||||
}
|
||||
version := 0
|
||||
if len(res) > 0 {
|
||||
version = gconv.Int(res[0]["user_version"])
|
||||
}
|
||||
if version < 2 {
|
||||
// v2:删除 license.plan_id(只留到期时间;PRAGMA table_info 检测列存在才 DROP,
|
||||
// 全新库建表已无此列、直接跳过,不丢账号数据)
|
||||
cols, err := g.DB().GetAll(ctx, "PRAGMA table_info(license)")
|
||||
if err != nil {
|
||||
g.Log().Fatalf(ctx, "读取 license 表结构失败: %+v", err)
|
||||
}
|
||||
hasPlanId := false
|
||||
for _, col := range cols {
|
||||
if gconv.String(col["name"]) == "plan_id" {
|
||||
hasPlanId = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasPlanId {
|
||||
if _, err := g.DB().Exec(ctx, "ALTER TABLE license DROP COLUMN plan_id"); err != nil {
|
||||
g.Log().Fatalf(ctx, "删除 license.plan_id 列失败: %+v", err)
|
||||
}
|
||||
}
|
||||
if _, err := g.DB().Exec(ctx, "PRAGMA user_version = 2"); err != nil {
|
||||
g.Log().Fatalf(ctx, "库版本写入失败: %+v", err)
|
||||
}
|
||||
g.Log().Infof(ctx, "数据库初始化完成(version=2)")
|
||||
}
|
||||
if version < 3 {
|
||||
// v3:套餐改 config.yml 配置后清理残留 plan 表(订单快照 payment_order.plan_id 不受影响)
|
||||
if _, err := g.DB().Exec(ctx, "DROP TABLE IF EXISTS plan"); err != nil {
|
||||
g.Log().Fatalf(ctx, "删除残留 plan 表失败: %+v", err)
|
||||
}
|
||||
if _, err := g.DB().Exec(ctx, "PRAGMA user_version = 3"); err != nil {
|
||||
g.Log().Fatalf(ctx, "库版本写入失败: %+v", err)
|
||||
}
|
||||
g.Log().Infof(ctx, "数据库初始化完成(version=3)")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user