28 KiB
28 KiB
opencatd-open 重构计划
本文档是重构过程的唯一进度记录,每完成一个阶段立即更新「阶段状态」与「执行记录」。 前后端同仓库,本期(第一期)只重构前端 + 前端相关的构建脚本;后端代码不在本期范围。
- 计划创建时间:2026-08-29
- 当前分支:
team(按约定不提交,所有改动留在工作区,由维护者回来后审查) - 项目根目录:
/Users/cjun/Code/Go/src/opencatd-open - 前端目录:
frontend/(构建产物dist/由 Go 通过//go:embed dist/*嵌入cmd/openteam)
一、背景与现状
| 项 | 现状 | 问题 |
|---|---|---|
| 技术栈 | Vue 3.5 + Vite 6 + JavaScript,无 TS | 依赖偏旧;无类型约束 |
| UI 库 | Element Plus 与 daisyUI/Tailwind 3 两套并存 | 9 个视图使用 el-* 组件,风格割裂、包体冗余 |
| 目录结构 | components/views 仅按 dashboard 简单分层 | 组件分类不规范,无 api/layouts/types 分层 |
| 构建脚本 | Dockerfile 三阶段,node 阶段未指定 $BUILDPLATFORM |
多架构构建时前端被 QEMU 模拟重复编译,极慢 |
| 依赖声明 | pinia、@iconify/vue 误放 devDependencies | 分类错误 |
| Dockerfile 杂项 | 存在无效的 CMD ["go mod tidy","go mod download"];node:20 基础镜像 |
需清理/升级 |
| 杂项 | 根目录 web/(仅 dist + node_modules,未跟踪) |
疑似误构建产物,暂不动,仅记录 |
二、已确认的决策(2026-08-29,维护者离开前确认)
- 迁移到 TypeScript(全量,含 vue-tsc 类型检查)。
- UI 统一到 Tailwind/daisyUI,移除 Element Plus,
el-*组件全部重写;接受外观变化。 - 不提交:所有改动留在工作区,按阶段推进,不做 git commit。
其余由执行者自行决定的默认约定:
- 依赖一律升到当前最新稳定版(含 Tailwind 4 / daisyUI 5 / Vite 7+ / Pinia 3 等大版本跨越)。
- Element Plus 在被移除前不再投入升级成本(Phase 4 直接删除)。
- 每阶段验收标准:
pnpm build(后期含vue-tsc)通过 + 页面路由/交互逻辑与重构前等价。 - 计划文档放项目根目录
REFACTOR_PLAN.md。
三、阶段计划
| 阶段 | 内容 | 状态 |
|---|---|---|
| Phase 0 | 创建本计划文档 | ✅ 完成 |
| Phase 1 | 依赖全部升级到最新版(Tailwind 4 / daisyUI 5 迁移、pinia 归位 dependencies) | ✅ 完成 |
| Phase 2 | TypeScript 迁移(tsconfig、vue-tsc、全量 .ts/.vue 改写) | ✅ 完成 |
| Phase 3 | 目录结构规范化(api / components / composables / layouts / types / views 分层) | ✅ 完成 |
| Phase 4 | 移除 Element Plus,统一 Tailwind/daisyUI 重写全部组件 | ✅ 完成 |
| Phase 5 | Docker / makefile 构建脚本更新(前端 $BUILDPLATFORM 单次编译) |
✅ 完成 |
| Phase 6 | 最终验证(前端 build + Go embed 编译),收尾文档 | ✅ 完成 |
四、各阶段详细方案
Phase 1 — 依赖升级
vite、@vitejs/plugin-vue、@vitejs/plugin-basic-ssl、vue、vue-router、axios、lucide-vue-next、qrcode.vue、@simplewebauthn/browser、@iconify/vue、@iconify-json/*→ 最新。pinia→ v3 并移入 dependencies;@iconify/vue移入 dependencies。- Tailwind 3 → 4:改用
@tailwindcss/vite插件,删除postcss.config.js/autoprefixer/tailwind.config.js,style.css改为@import "tailwindcss"+@plugin "daisyui"+@theme定义原有 daisyUI 主题集合(light/dark/cupcake/emerald/pastel)。 daisyui→ v5。- element-plus 保持现状(Phase 4 删除)。
- 验收:
pnpm build通过。
Phase 2 — TypeScript 迁移
- 新增
tsconfig.json(bundler 解析策略 +@别名路径映射)、src/vite-env.d.ts、env.d.ts(import.meta.env类型)。 vite.config.js→vite.config.ts;src/**/*.js(router/stores/utils/main)→.ts。- 全部
.vue改<script setup lang="ts">,props/emits/响应式数据补类型。 build脚本加vue-tsc --noEmit类型检查。- 验收:
pnpm build(含 vue-tsc)通过。
Phase 3 — 目录结构规范化
src/
├── api/ # axios 实例 + 各业务接口封装(由 utils/request.js 演进)
├── assets/ # 图片/图标(不变)
├── components/
│ ├── common/ # 通用组件(Toast、Pagination、QRCodeCard、LineSegmentFlow)
│ └── dashboard/ # 仪表盘布局组件(Sidebar、BreadcrumbHeader)
├── composables/ # 组合式函数(useToast 等从 provide/inject 演进)
├── layouts/ # 布局(DashboardLayout 等,如适用)
├── router/ # 路由
├── stores/ # pinia stores
├── styles/ # 全局样式
├── types/ # 共享 TS 类型(API 响应、业务实体)
├── utils/ # 纯工具函数(格式化日期等)
└── views/
├── auth/ # Login、Signup
├── error/ # 404
└── dashboard/ # Overview、Keys、Tokens、Users、Settings、Profile 等
- vite.config 的 manualChunks 别名同步更新。
- 验收:
pnpm build通过,无悬空 import。
Phase 4 — UI 统一到 Tailwind/daisyUI
- 移除
element-plus依赖与main.ts全局注册。 - 重写以下 9 个视图中的
el-*组件(table/dialog/form/select/input/switch/message 等用 daisyUI 组件类 + 自实现交互): Login、Signup、dashboard/{UserView、Settings、KeyView、Profile、TokenNew、KeyNew、UserNew}。 - 顺带规范既有自研组件(Toast、Pagination 等)使用 daisyUI 类。
- 保留既有业务逻辑、字段、接口调用不变。
- 验收:
pnpm build通过;grep el-/element-plus无残留。
Phase 5 — Docker / makefile 构建脚本
deploy/docker/Dockerfile:- 前端阶段
FROM --platform=$BUILDPLATFORM node:22-alpine AS frontend(多架构下只原生编译一次)。 - 后端阶段同样
$BUILDPLATFORM+CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH交叉编译(go.mod 使用纯 Go 的 glebarez/sqlite,可关闭 CGO);如遇阻塞则后端阶段回退为按目标平台编译,仅保留前端优化。 - 删除无效
CMD行;runner 阶段瘦身。
- 前端阶段
makefile:web 目标改用 pnpm(不强制全局安装 pnpm),构建产物位置与 embed 路径核对。- 同步更新
Dockerfile.cn(国内镜像版)保持一致。 - 验收:
docker build本地单架构通过(多架构如环境不允许则用--platform模拟检查语法与目标参数)。
Phase 6 — 最终验证与收尾
frontend: pnpm build(含 vue-tsc)。- 把
frontend/dist放入cmd/openteam/dist后执行go build ./cmd/openteam,确认 embed 成功。 - 更新本文档所有阶段状态与执行记录,列出遗留问题(如
web/目录处置、外观回归点)。
五、执行记录(每阶段完成后追加)
Phase 0 — 计划文档创建(2026-08-29)
- 已确认三项决策:TS 迁移 / 统一 Tailwind-daisyUI / 不提交。
- 摸底结论:前端约 4700 行 Vue;Element Plus 用于 9 个视图;pinia、@iconify/vue 在 devDependencies;
glebarez/sqlite为纯 Go 驱动(Docker 交叉编译可行);本地 Node v25.2.1 / pnpm 10.25.0。 - 发现根目录未跟踪的
web/目录仅含 dist 与 node_modules,疑似误产物,本期不动。
Phase 1 — 依赖升级(2026-08-29)✅
- 升级结果(均为当前最新稳定版):
- dependencies:vue 3.5.42、vue-router 5.3.0(大版本 4→5)、pinia 4.0.3(大版本 2→4,并移入 dependencies)、axios 1.20.0、qrcode.vue 3.10.0、@simplewebauthn/browser 13.3.0、@iconify/vue 5.0.1(移入 dependencies)、@lucide/vue 1.37.0(替代已废弃的 lucide-vue-next)。
- devDependencies:vite 8.2.2(大版本 6→8,构建器为 rolldown)、@vitejs/plugin-vue 6.0.8、@vitejs/plugin-basic-ssl 2.3.0、tailwindcss 4.3.3(大版本 3→4)、@tailwindcss/vite 4.3.3、daisyui 5.7.22(大版本 4→5)、@iconify-json/* 升级。
- 移除:autoprefixer、postcss、tailwind.config.js、postcss.config.js(Tailwind 4 改为 CSS-first 配置)。
- 迁移要点:
style.css改为@import "tailwindcss"+@plugin "daisyui",主题集合保持 light(默认)/dark/cupcake/emerald/pastel。vite.config.js加入@tailwindcss/vite插件;__dirname改为import.meta.dirname(消除 Vite 8 警告)。- package.json 改名为
opencatd-open-frontend;新增pnpm.onlyBuiltDependencies: [esbuild, vue-demi]放行构建脚本。
- 代码适配:新版 Lucide 移除品牌图标,
Profile.vue的<Github>图标改为项目内已有的<img src="/assets/github.svg">(与 Keys/KeyNew/KeyView 用法一致)。 - 验收:
pnpm build通过(4.8s,rolldown 构建)。 - 备注:element-plus 2.9.7 保持旧版未升级(Phase 4 将整体移除);当前 components chunk 406KB 主要来自 Element Plus,Phase 4 后预计大幅缩小。
Phase 2 — TypeScript 迁移(2026-08-29)✅
- 工具链:typescript 6.0.3 + vue-tsc 3.3.11 + @types/node 26.4.0。
- 注:最初装了 typescript 7.0.2(tsgo 原生版),但 vue-tsc 依赖
typescript/lib/tsc导出而 TS7 已移除,故回落到 6.x(当前最新 JS 版)。 - tsconfig:strict 模式、bundler 解析、
@别名(TS6 弃用 baseUrl,改用相对 paths)、types 含 vite/client + node。
- 注:最初装了 typescript 7.0.2(tsgo 原生版),但 vue-tsc 依赖
- 全量转换:
vite.config.ts、src/main.ts、router/stores/utils 共 9 个 JS→TS;19 个.vue全部<script setup lang="ts">。 - 类型设计:
src/types/index.ts:UserInfo / TokenInfo / ApiKey / PasskeyInfo 及各请求 Payload 类型(宽松可选字段 + 索引签名兼容后端松散返回)。src/composables/toast.ts:类型安全的 provide/inject(InjectionKey),替代各视图裸inject('toast')。vue-routerRouteMeta 模块扩展(title/icon/showInSidebar/requiresAuth 等);MenuItem 为可辨识联合。
- package.json:新增
typecheck脚本;build改为vue-tsc --noEmit && vite build。 - 顺带修复的存量 bug(均记录在案):
Keys.vuetoggleSelectAll 引用了不存在的users(应为keys)——运行时全选会抛错。Settings.vueupdateUser 引用了未定义的userStore/userId(复制粘贴残留),提交表单必抛错——改为经authStore.updateProfile更新当前用户。- store 的 catch 中
throw error抛出的是 Ref 对象,Login.vue会把 Ref 显示为[object Object]——加了errMsg()取值辅助。 KeyNew.vue模板绑定了不存在的togglePasswordVisibility(点击报 TypeError)——移除死绑定。User/Keys/UserNew/KeyNew里res.error恒为 undefined(AxiosResponse 无此字段)——改为res.data?.error。TokenNew.vue初始user_id: user.user_id(ComputedRef 上取值恒 undefined)——改为user.value?.user_id。Login.vuerember 记住密码存入布尔被 localStorage 转字符串('true'),统一String()存储。
- 验收:
pnpm build(含 vue-tsc 严格检查)通过。
Phase 3 — 目录结构规范化(2026-08-29)✅
- 最终结构:
src/api/client.ts← utils/request.ts(axios 实例与拦截器;业务接口调用仍保留在 stores 中,作为轻量 API 层,避免无谓 churn,后续可按需下沉到 api/ 各模块)src/components/common/← Toast / Pagination / QRCodeCard / LineSegmentFlowsrc/components/dashboard/保持(Sidebar / BreadcrumbHeader)src/layouts/DashboardLayout.vue← views/DashBoard.vue(本质是布局组件,归位 layouts 层)src/styles/main.css← src/style.csssrc/views/auth/← Login / Signup;src/views/error/NotFound.vue← views/404.vuesrc/views/Home.vue、src/views/dashboard/*保持
- 全部相对路径 import 统一为
@/别名;模板内相对资源路径(../assets/...)统一为@/assets/...。 - vite.config.ts 的 manualChunks 分包规则按新目录核对(components / views-dashboard / stores 三组仍有效)。
- 验收:
pnpm build通过,无悬空 import。
Phase 4 — UI 统一到 Tailwind/daisyUI(2026-08-29)✅
- 摸底修正:Element Plus 实际仅在 3 处使用(main.ts 全局注册 + KeyNew/KeyView 的
el-input-tag),其余视图本就以 daisyUI 为主。 - 变更:
main.ts移除 Element Plus 注册与样式;pnpm remove element-plus。- 新增
src/components/common/TagInput.vue(daisyUI 风格,Enter 添加/逐个删除/Backspace 删末尾/可清空),替换 KeyNew/KeyView 中的el-input-tag。 - 全库 grep 确认无
element-plus/el-*组件残留。
- 收益(构建产物对比):
- 主 CSS:489.6KB → 163.4KB(-67%,主要为 Element Plus 全量样式)
- components JS:405.7KB → 194.7KB(-52%)
- 入口 index JS:617.8KB → 1.3KB(Element Plus 运行时原本在入口包)
- 验收:
pnpm build(含类型检查)通过。
Phase 5 — Docker / makefile 构建脚本(2026-08-29)✅
deploy/docker/Dockerfile重写:- 前端阶段
FROM --platform=$BUILDPLATFORM node:22-alpine:多架构构建时前端只在构建机原生平台编译一次(原先会被 QEMU 模拟在每个目标平台各跑一遍)。 - 后端阶段同样
$BUILDPLATFORM+CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH交叉编译(glebarez/sqlite 纯 Go 驱动,已验证可行),全程零 QEMU。 - 删除了无效且写法错误的
CMD ["go mod tidy","go mod download"];pnpm 固定@10.25.0;pnpm install --frozen-lockfile;runner 阶段补充ca-certificates;修正LABEL anther→author;移除不再需要的cmake。 Dockerfile.cn(国内源版)同步更新。
- 前端阶段
- 新增根目录
.dockerignore(原先缺失:node_modules、dist、.git、web/ 等全部会被拷进构建上下文)。 makefile:web目标:pnpm 按需安装 +--frozen-lockfile,产物干净替换到cmd/openteam/dist(原mv dist ../cmd/openteam/在目标已存在时会错误嵌套一层)。build目标:加CGO_ENABLED=0;upx改为可选(本机未装时跳过,不再中断)。
- package.json 增加
"packageManager": "pnpm@10.25.0":新版 pnpm 默认启用供应链策略(拒装 24h 内发布的包)并不再读取 package.json 的pnpm字段,钉住版本保证容器内外行为一致、可重现。 - 验证:
docker build --target frontend通过,dist 产物完整。docker buildx build --platform linux/amd64,linux/arm64(xbuilder)通过;日志确认 frontend 仅在原生平台执行一次,arm64 后端为交叉编译,无 QEMU。- 本机
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build产出静态 ELF(含嵌入前端)。 make web、make build通过。
Phase 6 — 最终验证与收尾(2026-08-29)✅
pnpm build(vue-tsc 严格类型检查 + vite 构建)通过。.gitignore补充cmd/openteam/dist/(构建产物)与web/(误生成目录,未跟踪)。- 遗留事项(供维护者决策,均不影响本期交付):
frontend/src/utils/format-date.ts、Overview.vue内部仍各自实现了一份formatDateTime,可合并到 utils 统一导入(行为无差异,纯清理)。- CI workflow(
.github/workflows/)引用的./docker/Dockerfile路径早已失效(现为deploy/docker/Dockerfile),且 checkout 的还是 @v3 旧 action——后端/CI 不在本期范围,未改动。 - 依赖升级中未逐项验证运行时 UI 细节(如 daisyUI 4→5 的个别类名行为差异、vue-router 4→5),建议维护者回来后
make web && make build或pnpm dev过一遍登录/令牌/密钥/用户管理页面。 web/目录(仅 dist + node_modules)疑似误构建产物,已加入 .gitignore,确认无用后可删除。
六、后续增量(2026-08-29,维护者返程前追加)
增量 1 — 本地开发体验优化(前后端分离联调)✅
背景:前端构建产物经 //go:embed 嵌入 Go 二进制,本地每改一次前端都要 make web + make build,且没有热更新。
frontend/vite.config.ts:dev server 增加server.proxy,/api代理到本地 Go 后端(默认http://localhost:8080,VITE_DEV_API_TARGET可覆盖)。开发时前端跑在 Vite 上(HMR),接口走代理到后端,无跨域问题。- dev server 默认改为 HTTP(localhost 属浏览器安全上下文,clipboard/Passkey 均可用);需要自签名 HTTPS 时设
VITE_DEV_HTTPS=true恢复 basicSsl。
- dev server 默认改为 HTTP(localhost 属浏览器安全上下文,clipboard/Passkey 均可用);需要自签名 HTTPS 时设
cmd/openteam/main.go://go:embed dist/*→//go:embed all:dist,配合cmd/openteam/dist/.gitkeep占位(已跟踪),dist 没有真实产物时go run ./cmd/openteam也能编译启动——克隆后可直接起后端联调,不必先构建前端。make web移入产物后会补回.gitkeep。makefile新增:make dev-backend:PORT=8080 go run ./cmd/openteam(数据库./db/openteam.db)make dev-frontend:cd frontend && pnpm dev(5173)make dev:$(MAKE) -j2并行启动两者,Ctrl+C 一起退出
frontend/README.md补充开发文档(启动方式、环境变量表)。- 验证:后端 8080 + Vite 5173 同时运行,
curl http://localhost:5173/返回 SPA 页面;经 5173 代理的POST /api/auth/login返回后端真实校验 JSON、GET /api/auth/passkey/begin返回 200,代理链路完整。 - 说明:这是构建基础设施改动,触及
cmd/openteam/main.go一行 embed 指令;后端业务逻辑零改动。生产构建流程不受影响(Docker 内 dist 由前端阶段提供)。
增量 2 — 全站 UI/UX 重设计(web-design-guidelines)✅
依据:Vercel Web Interface Guidelines(~/.agents/skills/web-design-guidelines 拉取的最新规则集)。先对全部页面截图建立基线,再逐页重写模板;业务逻辑、接口调用、路由全部未动。
- 设计系统基础(
styles/main.css+index.html):- 深浅色
color-scheme跟随主题;<meta name="theme-color">;内联脚本恢复上次主题(不再每次刷新回 emerald)。 - 全局
:focus-visible焦点环、touch-action: manipulation、prefers-reduced-motion全局降级、.modal-box防滚动穿透。 - 覆写 emerald 主题圆角令牌(默认 selector 圆角 1rem 使小复选框渲染成正圆的 bug)。
- 深浅色
- 壳层:侧栏启用 daisyUI 5
menu-active高亮 + sticky;顶栏重排(侧栏开关带 aria-pressed、主题切换持久化 localStorage、用户菜单头像+用户名);主区限宽 max-w-6xl。 - 页面模式统一:
面包屑 + 大标题 → 描述 + 主操作 → 卡片内容;列表页统一工具栏/表格/空状态/分页(空数据隐藏分页);表单统一分区标题、label/控件绑定、required 标记、示例占位符、提交按钮 spinner。 - 主要变更:
- Overview:深色渐变横幅改为品牌 primary→secondary 渐变;信息卡由 badge 滥用改为 dl 键值布局(仅角色/状态保留 badge);时间 tabular-nums。
- Tokens/Keys/Users 列表:空状态(图标+文案+CTA)、行操作按钮 aria-label、状态筛选改为带计数的下拉、移除两个死的 Filter 输入框、批量操作菜单重排。
- 弹窗表单(TokenNew/KeyNew/UserNew):去掉 min-h-screen 包裹,适配弹窗容器。
- 详情页(KeyView/UserView):头像+徽章头部、分区表单、tokens 表格;加载态明确。
- Profile/Settings:分区卡片(基本信息/密码/Passkeys/关联账号),提交加 spinner。
- Login/Signup:实体主按钮、内联错误 alert(role=alert)、autocomplete(username/current-password/new-password)、死链"Forgot password?"移除、密码不一致内联提示。
- Home:导航栏 Star 徽标 + Open Dashboard 主 CTA,hero 文案重写,endpoint 复制组加 label,图片补尺寸。
- 404:品牌化布局 + 具体文案("doesn't exist or has been moved")。
- Toast:
aria-live="polite"+ toast-top/end 定位;Pagination:join 样式 + Showing x–y of z + tabular-nums。
- 顺带修复:DashboardLayout
if (!userInfo)恒真导致刷新后头部用户名丢失(改为!authStore.user)。 - 验证:
pnpm build(vue-tsc 严格检查)通过;本地起前后端后逐页浏览器截图回归(Users/Overview/Tokens/新建弹窗/Keys 空状态/Profile/404/Home/Login)视觉与交互正常;复选框圆角修复经计算样式确认(16px→8px)。 - 已知取舍:破坏性操作沿用原生
confirm()(满足"需确认"要求,后续可换主题化 modal);列表筛选/分页尚未同步到 URL query(指南建议,列为后续项);"Forgot password?" 为死链已移除。 - 补充(维护者反馈):Overview 横幅恢复随时间段变化的配色(原版行为),四段式与新版式协调——深夜 slate-900→indigo-950、早晨 sky-600→amber-400、白天 blue-600→cyan-400、夜晚 slate-900→indigo-950;白色文字置于渐变左侧深色端保证对比度。顺带修复原版问候语 bug:0-6 点原显示"早上好",现对齐四段为"夜深了"。
增量 3 — 主题切换(浅色 / 深色 / 自动)✅
- 新增
src/composables/theme.ts:偏好三态light | dark | auto(浅色映射品牌 emerald 主题),localStorage 持久化(keytheme),auto 模式监听prefers-color-scheme实时跟随系统切换;模块级单例状态,主页与仪表盘共享。 index.html内联脚本同步三态逻辑(含 auto 解析),首屏不闪烁。- 主页导航栏与仪表盘顶栏均提供主题下拉(太阳/月亮/显示器图标随当前偏好变化,当前项
menu-active高亮);仪表盘原先的二态硬切换按钮升级为同一三选下拉,避免两套主题逻辑互相覆盖。 - 默认偏好为
auto(首次访问跟随系统);旧存储值emerald不再有效,自动回落 auto。 - 验证:
pnpm build通过;浏览器实测浅色↔深色↔自动即时生效、data-theme与 localStorage 值正确、刷新后保持、auto 按系统深色解析为 dark;主页与仪表盘主题共享一致。
增量 4 — 导航栏按角色分区重设计(参考维护者提供的双栏设计稿)✅
- 信息架构对齐设计稿:导航拆为控制台(所有用户:仪表盘 / API 密钥 / 账户设置)与管理后台(role ≥ 10:用户管理 / 渠道管理)两个区域,按当前路由区域(
/dashboard/manager/*)切换显示;底部互切入口——控制台区显示「管理后台 →」(仅管理员),后台区显示「← 返回控制台」。 router_menu.ts重写:弃用递归菜单生成器,改为显式两套菜单数组;路由 meta 标题中文化(仪表盘 / API 密钥 / 用户管理 / 渠道管理 / 账户设置等)。BreadcrumbHeader增加路由路径→中文标题映射,面包屑与页面标题随之中文化(此前按英文路径段拼接)。- 与设计稿的差异(页面对应关系):API 密钥→个人 Tokens 页;渠道管理→上游 Provider Keys 页;设计稿中的用量明细/用量统计/模型定价/系统配置暂无对应页面,未做死链,留作后续功能。
- 验证:
pnpm build通过;浏览器实测 admin 视角(控制台菜单 + 底部管理后台入口 → 后台菜单 + 返回控制台,高亮正确)与普通用户视角(注册 member 账号实测:仅控制台菜单,管理后台入口数量为 0);中文面包屑生效。 - 补充(维护者反馈):「API 密钥」菜单项与页面标题改名为 API Keys;面包屑重设计——废弃路径段拼接,改为按路由名显式定义层级:顶级页面(仪表盘/API Keys/账户设置)不显示面包屑仅保留标题,管理后台列表页显示「管理后台」一级,详情页显示「管理后台 / 列表页」两级(末级为当前页标题),标题统一取自定义 title 或路由 meta.title。
- 补充(交互收尾):移动端抽屉在路由切换后自动收起(router.afterEach);顶栏主题/个人下拉为焦点展开型,选择后主动移除焦点收起菜单,个人菜单按钮补 aria-expanded 语义。注:DashboardLayout 模板含维护者手动增强的个人菜单(身份信息头 + 管理后台入口),脚本已按模板对齐(handleMenuAction / isAdminUser)。
增量 5 — 个人下拉修复与触屏可用性(维护者反馈)✅
- 问题 1(内容不对):身份信息行的
email || '@username'回退会显示伪社交句柄,且已在管理后台时仍显示「管理后台」入口。修复:第二行仅在存在邮箱时显示邮箱、有显示名时显示@用户名、否则不显示;名称行追加角色徽章(Root/Admin/User);「管理后台」入口在后台区域隐藏(isAdminUser && !isAdminArea)。 - 问题 2(手机点退出无反应):daisyUI CSS 下拉依赖焦点展开,触屏点击菜单项时按钮失焦、下拉先于 click 关闭导致点击落空。修复:主题与个人下拉改为状态驱动(
dropdown-openclass +v-if遮罩点击关闭 + Escape 关闭 + 路由切换关闭),互斥打开;主页主题下拉同步修复。 - 验证:
pnpm build通过;桌面实测下拉内容(root + Root 徽章 + @admin,菜单项完整);移动端 390px 实测点「退出登录」成功跳转 /login 且 token 清除;随后已恢复 admin 会话与桌面视口。 - 补充(维护者反馈):个人下拉内的
<hr>分割线被 daisyUI menu 的通用子元素样式选中(cursor: pointer + hover 背景,可点击),已为其 li 加pointer-events-none select-none,实测恢复默认光标且不可交互。
增量 6 — 主按钮统一黑白配色(维护者反馈)✅
- 背景:daisyUI dark 主题的 primary 为紫色,普通主按钮(btn-primary)在深色模式下显示为紫底。
- 方案:
main.css覆写.btn-primary的 daisyUI 颜色变量(--btn-color/--btn-fg)——浅色主题黑底白字(#171717/#fff,hover 纯黑)、深色主题白底黑字(#fff/#171717,hover 浅灰)。仅影响 btn-primary;success/error/warning/outline/ghost 等特殊按钮与链接、开关、焦点环均保持原样。 - 验证:
pnpm build通过;浏览器实测深色(白底黑字 New Token)与浅色(黑底白字 Log In)两种主题,特殊按钮未受影响;已恢复维护者的 auto 主题偏好与 admin 会话。
增量 7 — Toast 重写:多实例堆叠(维护者反馈)✅
- 背景:原实现为串行队列(processQueue 一次展示一条),连续操作时提示互相阻塞。
- daisyUI 的
toast组件本身只负责定位与堆叠(容器内多个alert自动纵向排列),队列/自动消失/动画需应用层实现——已按此重写:composables/toast.ts:模块级响应式toasts列表,setToast(message, type?, duration?)推入带唯一 id 的条目并定时自动移除(默认 3s);useToast()签名不变,13 个调用视图零改动;移除原 provide/inject 方案。Toast.vue:daisyUItoast toast-top toast-end容器 +TransitionGroup进出场动画(仅 transform/opacity,配合全局 reduced-motion 降级)、每条带关闭按钮(aria-label)、容器aria-live="polite"。
- 验证:
pnpm build通过;浏览器实测连续触发两条 toast 同时堆叠展示、3s 后全部自动消失。
增量 8 — dev 镜像构建脚本(多平台)✅
- 新增
deploy/docker/build-dev.sh+make image-dev:- 默认多平台
linux/amd64,linux/arm64构建并推送(自动创建缺失的 buildx 容器构建器);PUSH=0退化为本机架构构建并--load到本地。 - 标签:
dev、dev-<短SHA>、dev-<YYYYMMDD>(REGISTRY_IMAGE/PLATFORMS/BUILDER/DOCKERFILE均可用环境变量覆盖)。 - 推送时附带 registry inline cache(
--cache-from/--cache-to type=inline)加速后续 dev 构建。
- 默认多平台
- 验证:
PUSH=0端到端实测通过(容器内前端构建 + Go 交叉编译 + upx 压缩 31.7MB→11.8MB + 本地加载);镜像冒烟测试/:200、/api/*:200。