-
Notifications
You must be signed in to change notification settings - Fork 116
/
Copy pathmain.go
232 lines (205 loc) · 5.74 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
// -*- coding: utf-8 -*-
// @Time : 2022/4/2 12:46
// @Author : Nuanxinqing
// @Email : [email protected]
// @File : main.go
package main
import (
_const "QLPanelTools/const"
"QLPanelTools/server"
"QLPanelTools/server/settings"
"QLPanelTools/server/sqlite"
"QLPanelTools/tools/logger"
"QLPanelTools/tools/snowflake"
"QLPanelTools/tools/validator"
"context"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"path/filepath"
"strconv"
"syscall"
"time"
"github.com/gin-gonic/gin"
"github.com/spf13/viper"
"go.uber.org/zap"
"gopkg.in/yaml.v3"
)
func main() {
// 判断注册默认配置文件
bol := IFConfig("config/config.yaml")
if bol != true {
fmt.Println("自动生成配置文件失败, 请按照仓库的配置文件模板手动在config目录下创建 config.yaml 配置文件")
return
}
// 判断注册插件文件夹
bol = IFPlugin()
if bol != true {
fmt.Println("自动创建插件文件夹失败, 请手动在程序根目录创建 plugin 文件夹")
return
}
// 加载配置文件
if err := settings.Init(); err != nil {
fmt.Printf("viper init failed, err:%v\n", err)
return
}
// 初始化日志
if err := logger.Init(); err != nil {
fmt.Printf("Logger init failed, err:%v\n", err)
return
}
defer func(l *zap.Logger) {
_ = l.Sync()
}(zap.L())
zap.L().Debug("Logger success init ...")
// 初始化数据库
sqlite.Init()
sqlite.InitWebSettings()
zap.L().Debug("SQLite success init ...")
// 初始化翻译器
if err := validator.InitTrans("zh"); err != nil {
fmt.Printf("validator init failed, err:%v\n", err)
return
}
zap.L().Debug("Validator success init ...")
// 注册雪花ID算法
if err := snowflake.Init(); err != nil {
fmt.Printf("snowflake init failed, err:%v\n", err)
return
}
zap.L().Debug("Snowflake success init ...")
// 运行模式
if viper.GetString("app.mode") == "debug" {
gin.SetMode(gin.DebugMode)
} else {
gin.SetMode(gin.ReleaseMode)
}
// 注册路由
r := routes.Setup()
// 启动服务
srv := &http.Server{
Addr: fmt.Sprintf(":%d", viper.GetInt("app.port")),
Handler: r,
}
fmt.Println(` _______ _ _________ _______ _______ _ _______
( ___ )( \ \__ __/( ___ )( ___ )( \ ( ____ \
| ( ) || ( ) ( | ( ) || ( ) || ( | ( \/
| | | || | | | | | | || | | || | | (_____
| | | || | | | | | | || | | || | (_____ )
| | /\| || | | | | | | || | | || | ) |
| (_\ \ || (____/\| | | (___) || (___) || (____/Y\____) |
(____\/_)(_______/)_( (_______)(_______)(_______|_______)`)
fmt.Println(" ")
if viper.GetString("app.mode") == "debug" {
fmt.Println("运行模式:Debug模式")
} else {
fmt.Println("运行模式:Release模式")
}
fmt.Println("系统版本:" + _const.Version)
fmt.Println("登录地址:IP或域名:" + strconv.Itoa(viper.GetInt("app.port")) + "/#/login")
fmt.Println("注册地址:IP或域名:" + strconv.Itoa(viper.GetInt("app.port")) + "/#/register")
fmt.Println("后台地址:IP或域名:" + strconv.Itoa(viper.GetInt("app.port")) + "/#/admin")
fmt.Println("监听端口:" + strconv.Itoa(viper.GetInt("app.port")))
fmt.Println(" ")
zap.L().Info("监听端口:" + strconv.Itoa(viper.GetInt("app.port")))
// 启动
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("Listten: %s\n", err)
}
}()
// 等待终端信号来优雅关闭服务器,为关闭服务器设置5秒超时
quit := make(chan os.Signal, 1) // 创建一个接受信号的通道
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 此处不会阻塞
<-quit // 阻塞此处,当接受到上述两种信号时,才继续往下执行
zap.L().Info("Service ready to shut down")
// 创建五秒超时的Context
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 五秒内优雅关闭服务(将未处理完成的请求处理完再关闭服务),超过五秒就超时退出
if err := srv.Shutdown(ctx); err != nil {
zap.L().Fatal("Service timed out has been shut down:", zap.Error(err))
}
zap.L().Info("Service has been shut down")
}
type Config struct {
App App `yaml:"app"`
}
type App struct {
Mode string `yaml:"mode"`
Port int `yaml:"port"`
}
// IFConfig 判断并自动生成启动配置文件
func IFConfig(src string) bool {
// 检测是否存在配置文件
file, err := os.Stat(src)
if err != nil {
err = os.Mkdir("config", 0777)
if err != nil {
fmt.Printf("Create Config Dir Error: %s", err)
return false
}
err = os.Chmod("config", 0777)
if err != nil {
fmt.Printf("Chmod Config Dir Error: %s", err)
return false
}
_, err = os.Create(src)
if err != nil {
fmt.Printf("Create Config File Error: %s", err)
return false
}
// 需要生成默认
cfg := &Config{
App: App{
Mode: "",
Port: 15000,
},
}
data, err := yaml.Marshal(cfg)
if err != nil {
fmt.Printf("Marshal Config Error: %s", err)
return false
}
// 写入默认配置
err = os.WriteFile(src, data, 0777)
if err != nil {
fmt.Printf("WriteFile Config Error: %s", err)
return false
}
return true
}
if file.IsDir() {
return false
} else {
return true
}
}
// IFPlugin 判断并自动创建插件文件夹
func IFPlugin() bool {
ExecPath, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
fmt.Println(err)
return false
}
_, err = os.Stat(ExecPath + "/plugin")
if err != nil {
err = os.Mkdir("plugin", 0777)
if err != nil {
if err.Error() == "mkdir plugin: file exists" {
return true
} else {
fmt.Println(err)
return false
}
}
_, err2 := os.Stat(ExecPath + "/plugin")
if err2 != nil {
fmt.Println(err)
return false
}
}
return true
}