Files
fquiz/memory/2026-04-25.md
T
2026-04-26 00:14:25 +08:00

62 KiB
Raw Blame History

Work Log - 修复后台页面刷新后误判未登录(2026-04-25)

  • 背景:

    • 反馈“切菜单后刷新当前页面,会提示 请先登录后再访问后台”。
  • 根因:

    • 前端 AuthProvider.refreshAccessToken() 未做并发去重。
    • 页面刷新阶段可能触发并发 refresh(例如初始化 bootstrap 与其他请求链路重叠)。
    • 后端 refresh 会旋转 refresh token;并发请求中后发请求会带旧 token 命中失败,最终覆盖为未登录态。
  • 本次改动(最小闭环):

    • web/src/components/auth-provider.tsx
      • 新增 refreshPromiseRefin-flight Promise 引用)。
      • refreshAccessToken() 改为 single-flight
        • 有进行中的 refresh 时直接复用;
        • 无进行中时创建请求并在 finally 中安全释放引用。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
  • 风险与影响:

    • 仅影响前端鉴权刷新并发控制,不改接口契约与权限判定逻辑。
    • 该修复会降低页面刷新阶段误判登出概率,并减少重复 refresh 请求。

Work Log - 打包发布镜像并更新容器(2026-04-25)

  • 背景:

    • 用户要求“打包发布镜像并更新容器”。
  • 本次执行:

    • 在仓库根目录执行:
      • docker compose build
      • docker compose up -d
    • 发布后检查:
      • docker compose ps
      • docker compose logs --tail=80 api
      • docker compose logs --tail=80 web
      • curl -fsS http://127.0.0.1:8000/health
      • curl -I -fsS http://127.0.0.1:3000/
  • 验证结果:

    • apiweb 容器均已重建并启动。
    • api 健康检查通过(/health 返回 200{"status":"ok","service":"fquiz-api","version":"0.1.0"})。
    • web 首页返回 HTTP/1.1 200 OK
  • 风险与影响:

    • 本次仅为镜像重建与容器滚动重启,不涉及代码改动或数据库结构变更。

Work Log - 修复 localhost 刷新后丢登录态(2026-04-25

  • 背景:

    • 用户反馈:登录后进入 http://localhost:3000/dashboard,刷新页面后提示“请先登录后再访问后台”。
  • 根因:

    • .env 的前端 API 基址为 http://127.0.0.1:8000,而页面访问 host 为 localhost
    • 浏览器在 localhost -> 127.0.0.1 场景下会形成跨站 cookie 语义,refresh_token 无法稳定参与刷新链路,导致硬刷新后 AuthProvider bootstrap refresh 失败并清空登录态。
  • 本次改动(最小闭环):

    • web/src/lib/api.ts
      • 调整 getApiBaseUrl() 的 loopback 重写条件:
        • 只要配置 host 是 loopback,且与当前页面 host 不同(例如 127.0.0.1 vs localhost),就自动重写到当前页面 host,端口保持原配置(默认 8000)。
      • 使用 URL 对象回写 hostname,兼容 IPv6 场景。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • docker compose build web && docker compose up -d web -> 成功。
    • docker compose ps -> web/api/db 均为 Upapi/db healthy)。
    • curl -I -fsS http://127.0.0.1:3000/dashboard -> 200(路由重写正常)。
  • 风险与影响:

    • 仅影响前端运行时 API 基址解析,不改后端接口、cookie 配置和鉴权协议。
    • localhost/127.0.0.1 混用访问更稳健,可避免刷新阶段误判未登录。

Work Log - 后台顶部信息容器改为滚动时固定(2026-04-25)

  • 背景:

    • 用户要求:当页面内容过多出现纵向滚动条时,顶部用户信息/主题切换区域不要随内容一起滚动。
  • 本次改动(最小闭环):

    • web/src/app/admin/layout.tsx
      • 将主内容区“后台管理标题 + 用户信息”横向容器改为 sticky,固定在顶部导航(64px)下方:
        • sticky top-16 z-40
        • 增加半透明背景、底边框与 backdrop-blur,避免滚动时内容穿透影响可读性。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • docker compose build web && docker compose up -d web -> 成功。
    • docker compose ps -> web/api/db 均为 Upapi/db healthy)。
  • 风险与影响:

    • 仅影响后台页顶部视觉与滚动行为,不涉及接口、鉴权和数据逻辑。

Work Log - 新增线路与杆塔管理模块(2026-04-25)

  • 背景:

    • 需要基于 test.csv 的输电线路数据,落地“线路实体 + 杆塔实体”并提供后台管理能力。
  • 本次改动(最小闭环):

    • 后端模型与接口:

      • 新增模型:
        • api/app/models/line.pypower_line
        • api/app/models/line_tower.pypower_line_tower
      • 新增 Schema
        • api/app/schemas/line.py
      • 新增服务:
        • api/app/services/line_service.py
          • 线路 CRUD
          • 杆塔 CRUD
          • CSV 导入(UTF-8/GBK 兼容、表头额外列兼容、-1 归一化)
          • CSV 导出
      • 新增路由:
        • api/app/api/v1/lines.py
          • /api/v1/lines*
          • /api/v1/lines/{line_id}/towers*
          • /api/v1/lines/towers/{tower_id}
      • 接入总路由:
        • api/app/api/router.py
      • 接入模型初始化:
        • api/app/models/__init__.py
        • api/app/core/database.py
    • 权限与菜单:

      • api/app/services/seed_service.py 新增权限:
        • line.read / line.manage
        • tower.read / tower.manage
      • admin 角色默认授予上述权限。
      • 新增后台菜单:
        • admin.power_lines -> /admin/power-lines
      • admin 默认菜单绑定新增 admin.power_lines
      • 前端菜单管理保护集合新增 admin.power_lines
        • web/src/app/admin/menus/page.tsx
      • 后端受保护菜单集合同步新增 admin.power_lines(防止误删):
        • api/app/services/admin_service.py
        • api/app/services/legacy_admin_rbac_service.py
    • 前端页面:

      • 新增:
        • web/src/app/admin/power-lines/page.tsx
      • 功能:
        • 线路列表/筛选/新建/编辑/删除
        • 杆塔列表/筛选/新建/编辑/删除
        • 杆塔 CSV 导入与导出
      • 类型补充:
        • web/src/types/auth.ts 新增线路/杆塔相关类型定义
  • 验证:

    • 后端语法:
      • python3 -m py_compile api/app/models/line.py api/app/models/line_tower.py api/app/schemas/line.py api/app/services/line_service.py api/app/api/v1/lines.py api/app/api/router.py api/app/core/database.py api/app/services/seed_service.py -> 通过
      • python3 -m compileall api/app -> 通过
    • 前端类型与构建:
      • npm --workspace web exec tsc --noEmit --pretty false -> 通过
      • npm run build:web -> 通过(包含 /admin/power-lines 路由产物)
  • 风险与影响:

    • power_line* 为新表,create_all 模式下可自动创建,但不覆盖既有表结构;后续演进建议补 Alembic 迁移。
    • CSV 导入对“超出表头的额外列”做了兼容落库(raw_extra_json),避免因源文件列漂移中断导入。

Work Log - 更正滚动需求:固定顶部导航栏(Avatar/主题按钮)(2026-04-25

  • 背景:

    • 用户澄清:需要固定的是“最顶部导航栏(包含 Avatar 与主题切换)”,不是主内容区标题栏。
  • 本次改动(最小闭环):

    • web/src/app/admin/layout.tsx
      • 顶部导航栏从 fixed 调整为 sticky top-0 z-50,保证随页面纵向滚动始终固定在视口顶部。
      • 对应移除内容容器为 fixed 预留的 pt-[64px],避免多余上边距。
      • 回退主内容区标题栏为普通流布局(不再 sticky)。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • docker compose build web && docker compose up -d web -> 成功。
    • docker compose ps -> web/api/db 均为 Upapi/db healthy)。
  • 风险与影响:

    • 仅影响后台布局滚动行为与间距,不涉及业务逻辑与接口。

