setup.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. initWxPay(config)
  50. initDatabase(config)
  51. router := createRouter(config)
  52. return &App{router: router, address: config.ServerAddr}
  53. }
  54. func (app *App) RouteRegister(routeFns ...routeFn) {
  55. for _, fn := range routeFns {
  56. fn(app.router)
  57. }
  58. }
  59. func (app *App) Start() {
  60. err := app.router.Run(app.address)
  61. if err != nil {
  62. utils.Logger.Printf("server can't run on address[%s] for: %s", app.address, err)
  63. }
  64. }
  65. func initWxPay(config *utils.Config) {
  66. utils.WxTitle, utils.WxV3Key = config.WxPayTitle, config.WxApiV3Key
  67. utils.WxAppId, utils.WxMchId = config.WxAppId, config.WxMerchantAcc
  68. utils.WxCertSeq, utils.WxCertPath = config.WxApiCertSeq, config.WxApiCertPath
  69. var err error
  70. utils.WxPrivateKey, err = wx.LoadPrivateKeyWithPath(config.WxApiCertPath)
  71. if err != nil {
  72. utils.Logger.Fatalf("load merchant private key error: %s\n", err)
  73. }
  74. opts := []core.ClientOption{
  75. option.WithWechatPayAutoAuthCipher(config.WxMerchantAcc, config.WxApiCertSeq, utils.WxPrivateKey, config.WxApiV3Key),
  76. }
  77. utils.WxPayCli = context.Background()
  78. client, err := core.NewClient(utils.WxPayCli, opts...)
  79. if err != nil {
  80. utils.Logger.Fatalf("new wechat pay client error: %s\n", err)
  81. }
  82. utils.WxPaySrv = native.NativeApiService{Client: client}
  83. err = downloader.MgrInstance().RegisterDownloaderWithPrivateKey(
  84. utils.WxPayCli, utils.WxPrivateKey, config.WxApiCertSeq, config.WxMerchantAcc, config.WxApiV3Key,
  85. )
  86. visitor := downloader.MgrInstance().GetCertificateVisitor(config.WxMerchantAcc)
  87. utils.WxCrtHdr, err = notify.NewRSANotifyHandler(config.WxApiV3Key, verifiers.NewSHA256WithRSAVerifier(visitor))
  88. if err != nil {
  89. utils.Logger.Fatalf("wxpay notice handler init error: %s\n", err)
  90. }
  91. }
  92. func initDatabase(config *utils.Config) {
  93. // init
  94. utils.Redis = redis.NewClient(&redis.Options{
  95. Addr: utils.Format("%s:%d", config.RedisHost, config.RedisPort),
  96. Password: config.RedisPass, DB: config.RedisDatabase,
  97. })
  98. db, err := sql.Open(
  99. "mysql",
  100. utils.Format(
  101. "%s:%s@tcp(%s:%d)/%s?loc=Local&charset=utf8&parseTime=true",
  102. config.MysqlUser, config.MysqlPass, config.MysqlHost, config.MysqlPort, config.MysqlDatabase,
  103. ),
  104. )
  105. if err != nil {
  106. utils.Logger.Fatalf("mysql init failed: %s\n", err)
  107. }
  108. err = db.Ping()
  109. if err != nil {
  110. utils.Logger.Fatalf("mysql connection failed: %s\n", err)
  111. }
  112. utils.Mysql = db
  113. // create
  114. toCreate := []createTableFn{
  115. tables.CreateAdvertiseTable, tables.CreateDeviceTable, tables.CreateManagerTable,
  116. tables.CreateParamsTable, tables.CreateVersionTable, tables.CreateWineTable,
  117. tables.CreateTradeTable, tables.CreateWorkerTable, tables.CreateUserTable,
  118. tables.CreateRefundTable, tables.CreateOperationTable, tables.CreateWarnTable,
  119. tables.CreateChangeTable,
  120. }
  121. for _, Fn := range toCreate {
  122. err = Fn()
  123. if err != nil {
  124. utils.Logger.Fatalf("create mysql tables failed: %s\n", err)
  125. }
  126. }
  127. }
  128. func createRouter(config *utils.Config) *gin.Engine {
  129. router := gin.New()
  130. err := router.SetTrustedProxies([]string{"127.0.0.1"})
  131. if err != nil {
  132. utils.Logger.Fatalf("can't trust '127.0.0.1', for: %s", err)
  133. }
  134. if err = utils.LoadRsaKeyPairs(config); err != nil {
  135. utils.Logger.Fatalf("can't generate private and public key.")
  136. }
  137. conf := cors.DefaultConfig()
  138. allow := append(conf.AllowHeaders, "Token", "Device")
  139. conf.AllowAllOrigins, conf.AllowHeaders = true, allow
  140. router.Use(loggerFormat(config.TimeFormat), gin.Recovery(), utils.ErrorHandler, cors.New(conf))
  141. router.NoRoute(lostHandler)
  142. router.Static("/static", "./static")
  143. return router
  144. }