feat: 新增bj_power_mes项目主入口文件
实现了带管理员校验的CLI命令行工具,支持migrate/seed/reset-all/serve命令,包含数据库迁移、种子数据初始化、全量重置以及HTTP服务启动功能
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"crypto/subtle"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"bj_power_mes/common/logx"
|
||||
"bj_power_mes/internal/config"
|
||||
"bj_power_mes/internal/db"
|
||||
"bj_power_mes/internal/eventlog"
|
||||
"bj_power_mes/internal/handler"
|
||||
"bj_power_mes/internal/logic"
|
||||
"bj_power_mes/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/conf"
|
||||
gologx "github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
var configFile = flag.String("f", "etc/bj_power_mes-api.yaml", "the config file")
|
||||
|
||||
// promptPassword 从终端读取一行输入(不隐藏回显,用于运维终端操作)
|
||||
func promptPassword(msg string) string {
|
||||
fmt.Print(msg)
|
||||
line, _ := bufio.NewReader(os.Stdin).ReadString('\n')
|
||||
return strings.TrimRight(line, "\r\n")
|
||||
}
|
||||
|
||||
// adminGate 管理员密码门禁:敏感命令行操作(migrate/seed/reset-all)必须输入与配置
|
||||
// Cli.AdminPassword 一致的密码才放行;校验失败记录日志并终止,绝不继续执行。
|
||||
func adminGate(c config.Config) bool {
|
||||
pwd := promptPassword("请输入管理员密码以执行 [" + flag.Arg(0) + "]: ")
|
||||
if subtle.ConstantTimeCompare([]byte(pwd), []byte(c.Cli.AdminPassword)) != 1 {
|
||||
gologx.Errorf("敏感命令 [%s] 因管理员密码校验失败被终止", flag.Arg(0))
|
||||
fmt.Println("管理员密码不正确,已终止该操作。")
|
||||
return false
|
||||
}
|
||||
gologx.Infof("敏感命令 [%s] 已通过管理员密码校验", flag.Arg(0))
|
||||
return true
|
||||
}
|
||||
|
||||
// newSvc 最小 ServiceContext(CLI 场景:只连库 + 事件日志写入器)
|
||||
func newSvc(c config.Config) *svc.ServiceContext {
|
||||
client, _ := db.MustNewDB(c.Database)
|
||||
return &svc.ServiceContext{
|
||||
Config: c,
|
||||
EntClient: client,
|
||||
EventLog: eventlog.NewWriter(client),
|
||||
}
|
||||
}
|
||||
|
||||
// runMigrate 建库(若不存在)+ 建表/补列/清理旧结构(幂等,不删业务数据)
|
||||
func runMigrate(c config.Config) {
|
||||
if err := db.EnsureDB(c.Database); err != nil {
|
||||
gologx.Errorf("ensure database failed: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
client, sqlDB := db.MustNewDB(c.Database)
|
||||
defer client.Close()
|
||||
defer sqlDB.Close()
|
||||
if err := db.EnsureSchema(client, sqlDB); err != nil {
|
||||
gologx.Errorf("migrate failed: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("migrate: 数据库结构迁移成功(建表/补列/清理退役结构,未删除业务数据)。")
|
||||
}
|
||||
|
||||
// runSeed 建库建表(若不存在)+ 灌基础种子(工位/接驳台/权限等,不删数据)
|
||||
func runSeed(c config.Config) {
|
||||
if err := db.EnsureDB(c.Database); err != nil {
|
||||
gologx.Errorf("ensure database failed: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
client, sqlDB := db.MustNewDB(c.Database)
|
||||
defer client.Close()
|
||||
defer sqlDB.Close()
|
||||
if err := db.EnsureSchema(client, sqlDB); err != nil {
|
||||
gologx.Errorf("seed migrate failed: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
s := logic.New(newSvc(c))
|
||||
if err := s.Seed(context.Background()); err != nil {
|
||||
gologx.Errorf("seed failed: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("seed: 基础数据已对齐(工位/接驳台/权限等)。")
|
||||
}
|
||||
|
||||
// runResetAll 清空并重建全部表 + 重灌全部种子。此操作不可恢复!
|
||||
func runResetAll(c config.Config) {
|
||||
if err := db.EnsureDB(c.Database); err != nil {
|
||||
gologx.Errorf("ensure database failed: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := db.DropAllTables(c.Database); err != nil {
|
||||
gologx.Errorf("reset-all drop failed: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
client, sqlDB := db.MustNewDB(c.Database)
|
||||
defer client.Close()
|
||||
defer sqlDB.Close()
|
||||
if err := db.EnsureSchema(client, sqlDB); err != nil {
|
||||
gologx.Errorf("reset-all migrate failed: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
s := logic.New(newSvc(c))
|
||||
if err := s.Seed(context.Background()); err != nil {
|
||||
gologx.Errorf("reset-all seed failed: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("reset-all: 已清空并重建全部表,写入基础数据(管理员 admin/123456)。")
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
|
||||
// 按天日志:logs/bj_power_mes-2026-01-02.log,保留 30 天(go-zero logx Writer 适配 slog)
|
||||
if c.Logger.Filename != "" {
|
||||
logger := logx.NewLogger(c.Logger)
|
||||
logx.SetDefault(logger)
|
||||
gologx.SetWriter(logger)
|
||||
}
|
||||
|
||||
// 命令行子命令:DDL/删库/种子等敏感操作一律显式触发 + 管理员密码门禁,
|
||||
// 绝不随服务启动自动执行(migrate / seed / reset-all / serve)。
|
||||
switch cmd := flag.Arg(0); cmd {
|
||||
case "reset-all":
|
||||
fmt.Println("reset-all: 即将清空并重建 MES 全部表,此操作不可恢复!")
|
||||
if !adminGate(c) {
|
||||
os.Exit(1)
|
||||
}
|
||||
runResetAll(c)
|
||||
return
|
||||
case "seed":
|
||||
if !adminGate(c) {
|
||||
os.Exit(1)
|
||||
}
|
||||
runSeed(c)
|
||||
return
|
||||
case "migrate":
|
||||
if !adminGate(c) {
|
||||
os.Exit(1)
|
||||
}
|
||||
runMigrate(c)
|
||||
return
|
||||
case "", "serve":
|
||||
// 正常启动服务:落到下方启动逻辑
|
||||
default:
|
||||
fmt.Println("未知命令: " + cmd + ";可用命令: migrate / seed / reset-all / serve")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
defer server.Stop()
|
||||
|
||||
ctx := svc.NewServiceContext(c)
|
||||
|
||||
handler.RegisterRoutes(server, ctx)
|
||||
handler.RegisterProductionRoutes(server, ctx)
|
||||
|
||||
// 磁盘空间监控:每天 DiskCheckHour 点检测附件根目录剩余空间
|
||||
handler.StartDiskMonitor(ctx)
|
||||
|
||||
fmt.Printf("Starting bj_power_mes server at %s:%d...\n", c.Host, c.Port)
|
||||
gologx.Infof("Starting bj_power_mes server at %s:%d...", c.Host, c.Port)
|
||||
|
||||
server.Start()
|
||||
}
|
||||
Reference in New Issue
Block a user