Work Log - 去掉外层左侧 padding 使导航贴边(2026-04-25

  • 背景:

    • 用户反馈左侧导航距离左边界约 24px,确认是外层容器 px-* 导致。
  • 本次改动(最小闭环):

    • web/src/app/admin/layout.tsx
      • 将后台主栅格容器从统一 px-* 改为左右分离:
        • 左侧:md 及以上固定 pl-0(移除左 padding
        • 右侧:保持响应式 pr-3 sm:pr-4 xl:pr-6
      • 目标:在桌面端让左侧导航贴到左边界,同时不改变右侧留白。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • docker compose build web && docker compose up -d web -> 成功。
    • docker compose ps -> web/api/db 均为 Upapi/db healthy)。
  • 风险与影响:

    • 仅影响后台横向边距与视觉布局,不涉及业务逻辑、接口和权限。

Work Log - 重新打包发布镜像并更新容器(2026-04-25)

  • 背景:

    • 用户要求重新执行一次完整发布流程(构建镜像 + 更新容器)。
  • 本次执行:

    • docker compose build
    • docker compose up -d
  • 发布后验证:

    • docker compose psapi/web/db 均为 Upapi/db healthy。
    • docker compose logs --tail=60 api:启动完成,/health 200。
    • docker compose logs --tail=60 webNext.js Ready。
    • curl -fsS http://127.0.0.1:8000/health:返回 {"status":"ok","service":"fquiz-api","version":"0.1.0"}
    • curl -I -fsS http://127.0.0.1:3000/:返回 HTTP/1.1 200 OK
  • 风险与影响:

    • 本次仅容器重建与滚动重启,存在短时服务切换窗口,不涉及数据库结构变更。

Work Log - 移除后台页面通用“后台管理/用户邮箱”头信息(2026-04-25

  • 背景:
    • 用户要求去掉每个页面顶部重复出现的“后台管理、系统管理员、admin@asiainfo.com”信息。

Work Log - 新增 Wine 执行器与实时测试日志(2026-04-25)

  • 背景:

    • 用户要求开发“通过 Wine 调用 Windows exe”的功能,执行时能实时看到日志,并提供测试能力。
  • 本次改动(最小闭环):

    • 后端:

      • 新增 api/app/schemas/wine.pyWine 状态与执行请求 schema。
      • 新增 api/app/services/wine_service.py
        • 检测 wine --version
        • 通过 asyncio.create_subprocess_exec 调用 Wine,不走 shell。
        • stdout/stderr 合并为 SSE 事件实时输出。
        • 支持超时终止、客户端断开时终止进程。
        • EXE 与工作目录限制在 WINE_ALLOWED_ROOT 下,避免任意路径执行。
      • 新增 api/app/api/v1/wine.py
        • GET /api/v1/wine/status
        • POST /api/v1/wine/test/stream
        • POST /api/v1/wine/run/stream
      • api/app/api/router.py 注册 Wine 路由。
      • api/app/core/config.py / .env.example / docker-compose.yml 新增配置:
        • WINE_BINARY_PATH
        • WINE_ALLOWED_ROOT
        • WINE_DEFAULT_TIMEOUT_SECONDS
        • WINE_MAX_TIMEOUT_SECONDS
      • 权限与菜单:
        • 新增 wine.read / wine.manage
        • 新增菜单 admin.wine_runner -> /admin/wine-runner
        • 同步 admin 默认菜单绑定、受保护菜单集合、legacy 权限映射。
    • 前端:

      • 新增 web/src/app/admin/wine-runner/page.tsx
        • Wine 状态检测。
        • EXE 路径、工作目录、参数、超时配置。
        • 执行测试/停止。
        • 使用 fetchWithAuth 读取后端流式响应并实时追加日志。
      • 后台首页新增 “Wine执行器” 入口。
      • 菜单管理保护集合新增 admin.wine_runner
  • 验证:

    • python3 -m py_compile api/app/schemas/wine.py api/app/services/wine_service.py api/app/api/v1/wine.py api/app/api/router.py api/app/core/config.py api/app/services/seed_service.py api/app/services/legacy_authz_service.py api/app/services/admin_service.py api/app/services/legacy_admin_rbac_service.py -> 通过。
    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • 直接运行 Wine 状态服务验证未完成:宿主 Python 环境未安装 FastAPI 依赖,python3 -c ...ModuleNotFoundError: No module named 'fastapi'
    • Ant Design CLI 查询尝试未完成:默认 npm cache 在沙箱内只读;切换 /tmp/npm-cache 后 CLI 安装/执行未稳定返回,已停止该尝试。前端以 TypeScript 作为有效门禁。
  • 风险与影响:

    • 后端执行 EXE 属于高风险能力,当前仅允许 wine.manage 权限调用,并限制路径在 WINE_ALLOWED_ROOT 下。
    • Docker API 镜像默认未安装 Wine;部署环境需自行安装 Wine 或通过 WINE_BINARY_PATH 指向可执行文件,否则状态检测会显示不可用。
    • 停止操作会终止当前 Wine 进程;若 Windows 程序自行派生子进程,仍可能需要部署侧进一步加进程组/容器隔离策略。
  • 本次改动(最小闭环):

    • web/src/app/admin/layout.tsx
      • 删除主内容区通用头块(后台管理 标题 + 当前用户名/邮箱)。
      • 清理关联无用代码:
        • 移除 Heading/Flex 引入;
        • 移除 flattenMenuTreeflatMenus/currentTitle 计算。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • docker compose build web && docker compose up -d web -> 成功。
    • docker compose ps -> web/api/db 均为 Upapi/db healthy)。
  • 风险与影响:

    • 仅影响后台页面展示层,不涉及接口、权限和数据逻辑。

Work Log - 全局滚动条样式改造成 Ant 风格(2026-04-25

  • 背景:

    • 用户要求将页面滚动条改造成接近 Ant Design 文档站风格。
  • 本次改动(最小闭环):

    • web/src/app/globals.css
      • 新增全局滚动条样式:
        • Firefoxscrollbar-width: thin + scrollbar-color
        • WebKit::-webkit-scrollbar / ::-webkit-scrollbar-thumb / ::-webkit-scrollbar-track
      • 颜色基于 Ant token 变量(含回退值),避免主题切换时风格割裂。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • 容器构建与更新成功(见下条日志)。
  • 风险与影响:

    • 仅影响前端视觉层滚动条样式,不涉及业务逻辑。

Work Log - 修复 web 镜像构建链路(postinstall 脚本缺失)(2026-04-25

  • 背景:

    • 重新构建 web 镜像时,npm ci 触发 postinstall 报错:Cannot find module /app/scripts/sync-cesium-assets.mjs
  • 根因:

    • web/Dockerfilenpm ci 前仅复制 package.json/package-lock.json,未复制 scripts/ 目录。
  • 本次改动(最小闭环):

    • web/Dockerfile
      • npm ci 前补充:COPY scripts ./scripts
  • 验证:

    • docker compose build web && docker compose up -d web -> 成功。
    • docker compose ps -> web/api/db 均为 Upapi/db healthy)。
    • docker compose logs --tail=40 web -> Next.js Ready。
  • 风险与影响:

    • 仅影响 web 镜像构建阶段文件准备,不改变运行时业务逻辑。

Work Log - 线路 Cesium 展示可行性评估(2026-04-25

  • 背景:

    • 用户询问“当前杆塔/线路管理是否可用 Cesium 展示线路,并给出方案或缺失项”。
  • 评估结论:

    • 可行。现有数据模型已具备线路可视化最小条件:杆塔经纬度 + 海拔 + 序号。
    • 当前前端尚未接入任何地图引擎,web 依赖中无 cesium
  • 证据定位:

    • 后端杆塔模型已包含 longitude / latitude / altitude_mseq_no(可拼线路折线):
      • api/app/models/line_tower.py
    • 线路杆塔查询按 seq_no asc 返回,适合前端直接生成 polyline:
      • api/app/services/line_service.py -> list_line_towers
      • api/app/api/v1/lines.py -> GET /api/v1/lines/{line_id}/towers
    • 前端线路页已能拿到杆塔坐标并展示表格,但未做地图渲染:
      • web/src/app/admin/power-lines/page.tsx
  • 缺失项(接入前建议补齐):

    • 坐标系元数据(WGS84/GCJ-02/CGCS2000)未显式存储,可能导致地图偏移难以排查。
    • 当前塔列表接口单次 limit 上限为 1000,前端页面固定请求 500;超长线路会被截断,地图需补全分页拉取或专用几何接口。
    • 目前 schema 未限制经纬度范围(仅 float),建议加范围校验避免脏坐标影响渲染。
  • 验证:

    • rg -n "cesium|Cesium|mapbox|leaflet|openlayers|maplibre|deck\\.gl" web api package.json web/package.json -> 无结果(当前未接入地图引擎)。
    • python3 抽样读取 test.csv:34 条杆塔记录,经纬度有效 34 条,满足 Cesium MVP 展示条件。

Work Log - 线路 Cesium MVP 实施(2026-04-25

  • 背景:

    • 用户要求“先实现 MVP 版本”。
  • 本次改动(最小闭环):

    • 前端依赖与构建链路:

      • web/package.json
        • 新增依赖 cesium
        • 新增脚本:
          • postinstall: node scripts/sync-cesium-assets.mjs
          • prebuild: node scripts/sync-cesium-assets.mjs
      • 新增脚本 web/scripts/sync-cesium-assets.mjs
        • 兼容 workspace hoist(优先 web/node_modules,回退 ../node_modules
        • CesiumAssets/ThirdParty/Workers/Widgets 同步到 web/public/cesium
      • web/.gitignore 增加 public/cesium(避免提交生成资产)
      • web/src/app/layout.tsx 增加 Cesium Widgets 全局样式导入
      • web/src/types/antd.d.ts 增加 Cesium css 模块声明
    • 页面能力:

      • 新增组件 web/src/components/power-line-cesium-map.tsx
        • 基于 Cesium Viewer 渲染线路折线(按 seq_no 排序)
        • 渲染杆塔点位(带风险等级颜色)
        • 默认显示起止塔号标签(点位 <=30 时显示全量标签)
        • 空数据与初始化失败提示
      • 改造 web/src/app/admin/power-lines/page.tsx
        • 新增“表格/地图”视图切换
        • 地图视图复用当前筛选后的杆塔数据(塔号/模型/塔型/风险等级)
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • npm run build:web -> 通过(/admin/power-lines 页面产物正常生成,prebuild 触发 Cesium 资产同步)。
  • 风险与影响:

    • 当前为 MVP:仅实现线路折线 + 杆塔点位,不含杆塔 3D 模型与地形分析。
    • 若单条线路点位非常大(>500)仍受现有页面查询口径影响;后续建议补分页全量拉取或专用几何接口。

Work Log - 新增雷电流数据管理模块(2026-04-25)

  • 背景:

    • 需要将原始雷电流序列转化为可用于防雷计算的特征参数,并具备后台可管理能力(导入、查询、统计、预览)。
  • 本次改动(最小闭环):

    • 后端数据模型:
      • 新增 api/app/models/lightning_event.pylightning_current_event
        • 事件元数据(地域/设备/天气/合成标记)
        • 特征参数(peak_current_kawavefront_time_t1_ushalf_value_time_t2_ussteepness_ka_per_usaction_integral_j_ohmwave_shapepolaritystroke_count
      • 新增 api/app/models/lightning_sample.pylightning_current_sample
        • 采样点时序(seq_notime_uscurrent_ka
    • 后端能力:
      • 新增 schemaapi/app/schemas/lightning.py
      • 新增服务:api/app/services/lightning_service.py
        • 原始 TXT/CSV 序列解析
        • 时间轴构建(显式 time 列或采样间隔)
        • 特征提取(T1/T2、陡度、I²t、波形分类、多回击识别)
        • 事件 CRUD、采样分页查询、峰值超越概率(P 曲线)
      • 新增路由:api/app/api/v1/lightning.py
        • GET /api/v1/lightning-currents
        • POST /api/v1/lightning-currents/import
        • GET /api/v1/lightning-currents/stats/exceedance
        • GET/PATCH/DELETE /api/v1/lightning-currents/{event_id}
        • GET /api/v1/lightning-currents/{event_id}/samples
      • 接入总路由:api/app/api/router.py
      • 接入模型预加载:api/app/models/__init__.pyapi/app/core/database.py
    • 权限与菜单:
      • api/app/services/seed_service.py 新增权限:
        • lightning.read
        • lightning.manage
      • admin 默认角色授予上述权限。
      • 新增默认菜单:admin.lightning_currents -> /admin/lightning-currents
    • 前端页面:
      • 新增 web/src/app/admin/lightning-currents/page.tsx
        • 导入原始序列并提取特征
        • 事件筛选列表
        • 事件详情(核心防雷参数)
        • 采样点预览(前 200
        • 峰值超越概率表(P 曲线)
      • 首页卡片接入:web/src/app/admin/page.tsx
      • 菜单保护集合接入:web/src/app/admin/menus/page.tsx
      • 类型补充:web/src/types/auth.ts
  • 验证:

    • 后端语法:
      • python3 -m py_compile api/app/models/lightning_event.py api/app/models/lightning_sample.py api/app/schemas/lightning.py api/app/services/lightning_service.py api/app/api/v1/lightning.py api/app/api/router.py api/app/core/database.py api/app/services/seed_service.py api/app/models/__init__.py -> 通过。
      • python3 -m compileall api/app -> 通过。
    • 前端类型与构建:
      • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
      • npm run build:web -> 通过(包含 /admin/lightning-currents 路由产物)。
  • 风险与影响:

    • 采样点按关系型表存储(lightning_current_sample),超大序列导入会增加写入耗时与存储占用。
    • 当前 T1/T2、多回击识别采用工程化自动提取算法(可用于工程筛查),如需严格对齐特定实验标准可在后续版本引入可配置算法参数。

Work Log - 雷电流模块文案更名(2026-04-25)

  • 背景:

    • 用户要求将功能模块名称改为“雷电幅值统计”。
  • 本次改动(最小闭环):

    • api/app/services/seed_service.py
      • 默认菜单 admin.lightning_currentsname 从“雷电流管理”调整为“雷电幅值统计”。
    • web/src/app/admin/page.tsx
      • 后台首页卡片标题同步改为“雷电幅值统计”。
    • web/src/app/admin/lightning-currents/page.tsx
      • 页面登录提示与主卡片标题文案同步为“雷电幅值统计”。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
  • 风险与影响:

    • 仅文案调整,不涉及接口路径、权限码与数据结构变更。

Work Log - 打包镜像并发布更新(含 Next.js 页面导出修复)(2026-04-25

  • 背景:

    • 用户要求“打包镜像并发布更新”。
  • 发布过程与问题:

    • 首次执行 docker compose build 时,webnext build 的 TypeScript 阶段失败:
      • src/app/admin/models/page.tsx 默认导出带自定义 propsscene),不符合 App Router page.tsx 导出约束。
  • 本次改动(最小闭环):

    • 前端修复:
      • 新增 web/src/app/admin/models/models-page-content.tsx 承载可复用页面主体。
      • web/src/app/admin/models/page.tsx 改为无参默认导出包装,仅渲染 scene="models"
      • web/src/app/admin/mcp-server/page.tsxweb/src/app/admin/orchestration/page.tsx 改为复用 models-page-content.tsx
    • 发布执行:
      • docker compose build
      • docker compose up -d
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • docker compose ps -> api/web/db 均为 Upapi/db healthy。
    • docker compose logs --tail=80 api -> 启动完成,/health 200。
    • docker compose logs --tail=80 web -> Next.js Ready。
    • curl -fsS http://127.0.0.1:8000/health -> {"status":"ok","service":"fquiz-api","version":"0.1.0"}
    • curl -I -fsS http://127.0.0.1:3000/ -> HTTP/1.1 200 OK
  • 风险与影响:

    • 发布包含前端页面导出结构修复,影响范围限定在 models/mcp-server/orchestration 三个页面的组件复用入口,不改变接口契约。
    • 容器更新存在短时切换窗口;本次不涉及数据库结构变更。

Work Log - 下线文件管理功能(2026-04-25)

  • 背景:

    • 用户要求删除当前系统中的文件管理功能。
  • 本次改动(最小闭环):

    • 后端:
      • 移除文件管理 API 路由挂载:
        • 删除 api/app/api/v1/admin_files.py
        • api/app/api/router.py 不再 include admin_files_router
      • 删除文件管理服务与存储驱动实现:
        • 删除 api/app/services/file_service.py
        • 删除 api/app/services/storage_driver.py
        • 删除 api/app/schemas/file_storage.py
      • 清理权限/菜单默认配置:
        • api/app/services/seed_service.py 移除 file.read/file.manage
        • 移除默认菜单 admin.files/admin/knowledge-set
        • admin 默认菜单绑定移除 admin.files
        • 移除默认文件存储 backend/mount 初始化逻辑(_seed_file_storage
      • 清理鉴权与订阅映射:
        • api/app/services/legacy_authz_service.py 移除 file.* 权限与 admin.files 映射
        • api/app/services/topic_registry.py 移除 admin.files 主题规则
        • api/app/services/admin_service.pyapi/app/services/legacy_admin_rbac_service.py 取消 admin.files 受保护状态(并在 legacy removed 列表中标记为移除菜单)
    • 前端:
      • 删除文件管理页面:
        • 删除 web/src/app/admin/files/page.tsx
        • 删除 web/src/app/admin/knowledge-set/page.tsx
      • web/src/app/admin/page.tsx 移除“知识集管理”入口卡片
      • web/src/app/admin/menus/page.tsx 受保护菜单集合移除 admin.files
  • 验证:

    • 后端语法:
      • python3 -m py_compile api/app/api/router.py api/app/services/legacy_authz_service.py api/app/services/topic_registry.py api/app/services/admin_service.py api/app/services/legacy_admin_rbac_service.py api/app/services/seed_service.py -> 通过。
    • 前端类型:
      • 首次执行 npm --workspace web exec tsc --noEmit --pretty false.next/types 缓存残留已删除页面引用失败;
      • 清理缓存后执行:
        • rm -rf web/.next
        • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
  • 风险与影响:

    • 现网数据库若已存在 admin.files 菜单记录,本次代码不会直接删库;在 legacy 菜单树策略下该菜单会被过滤为移除项。
    • 本次仅下线文件管理能力,不触及既有文件存储表结构(file_storage_*)数据。

Work Log - 参考 modo-next 迁移并恢复文件管理(FastAPI 实现,2026-04-25

  • 背景:

    • 用户要求“参考 /root/.openclaw/workspace/modo-next 的文件管理功能,迁移到当前系统,后端用 py 实现”。
  • 本次改动(最小闭环):

    • 后端(FastAPI):
      • 恢复文件管理主链路(挂载点 + 目录索引 + 文件操作):
        • api/app/api/v1/admin_files.py
        • api/app/services/file_service.py
        • api/app/services/storage_driver.py
        • api/app/schemas/file_storage.py
      • 总路由接回:
        • api/app/api/router.py 重新 include admin_files_router
      • 权限、菜单、topic、鉴权映射恢复:
        • api/app/services/seed_service.py 恢复 file.read / file.manageadmin.files 菜单、默认 VFS/S3 存储后端与挂载点初始化;
        • api/app/services/legacy_authz_service.py 恢复 admin.files -> file.* 映射;
        • api/app/services/topic_registry.py 恢复 admin.files 订阅规则;
        • api/app/services/admin_service.py / api/app/services/legacy_admin_rbac_service.pyadmin.files 恢复为受保护菜单。
      • 参考 modo-next 增强点(目录打包下载):
        • 新增 GET /api/v1/admin/files/download-zip
        • file_service 新增目录递归读取 + 内存 zip 打包能力。
    • 前端:
      • 恢复文件管理页面与知识集入口:
        • web/src/app/admin/files/page.tsx
        • web/src/app/admin/knowledge-set/page.tsx
        • web/src/app/admin/page.tsx 恢复“知识集管理”卡片;
        • web/src/app/admin/menus/page.tsx 恢复 admin.files 受保护项。
      • 对齐增强点:
        • 文件管理页面目录行新增“下载目录”按钮,调用 /api/v1/admin/files/download-zip
  • 验证:

    • 后端语法:
      • python3 -m py_compile api/app/api/router.py api/app/api/v1/admin_files.py api/app/schemas/file_storage.py api/app/services/file_service.py api/app/services/storage_driver.py api/app/services/seed_service.py api/app/services/legacy_authz_service.py api/app/services/topic_registry.py api/app/services/admin_service.py api/app/services/legacy_admin_rbac_service.py -> 通过。
    • 前端类型:
      • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
  • 风险与影响:

    • 本次为“恢复 + 增强”改动,重新启用了 file.read/file.manageadmin.files 链路;若依赖最小权限策略,需确认角色权限配置是否符合预期。
    • 目录 zip 下载采用内存打包,大目录大文件场景会占用较多 API 内存;后续可按需升级为临时文件流式下载方案。

Work Log - 统一系统滚动条样式到主页面基线(2026-04-25)

  • 背景:

    • 用户反馈系统内滚动条样式不统一,要求与主页面滚动条样式一致。
  • 本次改动(最小闭环):

    • web/src/app/globals.css
      • 新增全局滚动条 token--fquiz-scrollbar-thumb--fquiz-scrollbar-thumb-hover
      • scrollbar-width/scrollbar-colorhtml, body 扩展为 *,统一所有滚动容器(尤其 Firefox)。
      • 统一 *::-webkit-scrollbar* 使用同一套 token。
      • scrollbar-antd 类仅保留 scrollbar-gutter: stable,移除重复的颜色/尺寸定义,避免局部与全局样式漂移。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
  • 风险与影响:

    • 仅影响前端滚动条视觉样式,不涉及业务逻辑、接口与权限。
    • 在 Firefox 中,之前未显式声明滚动条样式的局部滚动容器也会统一为主页面风格。

Work Log - 打包镜像并发布更新(2026-04-25,晚间重发)

  • 背景:

    • 用户要求再次执行“打包镜像并发布更新”。
  • 本次执行:

    • docker compose build
    • docker compose up -d
  • 发布后验证:

    • docker compose psapi/web/db 均为 Up,且 api/db healthy。
    • docker compose logs --tail=80 api:API 启动完成,健康检查请求返回 200。
    • docker compose logs --tail=80 webNext.js Ready。
    • curl -fsS http://127.0.0.1:8000/health:返回 {"status":"ok","service":"fquiz-api","version":"0.1.0"}
    • curl -I -fsS http://127.0.0.1:3000/:返回 HTTP/1.1 200 OK
  • 风险与影响:

    • 本次仅镜像重建与容器滚动更新,不涉及数据库结构变更。

Work Log - 修复 Cesium SPZ 依赖导致的前端 chunk 语法错误(2026-04-25

  • 背景:

    • 浏览器报错:Uncaught SyntaxError: Octal escape sequences are not allowed in template strings
    • 报错 chunk2117a04a.ddf56f789729a94a.js
  • 根因:

    • Cesium 1.140.0 依赖链中的 @spz-loader/core@0.3.1 把 SPZ WASM 二进制以内联模板字符串打进前端 chunk。
    • 该模板字符串中包含 \00 / \001 等八进制转义形态,浏览器解析阶段直接报错。
    • 当前业务地图仅使用 Cesium Viewer/Entity/Polyline/Point,不使用 SPZ/Gaussian splats。
  • 本次改动(最小闭环):

    • web/src/lib/spz-loader-core-shim.ts
      • 新增 loadSpz / loadSpzFromUrl 轻量 shim。
      • 若未来实际加载 SPZ 内容,显式抛出 SPZ Gaussian splat decoding is disabled in this build.
    • web/next.config.ts
      • 增加 webpack alias,将 @spz-loader/core 指向本地 shim,避免问题依赖进入浏览器 chunk。
    • 为恢复构建门禁,顺手修复现有 AntD + React 19 类型阻断:
      • web/src/app/admin/layout.tsx
      • web/src/app/admin/page.tsx
      • web/src/app/admin/menus/page.tsx
      • web/src/app/admin/roles/page.tsx
      • web/src/app/admin/users/page.tsx
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • npm run build:web -> 通过。
    • 本地构建产物检查:
      • rg -l --text '@spz-loader/core|load_spz|couldn.t allocate memory' web/.next/static/chunks -> 无匹配。
      • rg -l --text 'SPZ Gaussian splat decoding is disabled' web/.next/static/chunks -> 命中本地 shim chunk。
      • node --check web/.next/static/chunks/4912.c2dc9fb5bf5449a0.js -> 通过。
    • Docker 发布:
      • docker compose build web -> 通过。
      • docker compose up -d web -> 成功。
    • 运行中容器验证:
      • docker compose psweb Upapi/db/redis healthy。
      • docker compose logs --tail=60 webNext.js Ready。
      • curl -I -fsS http://127.0.0.1:3000/ -> HTTP/1.1 200 OK
      • curl -sS -I http://127.0.0.1:3000/_next/static/chunks/2117a04a.ddf56f789729a94a.js -> HTTP/1.1 404 Not Found
      • 容器内 grep -R -l 'load_spz\|@spz-loader/core\|couldn.t allocate memory' .next/static/chunks -> 无匹配。
  • 风险与影响:

    • 常规 Cesium 地图能力保留。
    • 如果后续需要加载 SPZ/Gaussian splats,需要移除 shim 并改为上游依赖修复或单独的安全 WASM 加载方案。

Work Log - 拆出雷电分布统计独立菜单入口(2026-04-25)

  • 背景:

    • 用户指出《雷电数据.txt》对应能力应该有基于该数据开发的页面。
  • 本次改动(最小闭环):

    • 前端:
      • 新增独立路由 web/src/app/admin/lightning-distribution/page.tsx,访问地址 /admin/lightning-distribution
      • 调整 web/src/app/admin/lightning-currents/page.tsx
        • /admin/lightning-distribution 下只展示分布统计相关能力;
        • 保留分布导入、Ng/网格热力、Cesium 散点地图、杆塔缓冲区、实测/合成对比、周/月报、P 曲线;
        • 隐藏雷电流幅值页专属的原始序列导入、事件列表、事件详情与采样预览。
      • web/src/app/admin/page.tsx 新增“雷电分布统计”首页入口卡片。
      • web/src/app/admin/menus/page.tsx 新增受保护菜单 admin.lightning_distribution
    • 后端:
      • api/app/services/seed_service.py 新增默认菜单:
        • admin.lightning_distribution -> /admin/lightning-distribution,权限 lightning.read
      • admin 默认菜单绑定新增 admin.lightning_distribution
      • admin_service / legacy_admin_rbac_service / legacy_authz_service 同步补充保护集合、权限映射与 legacy admin 默认权限。
  • 验证:

    • python3 -m py_compile api/app/services/seed_service.py api/app/services/admin_service.py api/app/services/legacy_admin_rbac_service.py api/app/services/legacy_authz_service.py -> 通过。
    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • npm run build:web -> 通过,构建产物包含 /admin/lightning-distribution
  • 风险与影响:

    • 仅新增入口并复用现有雷电分布统计接口与页面底座,不新增数据表和接口契约。
    • 已运行容器若要看到新菜单,需要重新构建/重启前后端服务并触发默认菜单种子同步。

Work Log - 打包镜像并发布更新(2026-04-25,连续重发)

  • 背景:

    • 用户再次要求执行“打包镜像并发布更新”。
  • 本次执行:

    • docker compose build
    • docker compose up -d
  • 发布后验证:

    • docker compose psapi/web/db/minio 均为 Upapi/db healthy。
    • docker compose logs --tail=80 apiAPI 启动完成,/health 请求返回 200。
    • docker compose logs --tail=80 webNext.js Ready。
    • curl -fsS http://127.0.0.1:8000/health:返回 {"status":"ok","service":"fquiz-api","version":"0.1.0"}
    • curl -I -fsS http://127.0.0.1:3000/:返回 HTTP/1.1 200 OK
  • 构建提示:

    • Next.js 构建仍提示 middleware 文件约定已 deprecated,建议后续迁移到 proxy
  • 风险与影响:

    • 本次仅镜像重建与容器滚动更新,不涉及数据库结构变更。
    • api 日志包含 InsecureKeyLengthWarningJWT HMAC key 长度低于建议值),不影响本次发布成功,但建议后续将 JWT_SECRET_KEY 升级为至少 32 字节。

Work Log - 修复 Next.js chunk 丢失导致页面白屏(2026-04-25)

  • 背景:

    • 本地访问 http://localhost:3000 出现报错:
      • Loading chunk 5782 failed. (missing: .../_next/static/chunks/*.js)
    • 该类问题通常由浏览器缓存中的旧 chunk 清单与当前构建产物不一致触发。
  • 本次改动(最小闭环):

    • web/src/lib/chunk-error.ts
      • 新增 chunk 错误识别与恢复工具:
        • 识别 Loading chunk ... failed / ChunkLoadError / 动态 import 失败等模式;
        • 提供“一次性自动刷新”逻辑,防止无限刷新循环。
    • web/src/components/chunk-load-recovery.tsx
      • 新增全局监听组件:监听 window errorunhandledrejection,命中 chunk 错误时自动刷新一次。
    • web/src/app/layout.tsx
      • 接入 ChunkLoadRecovery,让所有页面共享该容错能力。
    • web/src/app/error.tsx
      • 新增路由级错误边界 UI;chunk 失配时自动刷新,并提供“重试/刷新页面”手动恢复按钮。
    • web/src/app/global-error.tsx
      • 新增全局错误边界 UI,覆盖 root layout 级异常场景。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • npm run build:web -> 通过(Next.js 16 构建完成,路由产物正常)。
  • 风险与影响:

    • 仅影响前端异常恢复链路,不涉及接口契约、权限与数据库。
    • 若用户浏览器禁用 sessionStorage,则“防重复刷新标记”为 best-effort;仍可通过错误页按钮手动刷新恢复。

Work Log - 修复页面滚动后 Modal 顶部遮挡(2026-04-25

  • 背景:

    • 用户反馈:页面滚动到底部时打开 Modal,弹窗在顶部被屏幕遮挡。
  • 根因:

    • web/src/app/globals.css快乐工作特效body 使用了 filter 动画。
    • filter 会改变 position: fixed 的定位上下文,导致挂载到 body 的 AntD Modal 在滚动场景出现错位/遮挡。
  • 本次改动(最小闭环):

    • web/src/app/globals.css
      • 保留 :root.fquiz-happy-work body 动画开关。
      • 将关键帧从 filter 动画改为 background-color 轻微脉冲(color-mix),避免影响 fixed 定位。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
  • 风险与影响:

    • 仅影响“快乐工作特效”视觉表现;不涉及业务逻辑、接口与权限。
    • Modal 定位恢复为相对视口,滚动场景下不再被顶部裁切。

Work Log - 打包镜像并发布更新(2026-04-25,夜间重发)

  • 背景:

    • 用户要求执行“打包镜像并发布更新”。
  • 本次执行:

    • docker compose build
    • docker compose up -d
  • 发布后验证:

    • docker compose psapi/web/db 均为 Up,且 api/db healthy。
    • docker compose logs --tail=80 apiAPI 启动完成,/health 请求返回 200。
    • docker compose logs --tail=80 webNext.js Ready。
    • curl -fsS http://127.0.0.1:8000/health:返回 {"status":"ok","service":"fquiz-api","version":"0.1.0"}
    • curl -I -fsS http://127.0.0.1:3000/:返回 HTTP/1.1 200 OK
  • 风险与影响:

    • 本次仅镜像重建与容器滚动更新,不涉及数据库结构变更。

Work Log - 修复线路地图 Chunk 失败不自动恢复(2026-04-25

  • 背景:

    • 线路管理地图视图出现 地图加载失败,错误为 Loading chunk ... failed
    • 根因是 Cesium import("cesium") 在组件内被 try/catch 捕获,导致全局 chunk 恢复监听未触发。
  • 本次改动(最小闭环):

    • web/src/components/power-line-cesium-map.tsx
      • import("cesium") 失败的 catch 分支里接入 reloadOnceOnChunkError(error)
      • 命中 chunk 错误时先触发自动刷新恢复,再兜底展示错误。
    • web/src/components/chunk-load-recovery.tsx
      • 移除挂载时清理 marker 的逻辑,避免持续 chunk 失败时反复刷新。
    • web/src/lib/chunk-error.ts
      • 单次刷新标记改为“带时间戳冷却窗口”(2 分钟),避免刷新死循环,同时保留后续恢复能力。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • npm run build:web -> 通过。
  • 风险与影响:

    • 仅影响前端异常恢复策略,不涉及接口契约、权限和数据库。
    • 若 chunk 在冷却窗口内持续不可用,将停止自动刷新并保留页面错误提示,避免无限重载。

Work Log - 新增雷电分布统计模块(空间统计 + 资产关联 + 报表,2026-04-25

  • 背景:

    • 用户要求基于《雷电数据.txt》(经纬度 + 电流幅值)落地“雷电分布统计”能力,覆盖:
      • 网格化地闪密度(Ng
      • 电流极值/均值与极性占比
      • 雷电热力图 + 散点分布 + P 曲线
      • 杆塔缓冲区风险分析
      • 实测/合成分布对比
      • 周报/月报汇总
  • 本次改动(最小闭环,前后端联动):

    • 后端(FastAPI + SQLAlchemy

      • 新增分布导入接口(TXT/CSV 经纬度电流)与清洗逻辑:
        • POST /api/v1/lightning-currents/import-distribution
        • 自动过滤非法行/非法坐标,落库到 lightning_current_event(无波形样本)
      • 新增空间统计接口:
        • GET /api/v1/lightning-currents/stats/distribution
        • 返回网格统计(Ng/Imax/Iavg/正极占比)、散点数据、P 曲线、极性统计、来源统计
      • 新增资产关联接口:
        • GET /api/v1/lightning-currents/stats/tower-buffer
        • 支持 tower_id 或自定义坐标 + 半径(km)缓冲区分析,输出风险等级与建议
      • 新增合成对比接口:
        • GET /api/v1/lightning-currents/stats/compare-synthetic
        • 输出实测/合成统计与网格余弦相似度
      • 新增周期报表接口:
        • GET /api/v1/lightning-currents/reports/distribution?period=week|month
        • 输出近 7 天/30 天雷击次数、Imax/Iavg、Ng、最严重事件
      • 主要文件:
        • api/app/schemas/lightning.py
        • api/app/services/lightning_service.py
        • api/app/api/v1/lightning.py
    • 前端(Next.js + AntD

      • web/src/app/admin/lightning-currents/page.tsx 扩展为“雷电分布统计工作台”:
        • 分布筛选(经纬度范围、网格尺寸、年限、阈值)
        • 分布导入按钮(调用 import-distribution
        • 分布摘要指标(Ng、Imax/Iavg、极性与来源)
        • 网格热力表(按雷击次数着色)
        • 杆塔缓冲区分析表单 + 风险结果 + 命中事件表
        • 实测/合成对比 + 周/月报卡片
        • P 曲线优先展示空间统计返回结果
      • 新增 Cesium 地图组件:
        • web/src/components/lightning-distribution-map.tsx
        • 支持热力网格(矩形半透明着色)+ 雷击散点(按电流幅值分色)
      • 补充类型定义:
        • web/src/types/auth.ts
  • 验证:

    • 后端语法:
      • python3 -m py_compile api/app/schemas/lightning.py api/app/services/lightning_service.py api/app/api/v1/lightning.py -> 通过
    • 前端类型:
      • npm --workspace web exec tsc --noEmit --pretty false -> 通过
    • 前端构建:
      • npm run build:web -> 通过(含 /admin/lightning-currents
  • 风险与影响:

    • 当前空间统计采用经纬度近似换算(非 PostGIS 精确地理计算);在高纬或超大范围场景误差会增大。
    • import-distribution 为高吞吐导入,超大文件建议分批导入以降低单次事务压力。
    • 杆塔缓冲区分析当前为查询结果级风险判定(返回风险等级与建议),如需“自动写回杆塔风险字段”可在后续补充持久化开关与审计策略。

Work Log - 打包镜像并发布更新(2026-04-25,深夜重发)

  • 背景:

    • 用户要求再次执行“打包镜像并发布更新”。
  • 本次执行:

    • docker compose build
    • docker compose up -d
  • 发布后验证:

    • docker compose psapi/web/db 均为 Up,且 api/db healthy。
    • docker compose logs --tail=80 apiAPI 启动完成,/health 请求返回 200。
    • docker compose logs --tail=80 webNext.js Ready。
    • curl -fsS http://127.0.0.1:8000/health:返回 {"status":"ok","service":"fquiz-api","version":"0.1.0"}
    • curl -I -fsS http://127.0.0.1:3000/:返回 HTTP/1.1 200 OK
  • 风险与影响:

    • 本次仅镜像重建与容器更新,不涉及数据库结构变更。

Work Log - Docker Compose 接入 MinIO 并切换文件管理默认后端(2026-04-25)

  • 背景:

    • 用户要求为系统增加 MinIO 组件,并让文件管理功能连接 MinIO。
  • 本次改动(最小闭环):

    • docker-compose.yml
      • 新增 minio 服务(API 9000 + Console 9001)。
      • 新增 minio-init 服务(使用 minio/mc 自动创建 MINIO_BUCKET)。
      • api 服务新增 MinIO 环境变量,并依赖 miniominio-init
      • 新增数据卷 fquiz_minio_data
    • api/app/core/config.py
      • 新增 MinIO 配置项:minio_enabled/minio_endpoint/minio_access_key/minio_secret_key/minio_bucket/minio_region
    • api/app/services/seed_service.py
      • 文件存储种子改为按 MINIO_ENABLED 动态切换默认后端:
        • 开启时:files.s3.default 启用且设为默认,main 挂载指向 S3。
        • 关闭时:回退 files.vfs.default
      • 对已存在后端记录也会更新 status/is_default/config_json,保证切换生效。
    • .env / .env.example
      • 增加 MinIO 相关变量与端口/镜像默认值。
  • 验证:

    • python3 -m py_compile api/app/core/config.py api/app/services/seed_service.py -> 通过。
    • docker compose config -> 通过。
    • docker compose up -d minio minio-init api + docker compose up --build -d api -> 成功。
    • docker compose ps -a -> minio 运行中,minio-init Exited (0)
    • docker compose logs --tail=80 minio-init -> bucket 创建成功(Bucket created successfully local/fquiz-files)。
    • 数据库校验(postgres 库):
      • file_storage_backendsfiles.s3.defaultenabled + is_default=truefiles.vfs.defaultdisabled
      • file_storage_mounts.mainbackend_code=files.s3.default
  • 风险与影响:

    • 当前使用默认凭据 minioadmin/minioadmin,仅适合开发环境;生产需替换强口令并限制端口暴露。

Work Log - 打包镜像并更新重启(2026-04-25)

  • 背景:

    • 用户要求执行“打包镜像并更新重启”。
  • 本次执行:

    • docker compose build
    • docker compose up -d
  • 发布后验证:

    • docker compose psapi/web/db/minio 均为 Upapi/dbhealthy
    • docker compose logs --tail=80 apiAPI 启动完成,/health 持续返回 200。
    • docker compose logs --tail=80 webNext.js Ready。
    • curl -fsS http://127.0.0.1:8000/health:返回 {"status":"ok","service":"fquiz-api","version":"0.1.0"}
    • curl -I -fsS http://127.0.0.1:3000/:返回 HTTP/1.1 200 OK
  • 风险与影响:

    • 本次为镜像重建与容器滚动重启,存在短时服务切换窗口,不涉及数据库结构变更。

Work Log - 用户管理新增用户表单迁移到 Modal(2026-04-25

  • 背景:

    • 用户要求将“用户管理”页面的新增用户表单从页面内联区域改为弹窗输入。
  • 本次改动(最小闭环):

    • web/src/app/admin/users/page.tsx
      • 新增 createUserModalOpen 状态与打开/关闭处理。
      • 原“新增用户”卡片内联 Form 改为提示文案 + 新增用户 按钮触发。
      • 新增“新增用户”Modal,内部复用原有创建表单字段、校验规则与提交逻辑。
      • 创建成功后自动关闭弹窗并刷新用户/角色列表;创建中禁止关闭弹窗。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
  • 风险与影响:

    • 仅调整前端交互承载位置,不涉及接口契约、权限和数据库。

Work Log - 菜单管理页面去掉顶部统计区块(2026-04-25)

  • 背景:

    • 用户要求菜单管理页面移除顶部“总菜单数/启用/禁用/顶级菜单”统计展示。
  • 本次改动(最小闭环):

    • web/src/app/admin/menus/page.tsx
      • 删除顶部统计区块渲染(四个 Statistic 卡片)。
      • 清理未使用的 Statistic 引入与 stats 计算逻辑。
      • 保留筛选表单、菜单列表与新建/编辑弹窗能力不变。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
  • 风险与影响:

    • 仅影响页面展示,不涉及接口、权限和数据逻辑。

Work Log - 全部去掉外层间距并去掉圆角(2026-04-25)

  • 背景:

    • 用户要求“全部去掉外层间距,去掉圆角”。
  • 本次改动(最小闭环):

    • web/src/app/admin/layout.tsx
      • 顶栏容器去掉 max-width 与外层左右 padding。
      • 主栅格容器去掉 max-width 与外层左右 padding。
      • 主内容容器由 py-4 md:px-6 调整为 py-0 px-0(去掉外层间距)。
      • 进入后台时给 body 增加 fquiz-admin-flat 类,离开后台移除。
    • web/src/app/globals.css
      • 新增 body.fquiz-admin-flat 作用域:对元素与伪元素统一 border-radius: 0 !important,去掉后台页面与弹窗圆角。
    • web/src/components/ui-antd.tsx
      • Theme 默认 radiusmedium 调整为 none
      • AntD token borderRadius fallback 调整为 RADIUS_MAP.none
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
  • 风险与影响:

    • 后台视觉风格将显著变为“直角 + 贴边”,包括头像/标签/弹窗等圆角元素。
    • 仅影响前端样式,不涉及接口、权限与数据逻辑。

Work Log - 角色管理页面支持搜索(2026-04-25)

  • 背景:

    • 用户要求角色管理页面支持搜索。
  • 本次改动(最小闭环):

    • web/src/app/admin/roles/page.tsx
      • 新增搜索状态 searchKeyword
      • 新增 filteredRoles,基于关键词对角色进行前端过滤,匹配字段包括:
        • 角色编码 code
        • 角色名称 name
        • 权限编码列表 permission_codes
        • 菜单名称/编码(通过 menu_ids 映射)
      • 页面新增搜索输入框(支持清空),位于角色列表头部。
      • 列表统计文案改为“总数 + 匹配数”。
      • 无匹配时显示“未找到匹配角色,请调整搜索关键词”。
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
  • 风险与影响:

    • 本次为前端本地过滤,不改变后端接口契约和权限逻辑。
    • 当角色规模极大时,本地过滤性能可能下降;若后续角色数增长明显,可再升级为后端关键词查询。

Work Log - 打包镜像并发布更新(2026-04-25,夜间再次重发)

  • 背景:

    • 用户要求执行“打包镜像并发布更新”。
  • 本次执行:

    • docker compose build
    • docker compose up -d
  • 发布后验证:

    • docker compose psapi/web/db/minio 均为 Upapi/db healthy。
    • docker compose logs --tail=80 apiAPI 启动完成,/health 请求返回 200。
    • docker compose logs --tail=80 webNext.js Ready。
    • curl -fsS http://127.0.0.1:8000/health:返回 {"status":"ok","service":"fquiz-api","version":"0.1.0"}
    • curl -I -fsS http://127.0.0.1:3000/:返回 HTTP/1.1 200 OK
  • 风险与影响:

    • 本次仅镜像重建与容器滚动更新,不涉及数据库结构变更。

Work Log - 恢复后台圆角(2026-04-25

  • 背景:

    • 用户要求“恢复圆角”。
  • 本次改动(最小闭环):

    • web/src/app/globals.css
      • 移除 body.fquiz-admin-flat 下全局强制 border-radius: 0 !important 的规则。
    • web/src/app/admin/layout.tsx
      • 移除进入后台时给 body 增加 fquiz-admin-flat 的逻辑。
      • 保留已调整的贴边布局与外层间距策略。
    • web/src/components/ui-antd.tsx
      • Theme 默认 radius 恢复为 medium
      • AntD token borderRadius fallback 恢复为 RADIUS_MAP.medium
  • 验证:

    • rg -n "fquiz-admin-flat|admin-flat-ui|borderRadius: RADIUS_MAP\\[radius\\] \\?\\? RADIUS_MAP\\.none|radius = \\"none\\"" web/src -> 无匹配。
    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
  • 风险与影响:

    • 仅恢复前端视觉圆角,不涉及接口、权限、数据结构。
    • 外层贴边/去外层间距布局未回退。

Work Log - 打包镜像并发布更新(2026-04-25,再次执行)

  • 背景:

    • 用户要求执行“打包镜像并发布更新”。
  • 本次执行:

    • docker compose build
    • docker compose up -d
  • 发布后验证:

    • docker compose psapi/web/db/minio 均为 Upapi/db healthy。
    • docker compose logs --tail=80 apiAPI 启动完成,/health 请求返回 200。
    • docker compose logs --tail=80 webNext.js Ready。
    • curl -fsS http://127.0.0.1:8000/health:返回 {"status":"ok","service":"fquiz-api","version":"0.1.0"}
    • curl -I -fsS http://127.0.0.1:3000/:返回 HTTP/1.1 200 OK
  • 风险与影响:

    • 本次仅镜像重建与容器滚动更新,不涉及数据库结构变更。

Work Log - 接入 Redis + Celery + Beat 后端调度(2026-04-25

  • 背景:

    • 用户明确要求“加 redis 组件,上 Celery + Beat”。
  • 本次改动(最小闭环):

    • 依赖:
      • api/requirements.txt 新增 celery[redis]==5.5.3
      • api/pyproject.toml 新增 celery[redis]>=5.5.0,<6.0.0
    • 后端配置:
      • api/app/core/config.py 新增 CELERY_BROKER_URLCELERY_RESULT_BACKENDCELERY_TIMEZONESCHEDULER_EXPIRE_INTERVAL_SECONDS 配置。
      • 新增 api/app/core/celery_app.py,统一配置 Celery app、Redis broker/result backend 与 Beat schedule。
    • 任务模块:
      • 新增 api/app/tasks/
      • 新增任务 app.tasks.schedule_tasks.expire_overdue_schedule_items
      • api/app/services/calendar_event_service.py 将日程过期逻辑公开为 expire_overdue_events()
      • api/app/services/todo_service.py 新增 expire_overdue_todos()
    • Compose
      • docker-compose.yml 新增 rediscelery-workercelery-beat 服务。
      • .env.example 新增 Redis/Celery/调度间隔配置项。
  • 验证:

    • python3 -m py_compile api/app/core/config.py api/app/core/celery_app.py api/app/tasks/__init__.py api/app/tasks/schedule_tasks.py api/app/services/calendar_event_service.py api/app/services/todo_service.py -> 通过。
    • docker compose config -> 通过,能渲染 rediscelery-workercelery-beat
    • docker compose build api celery-worker celery-beat -> 通过,celery-5.5.3redis-5.2.1 安装成功。
    • docker compose up -d redis api celery-worker celery-beat -> 成功。
    • docker compose ps --status running -> api/celery-worker/celery-beat/redis/db/minio/web 均为 runningapi/db/redis healthy。
    • docker exec fquiz-redis redis-cli ping -> PONG
    • docker exec fquiz-celery-worker celery -A app.core.celery_app.celery_app inspect registered -> 已注册 app.tasks.schedule_tasks.expire_overdue_schedule_items
    • 手动投递 expire_overdue_schedule_items -> worker 执行成功,返回 {'expired_calendar_events': 0, 'expired_todos': 0}
    • Beat 日志显示已周期投递 expire-overdue-schedule-items
    • curl -fsS http://127.0.0.1:8000/health -> API 健康。
    • curl -I -fsS http://127.0.0.1:3000/ -> Web 首页 200。
  • 风险与影响:

    • 新增 Redis 数据卷 fquiz_redis_data 与端口 6379
    • celery-worker 当前以容器 root 用户运行,Celery 会输出安全警告;生产环境建议后续在 API Dockerfile 中新增非 root 用户并为 worker/beat 指定用户。
    • 当前 Beat schedule 使用本地文件 /tmp/celerybeat-schedule,适合当前单 Beat 实例;不要横向启动多个 Beat 实例,避免重复投递。

Work Log - 按 Ant Design 规范改造后台 UI2026-04-25

  • 背景:

    • 用户明确要求“按照 ant design 的设计规范改造当前系统,不要最小改动,要严格按照 ant design 的设计规范改造”。
  • 本次改动(系统级前端改造):

    • AntD 主题与 Provider

      • web/src/components/ui-antd.tsx
        • Theme 改为 ConfigProvider + App 包裹,接入 zh_CN locale。
        • 默认强调色恢复 AntD 蓝色体系(blue/#1677ff)。
        • 圆角 token 调整到 AntD 常规基线(medium=6large=8)。
        • 增加 AntD token CSS 变量桥接:背景、圆角、间距、阴影等。
        • 增加 Layout/Menu/Card/Table component token 配置。
        • 主题偏好 localStorage 初始化改为 microtask,避免 React lint 的同步 effect setState 告警。
      • web/src/app/layout.tsx
        • 根 Theme 默认 accentColor 改为 blue
    • 后台布局:

      • web/src/app/admin/layout.tsx
        • 从自绘 header/grid/aside 改为 AntD Layout/Header/Sider/Content
        • 增加桌面侧边栏收起/展开。
        • 增加移动端 Drawer 菜单入口。
        • 增加 Breadcrumb + 页面标题 + 描述的 AntD 页面头。
        • 账号区和主题区统一为 AntD Dropdown/Button/Avatar
      • web/src/app/globals.css
        • 增加 admin-design-* 布局类,统一 64px Header、24px 内容区留白、Sider 粘性高度、移动端 16px 内容留白。
        • 不使用全局 .ant-* 覆盖,布局样式通过项目自有 class + AntD token 变量表达。
    • 工作台与核心页面:

      • web/src/app/admin/page.tsx
        • 改为 AntD Statistic 汇总 + Row/Col/Card/Tag/Avatar 模块入口。
        • 模块入口 URL 改为公开路径(如 /users),减少 /admin/* 重定向依赖。
        • 增加 Wine执行器 入口。
      • web/src/app/admin/roles/page.tsx
        • 从自绘 table/dialog/input/checkbox 迁移为 AntD Card/Table/Form/Modal/Select/Input/App message/modal
        • 权限点和可见菜单改为 Select mode="multiple"
        • 保留角色搜索、创建、编辑、删除能力。
      • web/src/app/admin/users/page.tsx
        • 列表 Card 直接使用 AntD Card,并将“新增用户”动作收口到列表 Card extra,减少单按钮卡片。
      • web/src/app/admin/menus/page.tsx
        • 使用 AntD App.useApp() message,去掉独立 message context holder。
        • 列表 Card 直接使用 AntD Card。
      • web/src/components/row-action-menu.tsx
        • 从 Radix 兼容 DropdownMenu 改为 AntD Dropdown + Button
  • 验证:

    • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
    • 针对本次改动文件执行:
      • npx eslint src/app/admin/layout.tsx src/app/admin/page.tsx src/app/admin/roles/page.tsx src/app/admin/users/page.tsx src/app/admin/menus/page.tsx src/components/row-action-menu.tsx src/components/ui-antd.tsx -> 通过。
    • npm run build:web -> 通过(Next.js 16 构建完成,33 个 app routes 生成成功)。
    • git diff --check -- <本次改动文件> -> 通过。
  • 说明:

    • 尝试按 ant-design 技能要求运行官方 CLI
      • npx antd info ... --format json -> 失败(不是官方 CLI 可执行包)。
      • npx @ant-design/cli info ... --format json -> 下载后长时间卡住,已终止卡住进程。
    • 因 CLI 在当前环境不可用,本次以官方 AntD 组件 API 类型、本地 TypeScript、Next build 和 AntD 设计规范口径兜底。
    • npm --workspace web run lint 全量仍失败,主要来自 web/public/cesium 生成资产与历史页面 hook/any 问题;本次改动文件的 targeted lint 已通过。
  • 风险与影响:

    • 后台视觉与交互范围变更较大:恢复 AntD 内容区留白、页面标题、Breadcrumb、Sider 折叠和移动端 Drawer。
    • 这是前端 UI 改造,不涉及后端接口、权限码和数据库结构。
    • 因全局后台 layout 改造覆盖所有后台页面,建议发布前做一次浏览器人工走查:桌面、移动端、浅色/暗黑/紧凑主题。

Work Log - 新增任务监控模块(2026-04-25)

  • 背景:

    • 用户要求“补充任务监控功能”。
  • 本次改动(最小闭环):

    • 后端:

      • 新增 api/app/schemas/task_monitor.py:任务监控聚合响应 schema。
      • 新增 api/app/services/task_monitor_service.py
        • 聚合 RequirementTodo 的状态/优先级分布。
        • 输出关键指标:需求总量/活跃/完成、待办总量/活跃/完成/超期。
        • 输出风险清单:高优先级需求、滞留需求、超期待办。
        • 按权限分层返回(有哪类权限返回哪类数据)。
      • 新增 api/app/api/v1/task_monitor.pyGET /api/v1/admin/task-monitor/overview
      • 路由注册:api/app/api/router.py 接入 task_monitor_router
    • 菜单与权限映射:

      • api/app/services/seed_service.py:新增默认菜单 admin.task_monitor/admin/task-monitor)并加入 admin 默认菜单绑定。
      • api/app/services/legacy_authz_service.py:新增 admin.task_monitor 权限映射(requirement.read + todo.read)与 legacy synthetic 菜单兜底。
      • api/app/services/legacy_admin_rbac_service.py:将 admin.task_monitor 加入受保护菜单集合。
      • web/src/app/admin/menus/page.tsx:受保护菜单集合新增 admin.task_monitor,避免误删。
    • 前端:

      • 新增 web/src/app/admin/task-monitor/page.tsx
        • 监控参数(风险项上限、滞留阈值小时)可调。
        • 展示指标卡、分布标签、风险表格(高优先级需求/滞留需求/超期待办)。
        • 无权限与未登录态提示完整。
      • web/src/app/admin/page.tsx:新增“任务监控”工作台入口卡片。
  • 验证:

    • 后端语法:
      • python3 -m py_compile api/app/schemas/task_monitor.py api/app/services/task_monitor_service.py api/app/api/v1/task_monitor.py api/app/api/router.py api/app/services/legacy_authz_service.py api/app/services/legacy_admin_rbac_service.py api/app/services/seed_service.py -> 通过。
    • 前端类型:
      • rm -rf .next(清理过期类型产物)
      • npm --workspace web exec tsc --noEmit --pretty false -> 通过。
  • 风险与影响:

    • 任务监控为聚合读接口,不改原有需求/待办 CRUD 链路。
    • 需求数据当前无独立 due_at 持久字段,滞留判断基于 update_date 与阈值小时。
    • 菜单通过 seed + legacy synthetic 双路径兜底,老库与新库均可显示“任务监控”入口。