feat(api): dashboard 看板 + config 配置页

Dashboard (M3):
  - 路由 /api/dashboard/{daily,history,today,datasets,stats}/
  - daily_summary: 按日期聚合 ok/warning/error/blocked
  - history: 同步历史详情(按 task / 日期过滤)
  - today: 今日 KPI + 任务列表
  - datasets: dataset_registry + 最近 7d run 合并
  - stats: 各表行数 + 日期范围(17 张表)

  HTML SPA: app/api/static/dashboard.html
    - 5 张状态卡片 + 7 天趋势表 + 任务状态表 + 数据规模表 + 历史详情
    - 自动 30s 刷新, 纯 vanilla JS (无框架依赖)

Config (M5):
  - 路由 /api/config/{GET list, GET key, PUT upsert, DELETE}/
  - 凭证类自动脱敏 (MAIRUI_LICENCE / XUEQIU_TOKEN / MAIRUI_RPS_LIMIT)
  - POST /api/config/reload: 把 .env / 环境变量已知项回填到 config 表
  - 分类过滤 + key 搜索 + 凭证提示

  HTML SPA: app/api/static/config.html
    - 列表 + 编辑弹窗 + 删除确认
    - 凭证类编辑时强制重新输入完整值(避免显示脱敏误以为是新值)
    - 一键从环境变量回填

FastAPI 主入口挂载:
  - include_router(dashboard, config)
  - mount('/static', StaticFiles) 提供 HTML
This commit is contained in:
gao
2026-07-07 17:54:05 +08:00
parent d217553d79
commit 5cb64f181a
5 changed files with 758 additions and 1 deletions
+10 -1
View File
@@ -13,10 +13,11 @@ if str(_PROJECT_ROOT) not in sys.path:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from app.core.config import settings
from app.core.utils.logging import get_logger, setup_logging
from app.api.routes import health, sync, datasources, schedule
from app.api.routes import health, sync, datasources, schedule, dashboard, config
setup_logging()
logger = get_logger("api")
@@ -38,6 +39,14 @@ app.include_router(health.router)
app.include_router(sync.router)
app.include_router(datasources.router)
app.include_router(schedule.router)
app.include_router(dashboard.router)
app.include_router(config.router)
# 看板 HTML 静态文件
import pathlib
_static_dir = pathlib.Path(__file__).resolve().parent / "static"
if _static_dir.exists():
app.mount("/static", StaticFiles(directory=str(_static_dir)), name="static")
# ── 启动钩子 ──────────────────────────────────────────────────────────