配置全自动docker版本部署
This commit is contained in:
@@ -20,11 +20,10 @@ func SetupRouter() *gin.Engine {
|
||||
r := gin.Default()
|
||||
|
||||
// 从 embed 读取前端静态文件
|
||||
// 注意:embed.FS 不支持直接作为 http.FileSystem 传参,需要用 http.FS 转换
|
||||
staticSubFS, _ := fs.Sub(staticFS, "static")
|
||||
r.StaticFS("/static", http.FS(staticSubFS))
|
||||
|
||||
// 根路由:直接返回 index.html
|
||||
// 根路由
|
||||
r.GET("/", func(c *gin.Context) {
|
||||
content, err := staticFS.ReadFile("static/index.html")
|
||||
if err != nil {
|
||||
@@ -39,40 +38,32 @@ func SetupRouter() *gin.Engine {
|
||||
c.String(200, "frpc-console 后端已启动 🎉")
|
||||
})
|
||||
|
||||
// API 路由
|
||||
api := r.Group("/api")
|
||||
{
|
||||
// 登录(无需鉴权)
|
||||
api.GET("/check/users", checkUsersHandler)
|
||||
api.POST("/register", registerHandler)
|
||||
api.POST("/login", loginHandler)
|
||||
|
||||
// 需要鉴权的路由
|
||||
auth := api.Group("/")
|
||||
auth.Use(AuthMiddleware())
|
||||
{
|
||||
// 全局配置
|
||||
auth.GET("/config", getConfigHandler)
|
||||
auth.PUT("/config", updateConfigHandler)
|
||||
|
||||
// 隧道管理
|
||||
auth.GET("/proxies", getProxiesHandler)
|
||||
auth.GET("/proxy/:id", getProxyHandler)
|
||||
auth.POST("/proxy", createProxyHandler)
|
||||
auth.PUT("/proxy/:id", updateProxyHandler)
|
||||
auth.DELETE("/proxy/:id", deleteProxyHandler)
|
||||
|
||||
// frpc 控制
|
||||
auth.POST("/frpc/reload", reloadFrpcHandler)
|
||||
auth.POST("/frpc/start", startFrpcHandler)
|
||||
auth.POST("/frpc/stop", stopFrpcHandler)
|
||||
auth.GET("/frpc/status", getFrpcStatusHandler)
|
||||
|
||||
// 导入/导出 TOML
|
||||
auth.POST("/import/toml", importTomlHandler)
|
||||
auth.GET("/export/toml", ExportTomlHandler)
|
||||
|
||||
// 修改密码
|
||||
auth.PUT("/user/password", changePasswordHandler)
|
||||
}
|
||||
}
|
||||
@@ -80,7 +71,8 @@ func SetupRouter() *gin.Engine {
|
||||
return r
|
||||
}
|
||||
|
||||
// ========== 检查是否有用户 ==========
|
||||
// ========== 所有 Handler ==========
|
||||
|
||||
func checkUsersHandler(c *gin.Context) {
|
||||
count, err := CountUsers()
|
||||
if err != nil {
|
||||
@@ -89,14 +81,10 @@ func checkUsersHandler(c *gin.Context) {
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"data": gin.H{
|
||||
"hasUsers": count > 0,
|
||||
"count": count,
|
||||
},
|
||||
"data": gin.H{"hasUsers": count > 0, "count": count},
|
||||
})
|
||||
}
|
||||
|
||||
// ========== 注册(仅首次启动可用) ==========
|
||||
func registerHandler(c *gin.Context) {
|
||||
var req struct {
|
||||
Username string `json:"username"`
|
||||
@@ -123,10 +111,7 @@ func registerHandler(c *gin.Context) {
|
||||
}
|
||||
|
||||
if !ValidatePassword(req.Password) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 1,
|
||||
"msg": "密码至少 8 位,需包含大小写字母、数字和特殊字符",
|
||||
})
|
||||
c.JSON(http.StatusBadRequest, gin.H{"code": 1, "msg": "密码至少 8 位,需包含大小写字母、数字和特殊字符"})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -154,7 +139,6 @@ func registerHandler(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// ========== 登录 ==========
|
||||
func loginHandler(c *gin.Context) {
|
||||
var req struct {
|
||||
Username string `json:"username"`
|
||||
@@ -189,7 +173,6 @@ func loginHandler(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// ========== 修改密码 ==========
|
||||
func changePasswordHandler(c *gin.Context) {
|
||||
var req struct {
|
||||
OldPassword string `json:"oldPassword"`
|
||||
@@ -218,10 +201,7 @@ func changePasswordHandler(c *gin.Context) {
|
||||
}
|
||||
|
||||
if !ValidatePassword(req.NewPassword) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 1,
|
||||
"msg": "密码至少 8 位,需包含大小写字母、数字和特殊字符",
|
||||
})
|
||||
c.JSON(http.StatusBadRequest, gin.H{"code": 1, "msg": "密码至少 8 位,需包含大小写字母、数字和特殊字符"})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -239,7 +219,6 @@ func changePasswordHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "密码修改成功"})
|
||||
}
|
||||
|
||||
// ========== 全局配置 ==========
|
||||
func getConfigHandler(c *gin.Context) {
|
||||
cfg, err := GetGlobalConfig()
|
||||
if err != nil {
|
||||
@@ -275,7 +254,6 @@ func updateConfigHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "配置更新成功"})
|
||||
}
|
||||
|
||||
// ========== 隧道管理 ==========
|
||||
func getProxiesHandler(c *gin.Context) {
|
||||
proxies, err := GetProxies()
|
||||
if err != nil {
|
||||
@@ -366,7 +344,6 @@ func deleteProxyHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "隧道删除成功"})
|
||||
}
|
||||
|
||||
// ========== frpc 控制 ==========
|
||||
func reloadFrpcHandler(c *gin.Context) {
|
||||
if err := GenerateFrpcConfig(); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"code": 2, "msg": "生成配置失败: " + err.Error()})
|
||||
@@ -404,7 +381,6 @@ func getFrpcStatusHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "data": gin.H{"running": running}})
|
||||
}
|
||||
|
||||
// ========== 导入 TOML ==========
|
||||
func importTomlHandler(c *gin.Context) {
|
||||
file, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
@@ -455,6 +431,7 @@ func importTomlHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"code": 2, "msg": "生成配置失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := ReloadFrpc(); err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
@@ -469,7 +446,6 @@ func importTomlHandler(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// ========== 导出 TOML ==========
|
||||
func ExportTomlHandler(c *gin.Context) {
|
||||
cfg, err := GetGlobalConfig()
|
||||
if err != nil {
|
||||
@@ -515,7 +491,6 @@ func ExportTomlHandler(c *gin.Context) {
|
||||
c.String(http.StatusOK, buf.String())
|
||||
}
|
||||
|
||||
// ========== 辅助 ==========
|
||||
func generateAndReload() error {
|
||||
if err := GenerateFrpcConfig(); err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user