Skip to content

Commit afe3b88

Browse files
author
bajins
committed
refactor(app): 重构应用程序的核心逻辑和架构
- 重新设计了路由处理和上下文管理,提高了代码的可维护性和可扩展性 - 优化了系统信息获取、文件上传下载等核心功能的实现 - 改进了错误处理和日志记录机制,增强了系统的稳定性和可追踪性 - 重构了爬虫相关的逻辑,提高了数据获取的效率和准确性 - 优化了模板和静态文件的处理,提升了用户体验
1 parent a17f8ef commit afe3b88

File tree

10 files changed

+533
-135
lines changed

10 files changed

+533
-135
lines changed

app.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,11 @@ func Port() (port string) {
151151
// 配置gin(路由、中间件)并监听运行
152152
func run() {
153153

154-
router := gin.Default()
154+
router := NewEngine()
155155

156-
// 将全局中间件附加到路由器
156+
// 将全局中间件附加到路由器,使用中间件处理通用、横切性的关注点
157+
// Gin 自带的 panic 恢复中间件
158+
router.Use(gin.Recovery())
157159
router.Use(FilterNoCache)
158160
//router.Use(Cors())
159161
//router.Use(Authorize())

controller.go

Lines changed: 89 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ import (
1414
)
1515

1616
// WebRoot 首页
17-
func WebRoot(c *gin.Context) {
17+
func WebRoot(ctx *Context) {
1818
// 301重定向
19-
//c.Redirect(http.StatusMovedPermanently, "/static")
19+
//ctx.C.Redirect(http.StatusMovedPermanently, "/static")
2020
// 返回HTML页面
21-
//c.HTML(http.StatusOK, "index.html", nil)
22-
c.HTML(http.StatusOK, "index.html", gin.H{})
21+
//ctx.C.HTML(http.StatusOK, "index.html", nil)
22+
ctx.C.HTML(http.StatusOK, "index.html", gin.H{})
2323
}
2424

2525
// SystemInfo 获取系统信息
26-
func SystemInfo(c *gin.Context) {
26+
func SystemInfo(ctx *Context) {
2727
data := make(map[string]interface{}, 0)
2828
data["Version"] = utils.ToUpper(runtime.Version())
2929
data["cpu"] = runtime.NumCPU()
@@ -41,28 +41,39 @@ func SystemInfo(c *gin.Context) {
4141
// 获取当前存在的go协程数
4242
data["NumGoroutine"] = runtime.NumGoroutine()
4343

44-
SuccessJSON(c, "获取系统信息成功", data)
44+
ctx.SuccessJSON("获取系统信息成功", data)
45+
}
46+
47+
// GetKeyInfo 定义了GetKey的 JSON 结构体
48+
type GetKeyInfo struct {
49+
Company string `json:"company" binding:"required"`
50+
App string `json:"app" binding:"required"`
51+
Version string `json:"version" binding:"required"`
4552
}
4653

4754
// GetKey 获取key
48-
func GetKey(c *gin.Context) {
55+
func GetKey(ctx *Context) {
4956
// GET 获取参数内容,没有则返回空字符串
50-
//company := c.Query("company")
57+
//company := ctx.C.Query("company")
5158
// POST 获取的所有参数内容的类型都是 string
52-
company := c.PostForm("company")
59+
company := ctx.C.PostForm("company")
5360

61+
/*var getKeyInfo GetKeyInfo
62+
if !ctx.C.BindAndValidate(&getKeyInfo) {
63+
return
64+
}*/
5465
if utils.IsStringEmpty(company) {
55-
ErrorJSON(c, 300, "请选择公司")
66+
ctx.ErrorJSON(300, "请选择公司")
5667
return
5768
}
58-
app := c.PostForm("app")
69+
app := ctx.C.PostForm("app")
5970
if utils.IsStringEmpty(app) {
60-
ErrorJSON(c, 300, "请选择产品")
71+
ctx.ErrorJSON(300, "请选择产品")
6172
return
6273
}
63-
version := c.PostForm("version")
74+
version := ctx.C.PostForm("version")
6475
if utils.IsStringEmpty(version) {
65-
ErrorJSON(c, 300, "请选择版本")
76+
ctx.ErrorJSON(300, "请选择版本")
6677
return
6778
}
6879
dir := TempDirPath + string(filepath.Separator)
@@ -85,38 +96,38 @@ func GetKey(c *gin.Context) {
8596
ExecuteScriptError(err)
8697
if err != nil {
8798
log.Println(err)
88-
ErrorJSON(c, http.StatusInternalServerError, "系统错误!")
99+
ctx.ErrorJSON(http.StatusInternalServerError, "系统错误!")
89100
return
90101
}
91-
SuccessJSON(c, "获取key成功", map[string]string{"key": out})
102+
ctx.SuccessJSON("获取key成功", map[string]string{"key": out})
92103

93104
} else if company == "mobatek" {
94105
curr, err := utils.OsPath()
95106
if err != nil {
96-
SystemErrorJSON(c, http.StatusInternalServerError, "系统错误!")
107+
ctx.SystemErrorJSON(ERROR, "系统错误!")
97108
return
98109
}
99110
_, err = utils.ExecutePython(dir+"moba_xterm_Keygen.py", curr, version)
100111
ExecuteScriptError(err)
101112
if err != nil {
102-
SystemErrorJSON(c, http.StatusInternalServerError, "系统错误!")
113+
ctx.SystemErrorJSON(ERROR, "系统错误!")
103114
return
104115
}
105-
c.Header("Content-Type", "application/octet-stream")
106-
c.Header("Content-Disposition", "attachment; filename=\"Custom.mxtpro\"")
107-
//c.Writer.Header().Set("Content-Type", "application/octet-stream")
108-
//c.Writer.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", "Custom.mxtpro"))
116+
ctx.C.Header("Content-Type", "application/octet-stream")
117+
ctx.C.Header("Content-Disposition", "attachment; filename=\"Custom.mxtpro\"")
118+
//ctx.C.Writer.Header().Set("Content-Type", "application/octet-stream")
119+
//ctx.C.Writer.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", "Custom.mxtpro"))
109120

110-
c.FileAttachment(filepath.Join(curr, "Custom.mxtpro"), "Custom.mxtpro")
121+
ctx.C.FileAttachment(filepath.Join(curr, "Custom.mxtpro"), "Custom.mxtpro")
111122

112123
} else if company == "torchsoft" {
113124
out, err := utils.ExecutePython(dir+"reg_workshop_keygen.py", version)
114125
ExecuteScriptError(err)
115126
if err != nil {
116-
ErrorJSON(c, http.StatusInternalServerError, "系统错误!")
127+
ctx.ErrorJSON(http.StatusInternalServerError, "系统错误!")
117128
return
118129
}
119-
SuccessJSON(c, "获取key成功", map[string]string{"key": out})
130+
ctx.SuccessJSON("获取key成功", map[string]string{"key": out})
120131
}
121132
}
122133

@@ -133,9 +144,9 @@ func ExecuteScriptError(err error) {
133144
}
134145

135146
// Upload 文件上传请求
136-
func Upload(c *gin.Context) {
147+
func Upload(ctx *Context) {
137148
// 拿到上传的文件的信息
138-
file, header, err := c.Request.FormFile("upload")
149+
file, header, err := ctx.C.Request.FormFile("upload")
139150
filename := header.Filename
140151
log.Println(header.Filename)
141152
out, err := os.Create("./tmp/" + filename + ".png")
@@ -156,81 +167,81 @@ func Upload(c *gin.Context) {
156167
}
157168

158169
// Download 文件下载请求
159-
func Download(c *gin.Context) {
160-
response, err := http.Get(c.Request.Host + "/static/public/favicon.ico")
170+
func Download(ctx *Context) {
171+
response, err := http.Get(ctx.C.Request.Host + "/static/public/favicon.ico")
161172
if err != nil || response.StatusCode != http.StatusOK {
162-
c.Status(http.StatusServiceUnavailable)
173+
ctx.C.Status(http.StatusServiceUnavailable)
163174
return
164175
}
165176

166177
extraHeaders := map[string]string{
167178
"Content-Disposition": `attachment; filename="favicon.ico"`,
168179
}
169180

170-
c.DataFromReader(http.StatusOK, response.ContentLength, response.Header.Get("Content-Type"), response.Body, extraHeaders)
181+
ctx.C.DataFromReader(http.StatusOK, response.ContentLength, response.Header.Get("Content-Type"), response.Body, extraHeaders)
171182
}
172183

173184
// GetNetSarangDownloadUrl 获取NetSarang下载url
174-
func GetNetSarangDownloadUrl(c *gin.Context) {
185+
func GetNetSarangDownloadUrl(ctx *Context) {
175186
// POST 获取的所有参数内容的类型都是 string
176-
app := c.PostForm("app")
187+
app := ctx.C.PostForm("app")
177188
if utils.IsStringEmpty(app) {
178-
ErrorJSON(c, 300, "请选择产品")
189+
ctx.ErrorJSON(300, "请选择产品")
179190
return
180191
}
181-
version := c.PostForm("version")
192+
version := ctx.C.PostForm("version")
182193
if utils.IsStringEmpty(version) {
183-
ErrorJSON(c, 300, "请选择版本")
194+
ctx.ErrorJSON(300, "请选择版本")
184195
return
185196
}
186197
url, err := reptile.NetsarangGetInfo(app)
187198
if err != nil {
188-
ErrorJSON(c, http.StatusInternalServerError, "系统错误!")
199+
ctx.ErrorJSON(http.StatusInternalServerError, "系统错误!")
189200
return
190201
}
191-
SuccessJSON(c, "获取"+app+"成功", map[string]string{"url": url})
202+
ctx.SuccessJSON("获取"+app+"成功", map[string]string{"url": url})
192203
}
193204

194205
// NginxFormatIndex NGINX格式化代码页面
195-
func NginxFormatIndex(c *gin.Context) {
206+
func NginxFormatIndex(ctx *Context) {
196207
// 301重定向
197-
//c.Redirect(http.StatusMovedPermanently, "/static")
208+
//ctx.C.Redirect(http.StatusMovedPermanently, "/static")
198209
// 返回HTML页面
199-
//c.HTML(http.StatusOK, "index.html", nil)
200-
c.HTML(http.StatusOK, "nginx-format.html", gin.H{})
210+
//ctx.C.HTML(http.StatusOK, "index.html", nil)
211+
ctx.C.HTML(http.StatusOK, "nginx-format.html", gin.H{})
201212
}
202213

203214
// NginxFormatPython 格式化nginx配置代码
204-
func NginxFormatPython(c *gin.Context) {
215+
func NginxFormatPython(ctx *Context) {
205216
// GET 获取参数内容,没有则返回空字符串
206-
//code := c.Query("code")
217+
//code := ctx.C.Query("code")
207218
// POST 获取的所有参数内容的类型都是 string
208-
code := c.PostForm("code")
219+
code := ctx.C.PostForm("code")
209220

210221
if utils.IsStringEmpty(code) {
211-
ErrorJSON(c, 300, "请输入配置代码")
222+
ctx.ErrorJSON(300, "请输入配置代码")
212223
return
213224
}
214225
out, err := utils.ExecutePython(TempDirPath+string(filepath.Separator)+"nginxfmt.py", code)
215226
if err != nil {
216227
log.Println(err)
217-
ErrorJSON(c, http.StatusInternalServerError, "系统错误!")
228+
ctx.ErrorJSON(http.StatusInternalServerError, "系统错误!")
218229
return
219230
}
220231
res := make(map[string]string)
221232
res["contents"] = out
222-
SuccessJSON(c, "请求成功", res)
233+
ctx.SuccessJSON("请求成功", res)
223234
}
224235

225236
// GetNavicatDownloadUrl 获取navicat下载地址
226-
func GetNavicatDownloadUrl(c *gin.Context) {
227-
location, isExist := c.GetQuery("location")
237+
func GetNavicatDownloadUrl(ctx *Context) {
238+
location, isExist := ctx.C.GetQuery("location")
228239
if location == "" || !isExist {
229-
location = c.DefaultPostForm("location", "1")
240+
location = ctx.C.DefaultPostForm("location", "1")
230241
}
231-
product, isExist := c.GetQuery("product")
242+
product, isExist := ctx.C.GetQuery("product")
232243
if product == "" || !isExist {
233-
product = c.DefaultPostForm("product", "navicat_premium_cs_x64.exe")
244+
product = ctx.C.DefaultPostForm("product", "navicat_premium_cs_x64.exe")
234245
}
235246

236247
// POST 获取的所有参数内容的类型都是 string
@@ -244,19 +255,38 @@ func GetNavicatDownloadUrl(c *gin.Context) {
244255
result, err := utils.HttpReadBodyJsonMap(http.MethodPost, url, utils.ContentTypeAXWFU, params, nil)
245256

246257
if result == nil || err != nil {
247-
ErrorJSON(c, http.StatusInternalServerError, "系统错误!")
258+
ctx.ErrorJSON(http.StatusInternalServerError, "系统错误!")
248259
return
249260
}
250-
SuccessJSON(c, "获取下载地址成功", map[string]string{"url": result["download_link"].(string)})
261+
ctx.SuccessJSON("获取下载地址成功", map[string]string{"url": result["download_link"].(string)})
251262
}
252263

253-
func GetSvp(c *gin.Context) {
264+
func GetSvp(ctx *Context) {
254265
defer func() { // 捕获panic
255266
if r := recover(); r != nil {
256267
log.Println("Recovered from panic:", r)
257-
c.String(http.StatusOK, r.(string))
268+
ctx.C.String(http.StatusOK, r.(string))
258269
}
259270
}()
260-
log.Println("GetSvp Header:", c.Request.Header)
261-
c.String(http.StatusOK, reptile.GetSvpAll())
271+
//log.Println("GetSvp Header:", ctx.C.Request.Header)
272+
ctx.C.String(http.StatusOK, reptile.GetSvpAllHandler(getClientIP(ctx.C.Request)))
273+
}
274+
275+
// getClientIP 尝试从请求中获取真实的客户端IP
276+
func getClientIP(r *http.Request) string {
277+
// 检查 X-Forwarded-For 头,这是代理服务器常用的方式
278+
ip := r.Header.Get("X-Forwarded-For")
279+
if ip != "" {
280+
// X-Forwarded-For 可能包含多个IP,取第一个
281+
return strings.Split(ip, ",")[0]
282+
}
283+
// 检查 X-Real-IP 头
284+
ip = r.Header.Get("X-Real-IP")
285+
if ip != "" {
286+
return ip
287+
}
288+
// 如果都没有,则使用 RemoteAddr
289+
// RemoteAddr 格式为 "IP:port",我们需要去掉端口
290+
ip, _, _ = strings.Cut(r.RemoteAddr, ":")
291+
return ip
262292
}

main.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,33 @@ import (
66
"os"
77
"os/signal"
88
"syscall"
9-
"time"
10-
"tool-gin/reptile"
11-
"tool-gin/utils"
129
)
1310

1411
// 初始化函数
1512
func init() {
16-
// 设置日志初始化参数
13+
// --- 设置日志初始化参数 开启文件名和行号显示 ---
14+
// 使用 | (位或运算符) 来组合多个标志
15+
// log.LstdFlags 包含了日期和时间 (log.Ldate | log.Ltime)
1716
// log.Lshortfile 简要文件路径,log.Llongfile 完整文件路径
1817
log.SetFlags(log.Lshortfile | log.LstdFlags)
19-
// 设置项目为发布环境
20-
//gin.SetMode(gin.ReleaseMode)
2118

22-
go utils.SchedulerFixedTicker(reptile.NetsarangDownloadAll, time.Hour*24)
19+
// github.com/sirupsen/logrus
20+
// 报告调用者的信息
21+
//log.SetReportCaller(true)
22+
// 自定义格式化器
23+
/*log.SetFormatter(&log.TextFormatter{
24+
FullTimestamp: true,
25+
// 让文件和行号信息更突出
26+
CallerPrettyfier: func(f *log.Frame) (string, string) {
27+
return "",
28+
// f.Function, // 这里可以返回函数名
29+
// 格式化为 file:line
30+
fmt.Sprintf(" <%s:%d>", f.File, f.Line)
31+
},
32+
})*/
2333

24-
go utils.SchedulerFixedTicker(reptile.GetSvpDP, time.Minute*20)
34+
// 设置项目为发布环境
35+
//gin.SetMode(gin.ReleaseMode)
2536
}
2637

2738
// 运行主体函数

reptile/netsarang.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,23 @@ func init() {
3838
if mailtmMerr != nil {
3939
log.Println(mailtmMerr)
4040
}
41+
42+
go utils.SchedulerFixedTicker(func() {
43+
for _, app := range netsarangProduct {
44+
_, err := NetsarangGetInfo(app)
45+
if err != nil {
46+
log.Println(err)
47+
}
48+
}
49+
log.Println(netsarangMap)
50+
}, time.Hour*24)
4151
}
4252

4353
type NetsarangInfo struct {
4454
Time time.Time
4555
Url string
4656
}
4757

48-
// NetsarangDownloadAll 获取所有链接信息
49-
func NetsarangDownloadAll() {
50-
for _, app := range netsarangProduct {
51-
_, err := NetsarangGetInfo(app)
52-
if err != nil {
53-
log.Println(err)
54-
}
55-
}
56-
log.Println(netsarangMap)
57-
}
58-
5958
// NetsarangGetInfo 获取链接信息
6059
func NetsarangGetInfo(product string) (string, error) {
6160
if product == "" || len(product) == 0 {

0 commit comments

Comments
 (0)