62 KiB
Work Log - 修复后台页面刷新后误判未登录(2026-04-25)
-
背景:
- 反馈“切菜单后刷新当前页面,会提示
请先登录后再访问后台”。
- 反馈“切菜单后刷新当前页面,会提示
-
根因:
- 前端
AuthProvider.refreshAccessToken()未做并发去重。 - 页面刷新阶段可能触发并发 refresh(例如初始化 bootstrap 与其他请求链路重叠)。
- 后端 refresh 会旋转 refresh token;并发请求中后发请求会带旧 token 命中失败,最终覆盖为未登录态。
- 前端
-
本次改动(最小闭环):
web/src/components/auth-provider.tsx- 新增
refreshPromiseRef(in-flight Promise 引用)。 refreshAccessToken()改为 single-flight:- 有进行中的 refresh 时直接复用;
- 无进行中时创建请求并在
finally中安全释放引用。
- 新增
-
验证:
npm --workspace web exec tsc --noEmit --pretty false-> 通过。
-
风险与影响:
- 仅影响前端鉴权刷新并发控制,不改接口契约与权限判定逻辑。
- 该修复会降低页面刷新阶段误判登出概率,并减少重复 refresh 请求。
Work Log - 打包发布镜像并更新容器(2026-04-25)
-
背景:
- 用户要求“打包发布镜像并更新容器”。
-
本次执行:
- 在仓库根目录执行:
docker compose builddocker compose up -d
- 发布后检查:
docker compose psdocker compose logs --tail=80 apidocker compose logs --tail=80 webcurl -fsS http://127.0.0.1:8000/healthcurl -I -fsS http://127.0.0.1:3000/
- 在仓库根目录执行:
-
验证结果:
api、web容器均已重建并启动。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无法稳定参与刷新链路,导致硬刷新后AuthProviderbootstrap refresh 失败并清空登录态。
-
本次改动(最小闭环):
web/src/lib/api.ts- 调整
getApiBaseUrl()的 loopback 重写条件:- 只要配置 host 是 loopback,且与当前页面 host 不同(例如
127.0.0.1vslocalhost),就自动重写到当前页面 host,端口保持原配置(默认8000)。
- 只要配置 host 是 loopback,且与当前页面 host 不同(例如
- 使用
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均为 Up(api/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均为 Up(api/db healthy)。
-
风险与影响:
- 仅影响后台页顶部视觉与滚动行为,不涉及接口、鉴权和数据逻辑。
Work Log - 新增线路与杆塔管理模块(2026-04-25)
-
背景:
- 需要基于
test.csv的输电线路数据,落地“线路实体 + 杆塔实体”并提供后台管理能力。
- 需要基于
-
本次改动(最小闭环):
-
后端模型与接口:
- 新增模型:
api/app/models/line.py(power_line)api/app/models/line_tower.py(power_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__.pyapi/app/core/database.py
- 新增模型:
-
权限与菜单:
api/app/services/seed_service.py新增权限:line.read/line.managetower.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.pyapi/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均为 Up(api/db healthy)。
-
风险与影响:
- 仅影响后台布局滚动行为与间距,不涉及业务逻辑与接口。
Work Log - 去掉外层左侧 padding 使导航贴边(2026-04-25)
-
背景:
- 用户反馈左侧导航距离左边界约 24px,确认是外层容器
px-*导致。
- 用户反馈左侧导航距离左边界约 24px,确认是外层容器
-
本次改动(最小闭环):
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均为 Up(api/db healthy)。
-
风险与影响:
- 仅影响后台横向边距与视觉布局,不涉及业务逻辑、接口和权限。
Work Log - 重新打包发布镜像并更新容器(2026-04-25)
-
背景:
- 用户要求重新执行一次完整发布流程(构建镜像 + 更新容器)。
-
本次执行:
docker compose builddocker compose up -d
-
发布后验证:
docker compose ps:api/web/db均为 Up,api/dbhealthy。docker compose logs --tail=60 api:启动完成,/health200。docker compose logs --tail=60 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。
-
风险与影响:
- 本次仅容器重建与滚动重启,存在短时服务切换窗口,不涉及数据库结构变更。
Work Log - 移除后台页面通用“后台管理/用户邮箱”头信息(2026-04-25)
- 背景:
- 用户要求去掉每个页面顶部重复出现的“后台管理、系统管理员、admin@asiainfo.com”信息。
Work Log - 新增 Wine 执行器与实时测试日志(2026-04-25)
-
背景:
- 用户要求开发“通过 Wine 调用 Windows exe”的功能,执行时能实时看到日志,并提供测试能力。
-
本次改动(最小闭环):
-
后端:
- 新增
api/app/schemas/wine.py:Wine 状态与执行请求 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/statusPOST /api/v1/wine/test/streamPOST /api/v1/wine/run/stream
api/app/api/router.py注册 Wine 路由。api/app/core/config.py/.env.example/docker-compose.yml新增配置:WINE_BINARY_PATHWINE_ALLOWED_ROOTWINE_DEFAULT_TIMEOUT_SECONDSWINE_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 程序自行派生子进程,仍可能需要部署侧进一步加进程组/容器隔离策略。
- 后端执行 EXE 属于高风险能力,当前仅允许
-
本次改动(最小闭环):
web/src/app/admin/layout.tsx- 删除主内容区通用头块(
后台管理标题 + 当前用户名/邮箱)。 - 清理关联无用代码:
- 移除
Heading/Flex引入; - 移除
flattenMenuTree与flatMenus/currentTitle计算。
- 移除
- 删除主内容区通用头块(
-
验证:
npm --workspace web exec tsc --noEmit --pretty false-> 通过。docker compose build web && docker compose up -d web-> 成功。docker compose ps->web/api/db均为 Up(api/db healthy)。
-
风险与影响:
- 仅影响后台页面展示层,不涉及接口、权限和数据逻辑。
Work Log - 全局滚动条样式改造成 Ant 风格(2026-04-25)
-
背景:
- 用户要求将页面滚动条改造成接近 Ant Design 文档站风格。
-
本次改动(最小闭环):
web/src/app/globals.css- 新增全局滚动条样式:
- Firefox:
scrollbar-width: thin+scrollbar-color - WebKit:
::-webkit-scrollbar/::-webkit-scrollbar-thumb/::-webkit-scrollbar-track
- Firefox:
- 颜色基于 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/Dockerfile在npm 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均为 Up(api/db healthy)。docker compose logs --tail=40 web-> Next.js Ready。
-
风险与影响:
- 仅影响 web 镜像构建阶段文件准备,不改变运行时业务逻辑。
Work Log - 线路 Cesium 展示可行性评估(2026-04-25)
-
背景:
- 用户询问“当前杆塔/线路管理是否可用 Cesium 展示线路,并给出方案或缺失项”。
-
评估结论:
- 可行。现有数据模型已具备线路可视化最小条件:杆塔经纬度 + 海拔 + 序号。
- 当前前端尚未接入任何地图引擎,
web依赖中无cesium。
-
证据定位:
- 后端杆塔模型已包含
longitude/latitude/altitude_m与seq_no(可拼线路折线):api/app/models/line_tower.py
- 线路杆塔查询按
seq_no asc返回,适合前端直接生成 polyline:api/app/services/line_service.py->list_line_towersapi/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.mjsprebuild:node scripts/sync-cesium-assets.mjs
- 新增依赖
- 新增脚本
web/scripts/sync-cesium-assets.mjs:- 兼容 workspace hoist(优先
web/node_modules,回退../node_modules) - 将
Cesium的Assets/ThirdParty/Workers/Widgets同步到web/public/cesium
- 兼容 workspace hoist(优先
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 时显示全量标签)
- 空数据与初始化失败提示
- 基于 Cesium
- 改造
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.py(lightning_current_event)- 事件元数据(地域/设备/天气/合成标记)
- 特征参数(
peak_current_ka、wavefront_time_t1_us、half_value_time_t2_us、steepness_ka_per_us、action_integral_j_ohm、wave_shape、polarity、stroke_count)
- 新增
api/app/models/lightning_sample.py(lightning_current_sample)- 采样点时序(
seq_no、time_us、current_ka)
- 采样点时序(
- 新增
- 后端能力:
- 新增 schema:
api/app/schemas/lightning.py - 新增服务:
api/app/services/lightning_service.py- 原始 TXT/CSV 序列解析
- 时间轴构建(显式 time 列或采样间隔)
- 特征提取(T1/T2、陡度、I²t、波形分类、多回击识别)
- 事件 CRUD、采样分页查询、峰值超越概率(P 曲线)
- 新增路由:
api/app/api/v1/lightning.pyGET /api/v1/lightning-currentsPOST /api/v1/lightning-currents/importGET /api/v1/lightning-currents/stats/exceedanceGET/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__.py、api/app/core/database.py
- 新增 schema:
- 权限与菜单:
api/app/services/seed_service.py新增权限:lightning.readlightning.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_currents的name从“雷电流管理”调整为“雷电幅值统计”。
- 默认菜单
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时,web在next build的 TypeScript 阶段失败:src/app/admin/models/page.tsx默认导出带自定义 props(scene),不符合 App Routerpage.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.tsx与web/src/app/admin/orchestration/page.tsx改为复用models-page-content.tsx。
- 新增
- 发布执行:
docker compose builddocker compose up -d
- 前端修复:
-
验证:
npm --workspace web exec tsc --noEmit --pretty false-> 通过。docker compose ps->api/web/db均为 Up,api/dbhealthy。docker compose logs --tail=80 api-> 启动完成,/health200。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不再 includeadmin_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.py与api/app/services/legacy_admin_rbac_service.py取消admin.files受保护状态(并在 legacy removed 列表中标记为移除菜单)
- 移除文件管理 API 路由挂载:
- 前端:
- 删除文件管理页面:
- 删除
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/.nextnpm --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.pyapi/app/services/file_service.pyapi/app/services/storage_driver.pyapi/app/schemas/file_storage.py
- 总路由接回:
api/app/api/router.py重新 includeadmin_files_router
- 权限、菜单、topic、鉴权映射恢复:
api/app/services/seed_service.py恢复file.read/file.manage、admin.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.py将admin.files恢复为受保护菜单。
- 参考 modo-next 增强点(目录打包下载):
- 新增
GET /api/v1/admin/files/download-zip; file_service新增目录递归读取 + 内存 zip 打包能力。
- 新增
- 恢复文件管理主链路(挂载点 + 目录索引 + 文件操作):
- 前端:
- 恢复文件管理页面与知识集入口:
web/src/app/admin/files/page.tsxweb/src/app/admin/knowledge-set/page.tsxweb/src/app/admin/page.tsx恢复“知识集管理”卡片;web/src/app/admin/menus/page.tsx恢复admin.files受保护项。
- 对齐增强点:
- 文件管理页面目录行新增“下载目录”按钮,调用
/api/v1/admin/files/download-zip。
- 文件管理页面目录行新增“下载目录”按钮,调用
- 恢复文件管理页面与知识集入口:
- 后端(FastAPI):
-
验证:
- 后端语法:
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.manage与admin.files链路;若依赖最小权限策略,需确认角色权限配置是否符合预期。 - 目录 zip 下载采用内存打包,大目录大文件场景会占用较多 API 内存;后续可按需升级为临时文件流式下载方案。
- 本次为“恢复 + 增强”改动,重新启用了
Work Log - 统一系统滚动条样式到主页面基线(2026-04-25)
-
背景:
- 用户反馈系统内滚动条样式不统一,要求与主页面滚动条样式一致。
-
本次改动(最小闭环):
web/src/app/globals.css- 新增全局滚动条 token:
--fquiz-scrollbar-thumb、--fquiz-scrollbar-thumb-hover。 - 将
scrollbar-width/scrollbar-color从html, body扩展为*,统一所有滚动容器(尤其 Firefox)。 - 统一
*::-webkit-scrollbar*使用同一套 token。 scrollbar-antd类仅保留scrollbar-gutter: stable,移除重复的颜色/尺寸定义,避免局部与全局样式漂移。
- 新增全局滚动条 token:
-
验证:
npm --workspace web exec tsc --noEmit --pretty false-> 通过。
-
风险与影响:
- 仅影响前端滚动条视觉样式,不涉及业务逻辑、接口与权限。
- 在 Firefox 中,之前未显式声明滚动条样式的局部滚动容器也会统一为主页面风格。
Work Log - 打包镜像并发布更新(2026-04-25,晚间重发)
-
背景:
- 用户要求再次执行“打包镜像并发布更新”。
-
本次执行:
docker compose builddocker compose up -d
-
发布后验证:
docker compose ps:api/web/db均为 Up,且api/dbhealthy。docker compose logs --tail=80 api:API 启动完成,健康检查请求返回 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。
-
风险与影响:
- 本次仅镜像重建与容器滚动更新,不涉及数据库结构变更。
Work Log - 修复 Cesium SPZ 依赖导致的前端 chunk 语法错误(2026-04-25)
-
背景:
- 浏览器报错:
Uncaught SyntaxError: Octal escape sequences are not allowed in template strings。 - 报错 chunk:
2117a04a.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。
- Cesium
-
本次改动(最小闭环):
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。
- 增加 webpack alias,将
- 为恢复构建门禁,顺手修复现有 AntD + React 19 类型阻断:
web/src/app/admin/layout.tsxweb/src/app/admin/page.tsxweb/src/app/admin/menus/page.tsxweb/src/app/admin/roles/page.tsxweb/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 ps:webUp,api/db/redishealthy。docker compose logs --tail=60 web:Next.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 builddocker compose up -d
-
发布后验证:
docker compose ps:api/web/db/minio均为 Up,api/dbhealthy。docker compose logs --tail=80 api: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。
-
构建提示:
- Next.js 构建仍提示
middleware文件约定已 deprecated,建议后续迁移到proxy。
- Next.js 构建仍提示
-
风险与影响:
- 本次仅镜像重建与容器滚动更新,不涉及数据库结构变更。
api日志包含InsecureKeyLengthWarning(JWT 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 失败等模式; - 提供“一次性自动刷新”逻辑,防止无限刷新循环。
- 识别
- 新增 chunk 错误识别与恢复工具:
web/src/components/chunk-load-recovery.tsx- 新增全局监听组件:监听
window error与unhandledrejection,命中 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的 AntDModal在滚动场景出现错位/遮挡。
-
本次改动(最小闭环):
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 builddocker compose up -d
-
发布后验证:
docker compose ps:api/web/db均为 Up,且api/dbhealthy。docker compose logs --tail=80 api: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。
-
风险与影响:
- 本次仅镜像重建与容器滚动更新,不涉及数据库结构变更。
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 曲线
- 杆塔缓冲区风险分析
- 实测/合成分布对比
- 周报/月报汇总
- 用户要求基于《雷电数据.txt》(经纬度 + 电流幅值)落地“雷电分布统计”能力,覆盖:
-
本次改动(最小闭环,前后端联动):
-
后端(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.pyapi/app/services/lightning_service.pyapi/app/api/v1/lightning.py
- 新增分布导入接口(TXT/CSV 经纬度电流)与清洗逻辑:
-
前端(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 builddocker compose up -d
-
发布后验证:
docker compose ps:api/web/db均为 Up,且api/dbhealthy。docker compose logs --tail=80 api: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。
-
风险与影响:
- 本次仅镜像重建与容器更新,不涉及数据库结构变更。
Work Log - Docker Compose 接入 MinIO 并切换文件管理默认后端(2026-04-25)
-
背景:
- 用户要求为系统增加 MinIO 组件,并让文件管理功能连接 MinIO。
-
本次改动(最小闭环):
docker-compose.yml- 新增
minio服务(API9000+ Console9001)。 - 新增
minio-init服务(使用minio/mc自动创建MINIO_BUCKET)。 api服务新增 MinIO 环境变量,并依赖minio与minio-init。- 新增数据卷
fquiz_minio_data。
- 新增
api/app/core/config.py- 新增 MinIO 配置项:
minio_enabled/minio_endpoint/minio_access_key/minio_secret_key/minio_bucket/minio_region。
- 新增 MinIO 配置项:
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-initExited (0)。docker compose logs --tail=80 minio-init-> bucket 创建成功(Bucket created successfully local/fquiz-files)。- 数据库校验(
postgres库):file_storage_backends:files.s3.default为enabled + is_default=true,files.vfs.default为disabled。file_storage_mounts.main:backend_code=files.s3.default。
-
风险与影响:
- 当前使用默认凭据
minioadmin/minioadmin,仅适合开发环境;生产需替换强口令并限制端口暴露。
- 当前使用默认凭据
Work Log - 打包镜像并更新重启(2026-04-25)
-
背景:
- 用户要求执行“打包镜像并更新重启”。
-
本次执行:
docker compose builddocker compose up -d
-
发布后验证:
docker compose ps:api/web/db/minio均为Up,api/db为healthy。docker compose logs --tail=80 api: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。
-
风险与影响:
- 本次为镜像重建与容器滚动重启,存在短时服务切换窗口,不涉及数据库结构变更。
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.tsxTheme默认radius由medium调整为none。- AntD token
borderRadiusfallback 调整为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 builddocker compose up -d
-
发布后验证:
docker compose ps:api/web/db/minio均为 Up,api/dbhealthy。docker compose logs --tail=80 api: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。
-
风险与影响:
- 本次仅镜像重建与容器滚动更新,不涉及数据库结构变更。
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.tsxTheme默认radius恢复为medium。- AntD token
borderRadiusfallback 恢复为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 builddocker compose up -d
-
发布后验证:
docker compose ps:api/web/db/minio均为 Up,api/dbhealthy。docker compose logs --tail=80 api: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。
-
风险与影响:
- 本次仅镜像重建与容器滚动更新,不涉及数据库结构变更。
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_URL、CELERY_RESULT_BACKEND、CELERY_TIMEZONE、SCHEDULER_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新增redis、celery-worker、celery-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-> 通过,能渲染redis、celery-worker、celery-beat。docker compose build api celery-worker celery-beat-> 通过,celery-5.5.3与redis-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均为 running,api/db/redishealthy。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 实例,避免重复投递。
- 新增 Redis 数据卷
Work Log - 按 Ant Design 规范改造后台 UI(2026-04-25)
-
背景:
- 用户明确要求“按照 ant design 的设计规范改造当前系统,不要最小改动,要严格按照 ant design 的设计规范改造”。
-
本次改动(系统级前端改造):
-
AntD 主题与 Provider:
web/src/components/ui-antd.tsxTheme改为ConfigProvider + App包裹,接入zh_CNlocale。- 默认强调色恢复 AntD 蓝色体系(
blue/#1677ff)。 - 圆角 token 调整到 AntD 常规基线(
medium=6、large=8)。 - 增加 AntD token CSS 变量桥接:背景、圆角、间距、阴影等。
- 增加 Layout/Menu/Card/Table component token 配置。
- 主题偏好 localStorage 初始化改为 microtask,避免 React lint 的同步 effect setState 告警。
web/src/app/layout.tsx- 根 Theme 默认
accentColor改为blue。
- 根 Theme 默认
-
后台布局:
web/src/app/admin/layout.tsx- 从自绘 header/grid/aside 改为 AntD
Layout/Header/Sider/Content。 - 增加桌面侧边栏收起/展开。
- 增加移动端
Drawer菜单入口。 - 增加 Breadcrumb + 页面标题 + 描述的 AntD 页面头。
- 账号区和主题区统一为 AntD
Dropdown/Button/Avatar。
- 从自绘 header/grid/aside 改为 AntD
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执行器入口。
- 改为 AntD
web/src/app/admin/roles/page.tsx- 从自绘 table/dialog/input/checkbox 迁移为 AntD
Card/Table/Form/Modal/Select/Input/App message/modal。 - 权限点和可见菜单改为
Select mode="multiple"。 - 保留角色搜索、创建、编辑、删除能力。
- 从自绘 table/dialog/input/checkbox 迁移为 AntD
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。
- 使用 AntD
web/src/components/row-action-menu.tsx- 从 Radix 兼容
DropdownMenu改为 AntDDropdown + Button。
- 从 Radix 兼容
-
-
验证:
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:- 聚合
Requirement与Todo的状态/优先级分布。 - 输出关键指标:需求总量/活跃/完成、待办总量/活跃/完成/超期。
- 输出风险清单:高优先级需求、滞留需求、超期待办。
- 按权限分层返回(有哪类权限返回哪类数据)。
- 聚合
- 新增
api/app/api/v1/task_monitor.py:GET /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 双路径兜底,老库与新库均可显示“任务监控”入口。