setup.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package handlers
  2. import (
  3. "Wine-Server/utils"
  4. "Wine-Server/utils/tables"
  5. "context"
  6. "database/sql"
  7. "github.com/gin-contrib/cors"
  8. "github.com/gin-gonic/gin"
  9. "github.com/redis/go-redis/v9"
  10. "github.com/wechatpay-apiv3/wechatpay-go/core"
  11. "github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers"
  12. "github.com/wechatpay-apiv3/wechatpay-go/core/downloader"
  13. "github.com/wechatpay-apiv3/wechatpay-go/core/notify"
  14. "github.com/wechatpay-apiv3/wechatpay-go/core/option"
  15. "github.com/wechatpay-apiv3/wechatpay-go/services/payments/native"
  16. wx "github.com/wechatpay-apiv3/wechatpay-go/utils"
  17. "log"
  18. "os"
  19. )
  20. type routeFn func(*gin.Engine)
  21. type createTableFn func() error
  22. type App struct {
  23. router *gin.Engine
  24. address string
  25. }
  26. func lostHandler(ctx *gin.Context) {
  27. ctx.JSON(utils.HttpNotFound, utils.Fail("api/resource not found"))
  28. }
  29. func loggerFormat(timeFmt string) gin.HandlerFunc {
  30. return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
  31. return utils.Format("[wine] %s - %s [%s %s %s] %s, %s %d %s: %s\n",
  32. param.ClientIP,
  33. param.TimeStamp.Format(timeFmt),
  34. param.MethodColor(), param.Method, param.ResetColor(),
  35. param.Path,
  36. param.StatusCodeColor(), param.StatusCode, param.ResetColor(),
  37. param.ErrorMessage,
  38. )
  39. })
  40. }
  41. func CreateApp(config *utils.Config) *App {
  42. if config.Release {
  43. gin.SetMode(gin.ReleaseMode)
  44. } else {
  45. gin.SetMode(gin.DebugMode)
  46. }
  47. utils.ServerPrefix = config.ServerPrefix
  48. utils.Logger = log.New(os.Stderr, "[wine] ", log.Ldate|log.Ltime|log.Lshortfile|log.Lmsgprefix)
  49. utils.VipScanApi, utils.VipPayApi, utils.VipCallback = config.VipScanApi, config.VipPayApi, config.VipCallback
  50. initWxPay(config)
  51. initDatabase(config)
  52. router := createRouter(config)
  53. return &App{router: router, address: config.ServerAddr}
  54. }
  55. func (app *App) RouteRegister(routeFns ...routeFn) {
  56. for _, fn := range routeFns {
  57. fn(app.router)
  58. }
  59. }
  60. func (app *App) Start() {
  61. err := app.router.Run(app.address)
  62. if err != nil {
  63. utils.Logger.Printf("server can't run on address[%s] for: %s", app.address, err)
  64. }
  65. }
  66. func initWxPay(config *utils.Config) {
  67. utils.WxTitle, utils.WxV3Key = config.WxPayTitle, config.WxApiV3Key
  68. utils.WxAppId, utils.WxMchId = config.WxAppId, config.WxMerchantAcc
  69. utils.WxCertSeq = config.WxApiCertSeq
  70. var err error
  71. utils.WxPrivateKey, err = wx.LoadPrivateKeyWithPath(config.WxApiCertPath)
  72. if err != nil {
  73. utils.Logger.Fatalf("load merchant private key error: %s\n", err)
  74. }
  75. opts := []core.ClientOption{
  76. option.WithWechatPayAutoAuthCipher(config.WxMerchantAcc, config.WxApiCertSeq, utils.WxPrivateKey, config.WxApiV3Key),
  77. }
  78. utils.WxPayCli = context.Background()
  79. client, err := core.NewClient(utils.WxPayCli, opts...)
  80. if err != nil {
  81. utils.Logger.Fatalf("new wechat pay client error: %s\n", err)
  82. }
  83. utils.WxPaySrv = native.NativeApiService{Client: client}
  84. err = downloader.MgrInstance().RegisterDownloaderWithPrivateKey(
  85. utils.WxPayCli, utils.WxPrivateKey, config.WxApiCertSeq, config.WxMerchantAcc, config.WxApiV3Key,
  86. )
  87. visitor := downloader.MgrInstance().GetCertificateVisitor(config.WxMerchantAcc)
  88. _, err = notify.NewRSANotifyHandler(config.WxApiV3Key, verifiers.NewSHA256WithRSAVerifier(visitor))
  89. if err != nil {
  90. utils.Logger.Fatalf("wxpay notice handler init error: %s\n", err)
  91. }
  92. }
  93. func initDatabase(config *utils.Config) {
  94. // init
  95. utils.Redis = redis.NewClient(&redis.Options{
  96. Addr: utils.Format("%s:%d", config.RedisHost, config.RedisPort),
  97. Password: config.RedisPass, DB: config.RedisDatabase,
  98. })
  99. db, err := sql.Open(
  100. "mysql",
  101. utils.Format(
  102. "%s:%s@tcp(%s:%d)/%s?loc=Local&charset=utf8&parseTime=true",
  103. config.MysqlUser, config.MysqlPass, config.MysqlHost, config.MysqlPort, config.MysqlDatabase,
  104. ),
  105. )
  106. if err != nil {
  107. utils.Logger.Fatalf("mysql init failed: %s\n", err)
  108. }
  109. err = db.Ping()
  110. if err != nil {
  111. utils.Logger.Fatalf("mysql connection failed: %s\n", err)
  112. }
  113. utils.Mysql = db
  114. // create
  115. toCreate := []createTableFn{
  116. tables.CreateAdvertiseTable, tables.CreateDeviceTable, tables.CreateManagerTable,
  117. tables.CreateParamsTable, tables.CreateVersionTable, tables.CreateWineTable,
  118. tables.CreateTradeTable, tables.CreateWorkerTable, tables.CreateUserTable,
  119. tables.CreateRefundTable, tables.CreateOperationTable, tables.CreateWarnTable,
  120. tables.CreateChangeTable,
  121. }
  122. for _, Fn := range toCreate {
  123. err = Fn()
  124. if err != nil {
  125. utils.Logger.Fatalf("create mysql tables failed: %s\n", err)
  126. }
  127. }
  128. }
  129. func createRouter(config *utils.Config) *gin.Engine {
  130. router := gin.New()
  131. err := router.SetTrustedProxies([]string{"127.0.0.1"})
  132. if err != nil {
  133. utils.Logger.Fatalf("can't trust '127.0.0.1', for: %s", err)
  134. }
  135. if err = utils.LoadRsaKeyPairs(config); err != nil {
  136. utils.Logger.Fatalf("can't generate private and public key.")
  137. }
  138. conf := cors.DefaultConfig()
  139. allow := append(conf.AllowHeaders, "Token", "Device")
  140. conf.AllowAllOrigins, conf.AllowHeaders = true, allow
  141. router.Use(loggerFormat(config.TimeFormat), gin.Recovery(), utils.ErrorHandler, cors.New(conf))
  142. router.NoRoute(lostHandler)
  143. router.Static("/static", "./static")
  144. return router
  145. }