This commit is contained in:
wjqserver 2025-07-01 10:32:26 +08:00
parent d4e7f83131
commit cfaf82def3
12 changed files with 232 additions and 10 deletions

41
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,41 @@
---
name: Bug report
about: 报告问题与漏洞
title: "[BUG]"
labels: bug
assignees: ''
---
### 问题描述
请简要描述发现的问题是什么,以及如何重现。
### 复现步骤
1. 打开...
2. 点击...
3. 观察到...
### 预期行为
请描述在正常情况下应该发生什么。
### 实际行为
请描述实际发生了什么。
### 截图
如果适用,请添加截图以帮助解释您的问题。
### 环境信息
- 发行版: [例如 Debian12, Alpine-Edge ]
- 部署方式: [可执行文件/Docker ]
- CaddyDash版本: [例如 1.0.0]
- Caddy版本: [例如 2.10.0-v25.07.01]
### 附加信息
请提供任何其他可能有助于我们解决问题的信息。

41
.github/ISSUE_TEMPLATE/bug_report_en.md vendored Normal file
View file

@ -0,0 +1,41 @@
---
name: Bug report (English)
about: Report issues and bugs
title: "[BUG]"
labels: bug
assignees: ''
---
### Problem Description
Please briefly describe what the issue is and how to reproduce it.
### Steps to Reproduce
1. Open...
2. Click...
3. Observe...
### Expected Behavior
Please describe what should happen under normal circumstances.
### Actual Behavior
Please describe what actually happened.
### Screenshots
If applicable, please add screenshots to help explain your problem.
### Environment Information
- Distribution: [e.g., Debian12, Alpine-Edge ]
- Deployment Method: [Executable/Docker ]
- CaddyDash Version: [e.g., 1.0.0]
- Caddy Version: [e.g., 2.10.0-v25.07.01]
### Additional Information
Please provide any other information that might help us resolve the issue.

View file

@ -0,0 +1,20 @@
---
name: Features request
about: 提出新功能建议
title: "[Features]"
labels: 改进
assignees: ''
---
### 功能描述
请简要描述您希望增加的功能。
### 功能原因
请说明您为什么需要这个功能。
### 功能实现
请详细描述您期望的功能实现。

View file

@ -0,0 +1,20 @@
---
name: Feature request (English)
about: Suggest new features
title: "[Feature]"
labels: enhancement
assignees: ''
---
### Feature Description
Please briefly describe the feature you would like to add.
### Reason for Feature
Please explain why you need this feature.
### Feature Implementation
Please describe in detail how you expect this feature to be implemented.

View file

@ -1 +1,61 @@
# caddydash
# CaddyDash - 现代化 Caddy Web 管理面板
CaddyDash 是一个现代化、用户友好的 Web 界面,用于管理和配置您的 Caddy 服务器。它提供了一个直观的图形界面,让您能够轻松地管理站点配置、调整全局设置,并监控 Caddy 实例的状态。
## ✨ 特性
* **直观的站点配置**: 通过表单轻松创建、编辑和删除站点配置,支持反向代理和文件服务模式。
* **全局 Caddyfile 管理**: 直接在 Web 界面中修改和保存 Caddy 的全局配置文件。
* **Caddy 实例控制**: 一键启动、停止和重载 Caddy 服务。
* **多语言支持**: 内置国际化 (i18n) 功能,支持中英文切换,未来可扩展更多语言。
* **响应式设计**: 界面适配桌面和移动设备,提供一致的用户体验。
* **主题切换**: 支持明亮与暗色主题,满足不同用户偏好。
* **用户认证**: 提供安全的登录和初始化流程,保障面板访问安全。
* **预设管理**: 支持从预设填充常用的请求头配置,提高配置效率。
## 🚀 技术栈
**前端:**
* **纯原生 HTML5/CSS3/JavaScript (ESM)**: 完全基于浏览器原生技术构建,响应式设计, 移动端友好
**后端:**
* **Go 语言**: 高性能、并发友好的后端服务
* **Touka 框架**: 基于 Go 构建的 HTTP 框架,用于处理 Web 请求
* **SQLite**: 轻量级嵌入式数据库,用于存储用户和配置数据
* **CaddyServer**: 作为核心组件
## 💡 架构概览
CaddyDash 前端采用**多页面应用 (MPA)** 架构,每个主要功能模块都对应一个独立的 HTML 页面,并由其专属的 JavaScript 入口文件驱动。
* **高度模块化**: 所有 JavaScript 代码都以 **ESM (ECMAScript Modules)** 形式组织,通过 `import/export` 机制实现代码复用和职责分离。
* **共享组件**: `js/common.js``js/locale.js``js/notifications.js``js/ui.js``js/api.js` 等模块封装了跨页面共享的功能如页面初始化、国际化、通知、UI操作和后端 API 调用。
* **独立页面逻辑**: `js/app.js` (站点配置), `js/global.js` (全局配置), `js/settings.js` (面板设置), `js/login.js` (登录), `js/init.js` (初始化) 分别处理各自页面的特定业务逻辑。
## 🌐 国际化 (i18n)
CaddyDash 前端支持多语言显示。
* **语言包**: 翻译文本存储在 `locales/en.json` (英文) 和 `locales/zh-CN.json` (简体中文) 文件中。
* **动态翻译**: `js/locale.js` 模块负责加载正确的语言包,并动态地将 HTML 元素中带有 `data-i18n` (内容)、`data-i18n-title` (标题属性) 和 `data-i18n-placeholder` (输入框提示) 的文本进行翻译。
* **切换语言**: 在登录页、初始化页或面板设置页,您可以通过界面上的语言切换选项来改变语言。
**如何添加新的翻译条目:**
1. 在 `locales/en.json``locales/zh-CN.json` 中添加新的键值对。请遵循现有的点分隔命名约定(例如 `pages.feature.new_text`)。
2. 在 HTML 中使用 `data-i18n="your.new.key"``data-i18n-title="your.new.key"``data-i18n-placeholder="your.new.key"` 属性。
3. 在 JavaScript 代码中,使用 `t('your.new.key', { replacements })` 函数来获取翻译文本。
## 🤝 贡献
我们欢迎并鼓励任何形式的贡献如果您有任何功能建议、bug 报告或代码改进,请随时通过 Issues 或 Pull Requests 提交。
## 📜 许可证
Copyright © 2025 WJQSERVER
本项目 CaddyDash 在 **Mozilla Public License 2.0 (MPL 2.0)** 许可证下授权

