# 工作台模块项目计划(tools/workbench) > 独立完整项目流程:调研 ✓ → 设计规范 ✓ → 本计划 → 实现 → 审查 → 验证。 > 布局调研:lib-1(VSCode 四层 / Dashy Workspace / Vivaldi Web Panels / Arc pinned / Homepage groups + iframe 技术建议)。 > 设计规范:frontend-pack/design skill(8px 网格、语义色 token、层次/留白/焦点环/深浅色/加载空错误态)。 ## 1. 模块定位 「面板工作台」:浏览器式多面板聚合界面(左侧侧边栏 + 顶部工具栏 + 右侧 iframe 内容区),叠加密码库快捷取用。仅管理员(adminOnly)可进入。 ## 2. 技术方案 | 项 | 决定 | |---|---| | 风格 | **MUI**(与后台一致,MD3 主题复用 frontend/src/admin/theme.js) | | 路由 | 独立页面 `/workbench`(React Router,挂管理后台路由树外或独立 BrowserRouter 区——用后台同一入口 admin 应用内加路由最简,basename /admin 下 `/admin/workbench`?——**决定:独立入口**(admin.html 已有),路由挂 `/admin/workbench`,与 Dashboard 等并列,顶栏入口按钮跳转;整页全屏布局不带 AdminLayout 侧栏(工作台自带侧边栏) | | 代码位置 | `frontend/src/tools/workbench/`(独立工具区,页面+组件+密码库组件+工具函数全在这,方便后续升级) | | 鉴权 | 入口守卫:无 token → 跳 /login.html;非 admin → 403 提示返回(复用后台守卫模式) | | 数据 | admin_links API(复用 frontend/src/api/adminLinks.js)+ passwords API(复用) | | proxy | `/api/proxy/fetch?url=&token=`(iframe query token,复用 Embed.jsx 的 needsProxy 逻辑) | ## 3. 文件结构 ``` frontend/src/tools/workbench/ ├── Workbench.jsx # 页面入口(路由挂载点 + 鉴权守卫 + 布局组装) ├── components/ │ ├── Toolbar.jsx # 顶部工具栏(◀▶↻ 地址栏 搜索 添加 密码库 侧栏开关 返回) │ ├── Sidebar.jsx # 左侧边栏(固定区 + 分组列表 + 折叠 + 拖拽调宽可选) │ ├── PanelFrame.jsx # iframe 内容区(加载态/超时/失败回退/LRU 保留) │ ├── AddPanelDialog.jsx # 添加面板弹窗(URL/命名/分组/图标 + 打开方式) │ └── VaultDrawer.jsx # 密码库抽屉(PIN 解锁/搜索/复制,MUI) ├── hooks/ │ ├── usePanels.js # 面板数据/打开集合/历史栈/持久化(localStorage) │ └── useVault.js # 密码库解锁状态/条目加载(复用 passwords API) └── index.js # 模块导出(便于未来升级替换) ``` ## 4. 功能清单 ### 核心(必须) - [ ] 鉴权守卫(adminOnly) - [ ] 工具栏:◀ 后退 / ▶ 前进(当前面板历史栈)、↻ 刷新、只读地址栏、🔍 搜索(面板名/URL/分组)、+添加、🔑 密码库、侧边栏折叠、返回前台 - [ ] 侧边栏:admin_links 按 category 分组 + 固定区(pin),点击切换,当前项左侧 2px primary 指示条 + surface-container 底(MUI 化:ListItemButton selected 态) - [ ] iframe 区:懒加载(首次激活创建)、display:none 切换保留状态、**超时+load 双保险加载态**、失败(超时/空白启发式)显示「在新标签打开」回退按钮 - [ ] 打开方式:内嵌(默认)/ 新标签(target=_blank)/ 弹窗(modal)——面板项右键或添加时选择,存面板设置 - [ ] 添加面板弹窗:URL + 标题 + 分组 + 图标(favicon 预览)+ 打开方式;保存到 admin_links(复用现有 API) - [ ] localStorage 持久化:打开面板集合、当前面板、历史栈、侧边栏折叠态 - [ ] 密码库抽屉:PIN 解锁(复用 /api/passwords/unlock,服务端会话互通)→ 条目列表(标题/用户名)+ 搜索 + 详情(密码明文)+ 一键复制(clipboard);未设 PIN 引导去 /passwords.html;只读取用不编辑 - [ ] 空态/加载态/错误态:无面板引导添加、加载骨架、加载失败重试 ### 进阶(尽力) - [ ] LRU iframe 保留(最多 3 个活跃,超出销毁最久未用,记录 URL 重建) - [ ] 每面板定时刷新(可选 30s/5min/30min) - [ ] 侧边栏拖拽调宽 + 记忆 - [ ] 分组折叠状态持久化 ## 5. 设计规范(design skill + 调研要点) - 8px 网格间距;一屏内不超过 2 种圆角(MUI 默认 8px/20px pill) - 语义色 token(MD3):工具栏/侧边栏 surface-container、选中 primary-container、hover surface-variant - 选中态:左侧 2px primary 指示条(VSCode 模式)或 MUI selected 态,二选一统一 - 深色模式默认适配(后台已有 data-theme 机制) - 焦点环(focus-visible)、语义 HTML(nav/main/aside/button)、触控目标 ≥40px - 加载态用骨架/居中 spinner;空态带图标+CTA;错误态带重试 - iframe title 属性必须;allow 权限策略按面板 - 工具栏高度 48-56px、侧边栏默认 240px(可 180-360 拖拽) ## 6. 实施与质量流程 1. 派 designer 按本计划实现(一个会话,MUI + 复用后台主题/api) 2. ora 审查(鉴权/安全/iframe 处理/状态管理/无障碍)→ 修复 3. 验证:npm run build + 后台入口跳转 + admin 权限拦截 + 面板切换/proxy/密码库全链路冒烟 4. commit + 用户验收 ## 7. 验收标准 - [ ] 非 admin 无法进入(无 token 跳登录、非 admin 403) - [ ] 面板分组/固定/切换/关闭/添加/持久化全部可用 - [ ] proxy 面板正常嵌入;X-Frame-Options 拒绝的面板有回退提示 - [ ] 密码库解锁→搜索→复制链路通(与服务端会话互通) - [ ] 深浅色、320/768/1440 三档响应式正常 - [ ] build 通过、无 console 错误