215 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			215 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package api
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								import (
							 | 
						|||
| 
								 | 
							
									"context"
							 | 
						|||
| 
								 | 
							
									"fmt"
							 | 
						|||
| 
								 | 
							
									"go-admin/common/helper"
							 | 
						|||
| 
								 | 
							
									"go-admin/common/service/sysservice/sysstatuscode"
							 | 
						|||
| 
								 | 
							
									"go-admin/config/serverinit"
							 | 
						|||
| 
								 | 
							
									"go-admin/pkg/utility"
							 | 
						|||
| 
								 | 
							
									"log"
							 | 
						|||
| 
								 | 
							
									"net/http"
							 | 
						|||
| 
								 | 
							
									"os"
							 | 
						|||
| 
								 | 
							
									"os/signal"
							 | 
						|||
| 
								 | 
							
									"time"
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									"github.com/pkg/errors"
							 | 
						|||
| 
								 | 
							
									"gorm.io/gorm"
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									"github.com/gin-gonic/gin"
							 | 
						|||
| 
								 | 
							
									"github.com/go-admin-team/go-admin-core/config/source/file"
							 | 
						|||
| 
								 | 
							
									"github.com/go-admin-team/go-admin-core/sdk"
							 | 
						|||
| 
								 | 
							
									"github.com/go-admin-team/go-admin-core/sdk/api"
							 | 
						|||
| 
								 | 
							
									"github.com/go-admin-team/go-admin-core/sdk/config"
							 | 
						|||
| 
								 | 
							
									"github.com/go-admin-team/go-admin-core/sdk/pkg"
							 | 
						|||
| 
								 | 
							
									"github.com/spf13/cobra"
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									"go-admin/app/admin/models"
							 | 
						|||
| 
								 | 
							
									"go-admin/app/admin/router"
							 | 
						|||
| 
								 | 
							
									"go-admin/app/jobs"
							 | 
						|||
| 
								 | 
							
									"go-admin/common/database"
							 | 
						|||
| 
								 | 
							
									"go-admin/common/global"
							 | 
						|||
| 
								 | 
							
									common "go-admin/common/middleware"
							 | 
						|||
| 
								 | 
							
									"go-admin/common/middleware/handler"
							 | 
						|||
| 
								 | 
							
									"go-admin/common/storage"
							 | 
						|||
| 
								 | 
							
									ext "go-admin/config"
							 | 
						|||
| 
								 | 
							
								)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								var (
							 | 
						|||
| 
								 | 
							
									configYml string
							 | 
						|||
| 
								 | 
							
									apiCheck  bool
							 | 
						|||
| 
								 | 
							
									StartCmd  = &cobra.Command{
							 | 
						|||
| 
								 | 
							
										Use:          "server",
							 | 
						|||
| 
								 | 
							
										Short:        "Start API server",
							 | 
						|||
| 
								 | 
							
										Example:      "go-admin server -c config/settings.yml",
							 | 
						|||
| 
								 | 
							
										SilenceUsage: true,
							 | 
						|||
| 
								 | 
							
										PreRun: func(cmd *cobra.Command, args []string) {
							 | 
						|||
| 
								 | 
							
											setup()
							 | 
						|||
| 
								 | 
							
										},
							 | 
						|||
| 
								 | 
							
										RunE: func(cmd *cobra.Command, args []string) error {
							 | 
						|||
| 
								 | 
							
											return run()
							 | 
						|||
| 
								 | 
							
										},
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								var AppRouters = make([]func(), 0)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func init() {
							 | 
						|||
| 
								 | 
							
									StartCmd.PersistentFlags().StringVarP(&configYml, "config", "c", "config/settings.yml", "Start server with provided configuration file")
							 | 
						|||
| 
								 | 
							
									StartCmd.PersistentFlags().BoolVarP(&apiCheck, "api", "a", false, "Start server with check api data")
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									//注册路由 fixme 其他应用的路由,在本目录新建文件放在init方法
							 | 
						|||
| 
								 | 
							
									AppRouters = append(AppRouters, router.InitRouter)
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func setup() {
							 | 
						|||
| 
								 | 
							
									// 注入配置扩展项
							 | 
						|||
| 
								 | 
							
									config.ExtendConfig = &ext.ExtConfig
							 | 
						|||
| 
								 | 
							
									//1. 读取配置
							 | 
						|||
| 
								 | 
							
									config.Setup(
							 | 
						|||
| 
								 | 
							
										file.NewSource(file.WithPath(configYml)),
							 | 
						|||
| 
								 | 
							
										database.Setup,
							 | 
						|||
| 
								 | 
							
										storage.Setup,
							 | 
						|||
| 
								 | 
							
									)
							 | 
						|||
| 
								 | 
							
									//注册监听函数
							 | 
						|||
| 
								 | 
							
									queue := sdk.Runtime.GetMemoryQueue("")
							 | 
						|||
| 
								 | 
							
									queue.Register(global.LoginLog, models.SaveLoginLog)
							 | 
						|||
| 
								 | 
							
									queue.Register(global.OperateLog, models.SaveOperaLog)
							 | 
						|||
| 
								 | 
							
									queue.Register(global.ApiCheck, models.SaveSysApi)
							 | 
						|||
| 
								 | 
							
									go queue.Run()
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									usageStr := `starting api server...`
							 | 
						|||
| 
								 | 
							
									log.Println(usageStr)
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func run() error {
							 | 
						|||
| 
								 | 
							
									if config.ApplicationConfig.Mode == pkg.ModeProd.String() {
							 | 
						|||
| 
								 | 
							
										gin.SetMode(gin.ReleaseMode)
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									initRouter()
							 | 
						|||
| 
								 | 
							
									dbs := sdk.Runtime.GetDb()
							 | 
						|||
| 
								 | 
							
									var db *gorm.DB
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									for _, item := range dbs {
							 | 
						|||
| 
								 | 
							
										db = item
							 | 
						|||
| 
								 | 
							
										break
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									for _, f := range AppRouters {
							 | 
						|||
| 
								 | 
							
										f()
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									//初始化 status code 描述
							 | 
						|||
| 
								 | 
							
									sysstatuscode.InitStatusCodeLanguage(db)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									//初始redis 链接
							 | 
						|||
| 
								 | 
							
									helper.InitDefaultRedis(ext.ExtConfig.Redis.Addr, ext.ExtConfig.Redis.Password, ext.ExtConfig.Redis.Db)
							 | 
						|||
| 
								 | 
							
									helper.InitLockRedisConn(ext.ExtConfig.Redis.Addr, ext.ExtConfig.Redis.Password, utility.IntToString(ext.ExtConfig.Redis.Db))
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									//初始化雪花算法配置
							 | 
						|||
| 
								 | 
							
									err := helper.InitSnowflakeNode()
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										log.Printf("InitSnowflakeNode  error, %s \n", err.Error())
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									//业务需要配置-初始化
							 | 
						|||
| 
								 | 
							
									serverinit.BusinessInit(db)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									srv := &http.Server{
							 | 
						|||
| 
								 | 
							
										Addr:    fmt.Sprintf("%s:%d", config.ApplicationConfig.Host, config.ApplicationConfig.Port),
							 | 
						|||
| 
								 | 
							
										Handler: sdk.Runtime.GetEngine(),
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									go func() {
							 | 
						|||
| 
								 | 
							
										jobs.InitJob()
							 | 
						|||
| 
								 | 
							
										jobs.Setup(sdk.Runtime.GetDb())
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									}()
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									if apiCheck {
							 | 
						|||
| 
								 | 
							
										var routers = sdk.Runtime.GetRouter()
							 | 
						|||
| 
								 | 
							
										q := sdk.Runtime.GetMemoryQueue("")
							 | 
						|||
| 
								 | 
							
										mp := make(map[string]interface{})
							 | 
						|||
| 
								 | 
							
										mp["List"] = routers
							 | 
						|||
| 
								 | 
							
										message, err := sdk.Runtime.GetStreamMessage("", global.ApiCheck, mp)
							 | 
						|||
| 
								 | 
							
										if err != nil {
							 | 
						|||
| 
								 | 
							
											log.Printf("GetStreamMessage error, %s \n", err.Error())
							 | 
						|||
| 
								 | 
							
											//日志报错错误,不中断请求
							 | 
						|||
| 
								 | 
							
										} else {
							 | 
						|||
| 
								 | 
							
											err = q.Append(message)
							 | 
						|||
| 
								 | 
							
											if err != nil {
							 | 
						|||
| 
								 | 
							
												log.Printf("Append message error, %s \n", err.Error())
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									go func() {
							 | 
						|||
| 
								 | 
							
										// 服务连接
							 | 
						|||
| 
								 | 
							
										if config.SslConfig.Enable {
							 | 
						|||
| 
								 | 
							
											if err := srv.ListenAndServeTLS(config.SslConfig.Pem, config.SslConfig.KeyStr); err != nil && !errors.Is(err, http.ErrServerClosed) {
							 | 
						|||
| 
								 | 
							
												log.Fatal("listen: ", err)
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										} else {
							 | 
						|||
| 
								 | 
							
											if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
							 | 
						|||
| 
								 | 
							
												log.Fatal("listen: ", err)
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
									}()
							 | 
						|||
| 
								 | 
							
									fmt.Println(pkg.Red(string(global.LogoContent)))
							 | 
						|||
| 
								 | 
							
									tip()
							 | 
						|||
| 
								 | 
							
									fmt.Println(pkg.Green("Server run at:"))
							 | 
						|||
| 
								 | 
							
									fmt.Printf("-  Local:   %s://localhost:%d/ \r\n", "http", config.ApplicationConfig.Port)
							 | 
						|||
| 
								 | 
							
									fmt.Printf("-  Network: %s://%s:%d/ \r\n", "http", pkg.GetLocaHonst(), config.ApplicationConfig.Port)
							 | 
						|||
| 
								 | 
							
									fmt.Println(pkg.Green("Swagger run at:"))
							 | 
						|||
| 
								 | 
							
									fmt.Printf("-  Local:   http://localhost:%d/swagger/admin/index.html \r\n", config.ApplicationConfig.Port)
							 | 
						|||
| 
								 | 
							
									fmt.Printf("-  Network: %s://%s:%d/swagger/admin/index.html \r\n", "http", pkg.GetLocaHonst(), config.ApplicationConfig.Port)
							 | 
						|||
| 
								 | 
							
									fmt.Printf("%s Enter Control + C Shutdown Server \r\n", pkg.GetCurrentTimeStr())
							 | 
						|||
| 
								 | 
							
									// 等待中断信号以优雅地关闭服务器(设置 5 秒的超时时间)
							 | 
						|||
| 
								 | 
							
									quit := make(chan os.Signal, 1)
							 | 
						|||
| 
								 | 
							
									signal.Notify(quit, os.Interrupt)
							 | 
						|||
| 
								 | 
							
									<-quit
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
							 | 
						|||
| 
								 | 
							
									defer cancel()
							 | 
						|||
| 
								 | 
							
									fmt.Printf("%s Shutdown Server ... \r\n", pkg.GetCurrentTimeStr())
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									if err := srv.Shutdown(ctx); err != nil {
							 | 
						|||
| 
								 | 
							
										log.Fatal("Server Shutdown:", err)
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									log.Println("Server exiting")
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									return nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								//var Router runtime.Router
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func tip() {
							 | 
						|||
| 
								 | 
							
									usageStr := `欢迎使用 ` + pkg.Green(`go-admin `+global.Version) + ` 可以使用 ` + pkg.Red(`-h`) + ` 查看命令`
							 | 
						|||
| 
								 | 
							
									fmt.Printf("%s \n\n", usageStr)
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func initRouter() {
							 | 
						|||
| 
								 | 
							
									var r *gin.Engine
							 | 
						|||
| 
								 | 
							
									h := sdk.Runtime.GetEngine()
							 | 
						|||
| 
								 | 
							
									if h == nil {
							 | 
						|||
| 
								 | 
							
										h = gin.New()
							 | 
						|||
| 
								 | 
							
										sdk.Runtime.SetEngine(h)
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									switch h.(type) {
							 | 
						|||
| 
								 | 
							
									case *gin.Engine:
							 | 
						|||
| 
								 | 
							
										r = h.(*gin.Engine)
							 | 
						|||
| 
								 | 
							
									default:
							 | 
						|||
| 
								 | 
							
										log.Fatal("not support other engine")
							 | 
						|||
| 
								 | 
							
										//os.Exit(-1)
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									if config.SslConfig.Enable {
							 | 
						|||
| 
								 | 
							
										r.Use(handler.TlsHandler())
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									//r.Use(middleware.Metrics())
							 | 
						|||
| 
								 | 
							
									r.Use(common.Sentinel()).
							 | 
						|||
| 
								 | 
							
										Use(common.RequestId(pkg.TrafficKey)).
							 | 
						|||
| 
								 | 
							
										Use(api.SetRequestLogger)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									common.InitMiddleware(r)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								}
							 |