View file

@ -9,7 +9,7 @@ import (
"github.com/infinite-iroha/touka"
)
func ApiGroup(v0 touka.IRouter, cdb *db.ConfigDB, cfg *config.Config) {
func ApiGroup(v0 touka.IRouter, cdb *db.ConfigDB, cfg *config.Config, version string) {
api := v0.Group("/api")
api.GET("/config/filenames", func(c *touka.Context) {
filenames, err := cdb.GetFileNames()
@ -20,6 +20,8 @@ func ApiGroup(v0 touka.IRouter, cdb *db.ConfigDB, cfg *config.Config) {
c.JSON(200, filenames)
})
api.GET("/info", infoHandle(version))
// 配置参数相关
cfgr := api.Group("/config")
{

View file

@ -20,6 +20,7 @@ var (
"/v0/api/auth/init": {},
"/init.html": {},
"/favicon.ico": {},
"/v0/api/info": {},
}
prefixMatchPaths = []string{ // 保持前缀匹配,因为数量少
"/js/",
@ -38,17 +39,18 @@ var (
)
func isPassPath(requestPath string) bool {
// 精确匹配
if _, ok := exactMatchPaths[requestPath]; ok {
return true
}
// 前缀匹配
for _, prefix := range prefixMatchPaths {
if strings.HasPrefix(requestPath, prefix) {
return true
}
}
// 精确匹配
if _, ok := exactMatchPaths[requestPath]; ok {
return true
}
return false
}

33
api/info.go Normal file
View file

@ -0,0 +1,33 @@
package api
import (
"runtime/debug"
"github.com/infinite-iroha/touka"
)
type InfoApiStruct struct {
Version string `json:"version"`
License string `json:"license"`
Author []string `json:"author"`
BuildVersion string `json:"build_version"`
GoVersion string `json:"go_version"`
}
func infoHandle(version string) touka.HandlerFunc {
return func(c *touka.Context) {
buildinfo, ok := debug.ReadBuildInfo()
if !ok {
c.JSON(500, touka.H{"error": "no build info"})
return
}
c.JSON(200, InfoApiStruct{
Version: version,
License: "Mozilla Public License 2.0",
//Author: "WJQSERVER",
Author: []string{"WJQSERVER"},
BuildVersion: buildinfo.Main.Version,
GoVersion: buildinfo.GoVersion,
})
}
}

4
go.mod
View file

@ -7,7 +7,7 @@ require (
github.com/fenthope/compress v0.0.3
github.com/fenthope/record v0.0.3
github.com/fenthope/sessions v0.0.1
github.com/infinite-iroha/touka v0.2.2
github.com/infinite-iroha/touka v0.2.8
github.com/klauspost/compress v1.18.0
golang.org/x/crypto v0.39.0
modernc.org/sqlite v1.38.0
@ -34,4 +34,4 @@ require (
modernc.org/memory v1.11.0 // indirect
)
replace github.com/infinite-iroha/touka => /data/github/WJQSERVER/touka
//replace github.com/infinite-iroha/touka => /data/github/WJQSERVER/touka

2
go.sum
View file

@ -28,6 +28,8 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
github.com/infinite-iroha/touka v0.2.8 h1:PH4oR0fUjNr6t+Q3xkpqK+Q+kOFk7LN3xvy81xydu7Y=
github.com/infinite-iroha/touka v0.2.8/go.mod h1:e2LRc8FoSU8qjxSlyh3J8gGsBGKQ2VN9bQMU4sIrqnE=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=

0
licenses/about.md Normal file
View file

View file

@ -29,6 +29,7 @@ var (
cfgfile string
cdb *db.ConfigDB
sessionKey []byte
version string
)
func init() {
@ -161,7 +162,7 @@ func main() {
r.Use(api.SessionMiddleware(cdb))
v0 := r.Group("/v0")
api.ApiGroup(v0, cdb, cfg)
api.ApiGroup(v0, cdb, cfg, version)
gob.Register(map[string]interface{}{})
gob.Register(time.Time{})