feat: complete 2.0.7.12 platform overhaul

This commit is contained in:
2026-08-16 19:33:03 +08:00
parent 73555cd04c
commit c9fa6f7a88
159 changed files with 13243 additions and 2539 deletions
@@ -11,7 +11,6 @@ import (
"ymhut-box/server/unified-management/internal/config"
"ymhut-box/server/unified-management/internal/db"
"ymhut-box/server/unified-management/internal/health"
feedbackmail "ymhut-box/server/unified-management/internal/mail"
)
@@ -54,6 +53,7 @@ func (r *router) handleAdminDatabase(w http.ResponseWriter, req *http.Request) {
writeError(w, http.StatusInternalServerError, "DATABASE_SAVE_FAILED", err)
return
}
r.health.RefreshPreflight()
_ = r.store.InsertAudit(db.AuditLog{Actor: "admin", Type: "system.database.saved", Target: body.Provider, Message: "数据库配置已保存并热切换", IP: req.RemoteAddr, UserAgent: req.UserAgent()})
writeJSON(w, http.StatusOK, map[string]any{"ok": true, "database": r.store.Status(), "config": config.SafeDatabase(r.cfg.BaseDir, r.cfg.Database)})
case req.Method == http.MethodPost && path == "/api/admin/database/sync/jobs":
@@ -161,15 +161,47 @@ func (r *router) handleAdminDashboard(w http.ResponseWriter, req *http.Request)
http.NotFound(w, req)
return
}
overview, err := r.store.DashboardOverview(80)
window, duration, points := dashboardWindow(req.URL.Query().Get("window"))
overview, cacheHit, err := r.dashboardCache.Get(window, func() (map[string]any, error) {
since := time.Now().UTC().Add(-duration).Format(time.RFC3339)
result, buildErr := r.store.DashboardOverviewWindow(points, since)
if buildErr != nil {
return nil, buildErr
}
result["window"] = window
jobs := r.sources.CheckJobs()
if len(jobs) > 5 {
jobs = jobs[:5]
}
result["sourceCheckJobs"] = jobs
result["health"] = r.healthSnapshot()
return result, nil
})
if err != nil {
writeError(w, http.StatusInternalServerError, "DASHBOARD_FAILED", err)
return
}
overview["health"] = health.Snapshot(r.cfg, r.store)
if cacheHit {
w.Header().Set("X-Admin-Cache", "hit")
} else {
w.Header().Set("X-Admin-Cache", "miss")
}
writeJSON(w, http.StatusOK, overview)
}
func dashboardWindow(value string) (string, time.Duration, int) {
switch strings.ToLower(strings.TrimSpace(value)) {
case "1h":
return "1h", time.Hour, 60
case "6h":
return "6h", 6 * time.Hour, 72
case "7d":
return "7d", 7 * 24 * time.Hour, 112
default:
return "24h", 24 * time.Hour, 96
}
}
func (r *router) handleAdminSync(w http.ResponseWriter, req *http.Request) {
if r.syncer == nil {
writeError(w, http.StatusNotFound, "SYNC_DISABLED", errors.New("legacy sync service is not configured"))
@@ -239,7 +271,18 @@ func (r *router) handleAdminSystem(w http.ResponseWriter, req *http.Request) {
path := cleanPath(req.URL.Path)
switch path {
case "/api/admin/system/health":
writeJSON(w, http.StatusOK, health.Snapshot(r.cfg, r.store))
if req.Method != http.MethodGet {
writeError(w, http.StatusMethodNotAllowed, "METHOD_NOT_ALLOWED", errors.New("GET required"))
return
}
writeJSON(w, http.StatusOK, r.healthSnapshot())
case "/api/admin/system/preflight":
if req.Method != http.MethodPost {
writeError(w, http.StatusMethodNotAllowed, "METHOD_NOT_ALLOWED", errors.New("POST required"))
return
}
r.health.RefreshPreflight()
writeJSON(w, http.StatusOK, r.healthSnapshot())
case "/api/admin/system/audit":
page, err := r.store.ListAuditLogsPage(db.AuditFilters{
Page: queryInt(req, "page", 1),
@@ -293,6 +336,12 @@ func (r *router) handleAdminSystem(w http.ResponseWriter, req *http.Request) {
}
}
func (r *router) healthSnapshot() map[string]any {
snapshot := r.health.Snapshot()
snapshot["adminAssets"] = r.adminAssets.Diagnostics()
return snapshot
}
func queryInt(req *http.Request, key string, fallback int) int {
value, err := strconv.Atoi(req.URL.Query().Get(key))
if err != nil || value <= 0 {