123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- package handlers
- import (
- "Wine-Server/utils"
- "Wine-Server/utils/tables"
- "context"
- "database/sql"
- "github.com/gin-contrib/cors"
- "github.com/gin-gonic/gin"
- "github.com/redis/go-redis/v9"
- "github.com/wechatpay-apiv3/wechatpay-go/core"
- "github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers"
- "github.com/wechatpay-apiv3/wechatpay-go/core/downloader"
- "github.com/wechatpay-apiv3/wechatpay-go/core/notify"
- "github.com/wechatpay-apiv3/wechatpay-go/core/option"
- "github.com/wechatpay-apiv3/wechatpay-go/services/payments/native"
- wx "github.com/wechatpay-apiv3/wechatpay-go/utils"
- "log"
- "os"
- )
- type routeFn func(*gin.Engine)
- type createTableFn func() error
- type App struct {
- router *gin.Engine
- address string
- }
- func lostHandler(ctx *gin.Context) {
- ctx.JSON(utils.HttpNotFound, utils.Fail("api/resource not found"))
- }
- func loggerFormat(timeFmt string) gin.HandlerFunc {
- return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
- return utils.Format("[wine] %s - %s [%s %s %s] %s, %s %d %s: %s\n",
- param.ClientIP,
- param.TimeStamp.Format(timeFmt),
- param.MethodColor(), param.Method, param.ResetColor(),
- param.Path,
- param.StatusCodeColor(), param.StatusCode, param.ResetColor(),
- param.ErrorMessage,
- )
- })
- }
- func CreateApp(config *utils.Config) *App {
- if config.Release {
- gin.SetMode(gin.ReleaseMode)
- } else {
- gin.SetMode(gin.DebugMode)
- }
- utils.ServerPrefix = config.ServerPrefix
- utils.Logger = log.New(os.Stderr, "[wine] ", log.Ldate|log.Ltime|log.Lshortfile|log.Lmsgprefix)
- initWxPay(config)
- initDatabase(config)
- router := createRouter(config)
- return &App{router: router, address: config.ServerAddr}
- }
- func (app *App) RouteRegister(routeFns ...routeFn) {
- for _, fn := range routeFns {
- fn(app.router)
- }
- }
- func (app *App) Start() {
- err := app.router.Run(app.address)
- if err != nil {
- utils.Logger.Printf("server can't run on address[%s] for: %s", app.address, err)
- }
- }
- func initWxPay(config *utils.Config) {
- utils.WxTitle, utils.WxV3Key = config.WxPayTitle, config.WxApiV3Key
- utils.WxAppId, utils.WxMchId = config.WxAppId, config.WxMerchantAcc
- utils.WxCertSeq, utils.WxCertPath = config.WxApiCertSeq, config.WxApiCertPath
- var err error
- utils.WxPrivateKey, err = wx.LoadPrivateKeyWithPath(config.WxApiCertPath)
- if err != nil {
- utils.Logger.Fatalf("load merchant private key error: %s\n", err)
- }
- opts := []core.ClientOption{
- option.WithWechatPayAutoAuthCipher(config.WxMerchantAcc, config.WxApiCertSeq, utils.WxPrivateKey, config.WxApiV3Key),
- }
- utils.WxPayCli = context.Background()
- client, err := core.NewClient(utils.WxPayCli, opts...)
- if err != nil {
- utils.Logger.Fatalf("new wechat pay client error: %s\n", err)
- }
- utils.WxPaySrv = native.NativeApiService{Client: client}
- err = downloader.MgrInstance().RegisterDownloaderWithPrivateKey(
- utils.WxPayCli, utils.WxPrivateKey, config.WxApiCertSeq, config.WxMerchantAcc, config.WxApiV3Key,
- )
- visitor := downloader.MgrInstance().GetCertificateVisitor(config.WxMerchantAcc)
- utils.WxCrtHdr, err = notify.NewRSANotifyHandler(config.WxApiV3Key, verifiers.NewSHA256WithRSAVerifier(visitor))
- if err != nil {
- utils.Logger.Fatalf("wxpay notice handler init error: %s\n", err)
- }
- }
- func initDatabase(config *utils.Config) {
- // init
- utils.Redis = redis.NewClient(&redis.Options{
- Addr: utils.Format("%s:%d", config.RedisHost, config.RedisPort),
- Password: config.RedisPass, DB: config.RedisDatabase,
- })
- db, err := sql.Open(
- "mysql",
- utils.Format(
- "%s:%s@tcp(%s:%d)/%s?loc=Local&charset=utf8&parseTime=true",
- config.MysqlUser, config.MysqlPass, config.MysqlHost, config.MysqlPort, config.MysqlDatabase,
- ),
- )
- if err != nil {
- utils.Logger.Fatalf("mysql init failed: %s\n", err)
- }
- err = db.Ping()
- if err != nil {
- utils.Logger.Fatalf("mysql connection failed: %s\n", err)
- }
- utils.Mysql = db
- // create
- toCreate := []createTableFn{
- tables.CreateAdvertiseTable, tables.CreateDeviceTable, tables.CreateManagerTable,
- tables.CreateParamsTable, tables.CreateVersionTable, tables.CreateWineTable,
- tables.CreateTradeTable, tables.CreateWorkerTable, tables.CreateUserTable,
- tables.CreateRefundTable, tables.CreateOperationTable, tables.CreateWarnTable,
- tables.CreateChangeTable,
- }
- for _, Fn := range toCreate {
- err = Fn()
- if err != nil {
- utils.Logger.Fatalf("create mysql tables failed: %s\n", err)
- }
- }
- }
- func createRouter(config *utils.Config) *gin.Engine {
- router := gin.New()
- err := router.SetTrustedProxies([]string{"127.0.0.1"})
- if err != nil {
- utils.Logger.Fatalf("can't trust '127.0.0.1', for: %s", err)
- }
- if err = utils.LoadRsaKeyPairs(config); err != nil {
- utils.Logger.Fatalf("can't generate private and public key.")
- }
- conf := cors.DefaultConfig()
- allow := append(conf.AllowHeaders, "Token", "Device")
- conf.AllowAllOrigins, conf.AllowHeaders = true, allow
- router.Use(loggerFormat(config.TimeFormat), gin.Recovery(), utils.ErrorHandler, cors.New(conf))
- router.NoRoute(lostHandler)
- router.Static("/static", "./static")
- return router
- }
|