303 lines
28 KiB
Markdown
303 lines
28 KiB
Markdown
# 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,维护者离开前确认)
|
||
|
||
1. **迁移到 TypeScript**(全量,含 vue-tsc 类型检查)。
|
||
2. **UI 统一到 Tailwind/daisyUI**,移除 Element Plus,`el-*` 组件全部重写;接受外观变化。
|
||
3. **不提交**:所有改动留在工作区,按阶段推进,不做 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。
|
||
- 全量转换:`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-router` RouteMeta 模块扩展(title/icon/showInSidebar/requiresAuth 等);MenuItem 为可辨识联合。
|
||
- package.json:新增 `typecheck` 脚本;`build` 改为 `vue-tsc --noEmit && vite build`。
|
||
- 顺带修复的存量 bug(均记录在案):
|
||
1. `Keys.vue` toggleSelectAll 引用了不存在的 `users`(应为 `keys`)——运行时全选会抛错。
|
||
2. `Settings.vue` updateUser 引用了未定义的 `userStore`/`userId`(复制粘贴残留),提交表单必抛错——改为经 `authStore.updateProfile` 更新当前用户。
|
||
3. store 的 catch 中 `throw error` 抛出的是 Ref 对象,`Login.vue` 会把 Ref 显示为 `[object Object]`——加了 `errMsg()` 取值辅助。
|
||
4. `KeyNew.vue` 模板绑定了不存在的 `togglePasswordVisibility`(点击报 TypeError)——移除死绑定。
|
||
5. `User/Keys/UserNew/KeyNew` 里 `res.error` 恒为 undefined(AxiosResponse 无此字段)——改为 `res.data?.error`。
|
||
6. `TokenNew.vue` 初始 `user_id: user.user_id`(ComputedRef 上取值恒 undefined)——改为 `user.value?.user_id`。
|
||
7. `Login.vue` rember 记住密码存入布尔被 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 / LineSegmentFlow
|
||
- `src/components/dashboard/` 保持(Sidebar / BreadcrumbHeader)
|
||
- `src/layouts/DashboardLayout.vue` ← views/DashBoard.vue(本质是布局组件,归位 layouts 层)
|
||
- `src/styles/main.css` ← src/style.css
|
||
- `src/views/auth/` ← Login / Signup;`src/views/error/NotFound.vue` ← views/404.vue
|
||
- `src/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/`(误生成目录,未跟踪)。
|
||
- 遗留事项(供维护者决策,均不影响本期交付):
|
||
1. `frontend/src/utils/format-date.ts`、`Overview.vue` 内部仍各自实现了一份 `formatDateTime`,可合并到 utils 统一导入(行为无差异,纯清理)。
|
||
2. CI workflow(`.github/workflows/`)引用的 `./docker/Dockerfile` 路径早已失效(现为 `deploy/docker/Dockerfile`),且 checkout 的还是 @v3 旧 action——后端/CI 不在本期范围,未改动。
|
||
3. 依赖升级中未逐项验证运行时 UI 细节(如 daisyUI 4→5 的个别类名行为差异、vue-router 4→5),建议维护者回来后 `make web && make build` 或 `pnpm dev` 过一遍登录/令牌/密钥/用户管理页面。
|
||
4. `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。
|
||
- `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 持久化(key `theme`),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-open` class + `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`:daisyUI `toast 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`。
|