From ffa869e08639eb72416305f86fad9ecde18f27c6 Mon Sep 17 00:00:00 2001 From: zwt13703 Date: Wed, 1 Jul 2026 20:36:04 +0800 Subject: [PATCH] feat: add interactive left menu --- .../AI文档模板系统-像素级任务清单-20260701.md | 6 +- docs/tasks/task_detail_2026_07_01.md | 11 ++ .../src/components/TemplateEdit/LeftMenu.vue | 177 +++++++++++++++--- 3 files changed, 168 insertions(+), 26 deletions(-) diff --git a/docs/AI文档模板系统-像素级任务清单-20260701.md b/docs/AI文档模板系统-像素级任务清单-20260701.md index 419df4a..c287c35 100644 --- a/docs/AI文档模板系统-像素级任务清单-20260701.md +++ b/docs/AI文档模板系统-像素级任务清单-20260701.md @@ -57,9 +57,9 @@ | 038 | 实现预览区 shell 组件(A4 纸效果) | 前端 | 0.25d | ✅ 已完成 | | 039 | 实现结构树 shell 组件 | 前端 | 0.25d | ✅ 已完成 | | | **左侧菜单** | | | | -| 040 | 菜单数据模型(JSON)+ 子菜单配置 | 前端 | 0.25d | ⏳ 未完成 | -| 041 | 菜单展开/收起交互 + 箭头旋转动画 | 前端 | 0.25d | ⏳ 未完成 | -| 042 | 菜单选中高亮(蓝色左侧竖条) | 前端 | 0.25d | ⏳ 未完成 | +| 040 | 菜单数据模型(JSON)+ 子菜单配置 | 前端 | 0.25d | ✅ 已完成 | +| 041 | 菜单展开/收起交互 + 箭头旋转动画 | 前端 | 0.25d | ✅ 已完成 | +| 042 | 菜单选中高亮(蓝色左侧竖条) | 前端 | 0.25d | ✅ 已完成 | | | **顶部工具栏** | | | | | 043 | 面包屑导航渲染 | 前端 | 0.25d | ⏳ 未完成 | | 044 | 模板名称 + 版本号标签展示 | 前端 | 0.25d | ⏳ 未完成 | diff --git a/docs/tasks/task_detail_2026_07_01.md b/docs/tasks/task_detail_2026_07_01.md index 57e4ad8..b35176f 100644 --- a/docs/tasks/task_detail_2026_07_01.md +++ b/docs/tasks/task_detail_2026_07_01.md @@ -72,3 +72,14 @@ 6. 新增 `StructureTree.vue`,实现结构树 shell。 7. 增加 `/templates/:id/edit` 路由,并执行前端构建和浏览器 DOM 检查。 - **执行结果**: 完成任务 034-039,编辑页基础四栏工作台已可访问。 + +## 会话 ID: 20260701-left-menu +- [2026-07-01 20:35:45] +- **执行原因**: 按任务清单继续完成左侧菜单 040-042。 +- **执行过程**: + 1. 将左侧菜单改为 JSON 数据模型驱动,包含一级菜单和子菜单配置。 + 2. 增加分组展开/收起状态,点击一级菜单可切换子菜单显示。 + 3. 增加箭头旋转动画,展示当前展开状态。 + 4. 增加选中状态管理,子菜单选中后显示高亮样式。 + 5. 执行前端构建和浏览器交互检查。 +- **执行结果**: 完成任务 040-042,左侧菜单支持数据驱动、展开收起与选中高亮。 diff --git a/frontend/src/components/TemplateEdit/LeftMenu.vue b/frontend/src/components/TemplateEdit/LeftMenu.vue index 3088570..0e4314b 100644 --- a/frontend/src/components/TemplateEdit/LeftMenu.vue +++ b/frontend/src/components/TemplateEdit/LeftMenu.vue @@ -1,10 +1,65 @@ @@ -71,11 +140,8 @@ import { padding: 8px 0; } -.menu-group-title { - padding: 8px 16px 4px; - color: var(--c-text-muted); - font-size: 11px; - font-weight: 500; +.menu-group { + margin-bottom: 2px; } .menu-item { @@ -92,6 +158,12 @@ import { text-align: left; } +.menu-item span { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + .menu-item:hover { color: var(--c-text); background: var(--c-surface-soft); @@ -113,4 +185,63 @@ import { background: var(--c-primary); content: ""; } + +.menu-arrow { + margin-left: auto; + color: var(--c-text-muted); + font-size: 12px; + transition: transform 0.18s ease; +} + +.menu-arrow.open { + transform: rotate(180deg); +} + +.sub-menu { + max-height: 0; + overflow: hidden; + transition: max-height 0.22s ease; +} + +.sub-menu.open { + max-height: 220px; +} + +.sub-menu-item { + display: flex; + align-items: center; + width: 100%; + gap: 8px; + padding: 6px 16px 6px 32px; + border: 0; + color: var(--c-text-muted); + background: transparent; + cursor: pointer; + text-align: left; +} + +.sub-menu-item:hover { + color: var(--c-text); + background: var(--c-surface-soft); +} + +.sub-menu-item.active { + color: var(--c-primary); + font-weight: 500; +} + +.sub-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--c-text-muted); +} + +.sub-dot.done { + background: var(--c-success); +} + +.sub-dot.empty { + background: var(--c-border); +}