package main import ( "fmt" "log" "strconv" _ "think-go/models" _ "think-go/routers" "think-go/utils" "time" "github.com/beego/beego/v2/client/orm" beego "github.com/beego/beego/v2/server/web" bcontext "github.com/beego/beego/v2/server/web/context" _ "github.com/go-sql-driver/mysql" ) const ( defaultMaxIdleConns = 10 defaultMaxOpenConns = 100 defaultConnMaxLife = 300 ) func getStringConfig(key string, fallback string) string { v, err := beego.AppConfig.String(key) if err != nil || v == "" { return fallback } return v } func getIntConfig(key string, fallback int) int { raw, err := beego.AppConfig.String(key) if err != nil || raw == "" { return fallback } v, err := strconv.Atoi(raw) if err != nil || v <= 0 { log.Printf("invalid config %s=%q, fallback=%d", key, raw, fallback) return fallback } return v } func buildMySQLDSN() string { user := getStringConfig("db_user", "root") password := getStringConfig("db_password", "root") host := getStringConfig("db_host", "127.0.0.1") port := getStringConfig("db_port", "3306") name := getStringConfig("db_name", "gva") charset := getStringConfig("db_charset", "utf8mb4") parseTime := getStringConfig("db_parse_time", "True") loc := getStringConfig("db_loc", "Local") return fmt.Sprintf( "%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=%s&loc=%s", user, password, host, port, name, charset, parseTime, loc, ) } func init() { if err := orm.RegisterDriver("mysql", orm.DRMySQL); err != nil { log.Fatalf("register mysql driver failed: %v", err) } dbConn := getStringConfig("sqlconn", "") if dbConn == "" { dbConn = buildMySQLDSN() } maxIdle := getIntConfig("db_max_idle_conns", defaultMaxIdleConns) maxOpen := getIntConfig("db_max_open_conns", defaultMaxOpenConns) connLife := getIntConfig("db_conn_max_lifetime_sec", defaultConnMaxLife) if err := orm.RegisterDataBase( "default", "mysql", dbConn, orm.MaxIdleConnections(maxIdle), orm.MaxOpenConnections(maxOpen), orm.ConnMaxLifetime(time.Duration(connLife)*time.Second), ); err != nil { log.Fatalf("register database failed: %v", err) } if runmode, _ := beego.AppConfig.String("runmode"); runmode == "dev" { orm.Debug = true } if err := utils.InitRedis(); err != nil { log.Fatalf("init redis failed: %v", err) } if err := utils.InitWxPay(); err != nil { log.Fatalf("init wxpay failed: %v", err) } // 注册全局CORS过滤器 beego.InsertFilter("*", beego.BeforeRouter, CORSFilter) } // CORSFilter 用于处理跨域请求 func CORSFilter(ctx *bcontext.Context) { origin := ctx.Input.Header("Origin") if origin != "" { ctx.Output.Header("Access-Control-Allow-Origin", origin) } ctx.Output.Header("Access-Control-Allow-Credentials", "true") ctx.Output.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH, HEAD") // 建议把前端 fetch 用到的所有 Header 都加上 ctx.Output.Header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With, Accept, Origin") ctx.Output.Header("Access-Control-Max-Age", "86400") if ctx.Input.Method() == "OPTIONS" { ctx.Output.SetStatus(200) // 显式结束请求,防止进入后续逻辑 return } } func main() { defer utils.CloseRedis() beego.Run() }