diff --git a/docs/superpowers/plans/2026-03-30-layout-redesign.md b/docs/superpowers/plans/2026-03-30-layout-redesign.md new file mode 100644 index 0000000..c8ea482 --- /dev/null +++ b/docs/superpowers/plans/2026-03-30-layout-redesign.md @@ -0,0 +1,969 @@ +# Layout结构优化实施计划 + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 将UmiJS layout从mix模式优化为side模式,实现左右分栏布局,白色主题风格,侧边栏可折叠。 + +**Architecture:** +1. 修改UmiJS layout配置,从'mix'改为'side'模式 +2. 自定义Header渲染组件,保持用户信息功能 +3. 自定义Logo渲染组件,实现展开/折叠智能显示 +4. 更新token配置实现白色主题 + +**Tech Stack:** UmiJS Max, Ant Design Pro Layout, React, TypeScript + +--- + +## 文件结构 + +**修改的文件:** +- `src/common/libs/umi/layoutConfig.tsx` - 核心layout配置 + +**新建的文件:** +- `src/common/components/layout/CustomHeader.tsx` - 自定义Header组件 +- `src/common/components/layout/CustomLogo.tsx` - 自定义Logo组件 +- `src/common/components/layout/index.ts` - 导出新组件 + +--- + +### Task 1: 备份现有layout配置 + +**Files:** +- Copy: `src/common/libs/umi/layoutConfig.tsx` → `src/common/libs/umi/layoutConfig.tsx.backup` + +- [ ] **Step 1: 创建备份文件** + +```bash +cp src/common/libs/umi/layoutConfig.tsx src/common/libs/umi/layoutConfig.tsx.backup +``` + +- [ ] **Step 2: 验证备份成功** + +```bash +ls -lh src/common/libs/umi/layoutConfig.tsx.backup +``` + +Expected: 输出文件大小和日期 + +- [ ] **Step 3: 提交备份** + +```bash +git add src/common/libs/umi/layoutConfig.tsx.backup +git commit -m "chore: backup layoutConfig before refactoring" +``` + +--- + +### Task 2: 修改layout基础配置 + +**Files:** +- Modify: `src/common/libs/umi/layoutConfig.tsx:31-78` + +- [ ] **Step 1: 修改layout模式和基础配置** + +将 `layout: 'mix'` 改为 `layout: 'side'`,移除logo配置(稍后自定义): + +```typescript +export const LayoutConfig: RuntimeConfig['layout'] = () => { + const { snap } = useMyState(); + + return { + title: snap.session.campus?.name ?? '物业管理系统', + logo: false, // 禁用默认logo,使用自定义 + layout: 'side', // 从 'mix' 改为 'side' + colorPrimary: '#1890ff', + siderWidth: 220, + pure: history.location.pathname === '/login', + avatarProps: { + render: () => , + }, + collapsedButtonRender: false, + // 保持其他配置不变... + }; +}; +``` + +- [ ] **Step 2: 运行应用查看变化** + +```bash +npm run dev +``` + +Expected: 应用启动,layout已切换为side模式 + +- [ ] **Step 3: 提交配置修改** + +```bash +git add src/common/libs/umi/layoutConfig.tsx +git commit -m "refactor: change layout mode from mix to side" +``` + +--- + +### Task 3: 更新主题token为白色主题 + +**Files:** +- Modify: `src/common/libs/umi/layoutConfig.tsx:50-61` + +- [ ] **Step 1: 替换token配置** + +将现有的深色主题token替换为白色主题: + +```typescript +export const LayoutConfig: RuntimeConfig['layout'] = () => { + const { snap } = useMyState(); + + return { + // ... 前面的配置保持不变 + + token: { + bgLayout: '#f5f5f5', // 浅灰布局背景 + header: { + colorBgHeader: '#ffffff', // 白色header背景 + colorHeaderTitle: '#262626', // 深色标题文字 + colorTextRightActionsItem: '#595959', // 深色操作文字 + heightLayoutHeader: 64, // Header高度64px + }, + sider: { + colorMenuBackground: '#ffffff', // 白色菜单背景 + colorMenuText: '#595959', // 深色菜单文字 + colorMenuTextSelected: '#1890ff', // 激活菜单文字蓝色 + colorMenuItemBgSelected: '#e6f7ff', // 激活菜单背景浅蓝 + colorMenuDivider: '#f0f0f0', // 分割线颜色 + }, + }, + + // ... 后面的配置保持不变 + }; +}; +``` + +- [ ] **Step 2: 检查样式变化** + +在浏览器中查看header和侧边栏背景是否已变为白色 + +Expected: Header和侧边栏背景为白色 + +- [ ] **Step 3: 提交token配置** + +```bash +git add src/common/libs/umi/layoutConfig.tsx +git commit -m "style: update theme tokens to white color scheme" +``` + +--- + +### Task 4: 创建CustomLogo组件 + +**Files:** +- Create: `src/common/components/layout/CustomLogo.tsx` + +- [ ] **Step 1: 创建CustomLogo组件文件** + +```typescript +import React from 'react'; +import { MyIcons, MyIconsType } from '@/common'; + +interface CustomLogoProps { + collapsed: boolean; +} + +export const CustomLogo: React.FC = ({ collapsed }) => { + return ( +
+
+ +
+ {!collapsed && ( +
+ {collapsed ? '' : '物业管理系统'} +
+ )} +
+ ); +}; +``` + +- [ ] **Step 2: 添加组件样式** + +在文件末尾添加样式: + +```typescript +export const CustomLogo: React.FC = ({ collapsed }) => { + // ... 组件代码保持不变 +}; + +// 添加样式定义 +export const customLogoStyles = ` + .custom-logo { + display: flex; + align-items: center; + height: 64px; + padding: 0 16px; + border-bottom: 1px solid #f0f0f0; + transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1.000); + } + + .custom-logo .logo-icon { + font-size: 32px; + min-width: 32px; + display: flex; + align-items: center; + justify-content: center; + } + + .custom-logo .logo-text { + margin-left: 12px; + font-size: 16px; + font-weight: 600; + color: #262626; + white-space: nowrap; + opacity: 1; + transition: opacity 0.2s; + } + + /* 折叠状态下的样式调整 */ + .ant-layout-sider-collapsed .custom-logo { + padding: 0; + justify-content: center; + } + + .ant-layout-sider-collapsed .custom-logo .logo-text { + display: none; + } +`; +``` + +- [ ] **Step 3: 提交CustomLogo组件** + +```bash +git add src/common/components/layout/CustomLogo.tsx +git commit -m "feat: add CustomLogo component with collapse support" +``` + +--- + +### Task 5: 创建CustomHeader组件 + +**Files:** +- Create: `src/common/components/layout/CustomHeader.tsx` + +- [ ] **Step 1: 创建CustomHeader组件文件** + +```typescript +import React from 'react'; +import { Layout, Dropdown, Avatar, Space } from 'antd'; +import type { MenuProps } from 'antd'; +import { AvatarProps } from './AvatarProps'; +import { useMyState } from '@/common'; + +const { Header } = Layout; + +interface CustomHeaderProps { + collapsed?: boolean; + toggle?: () => void; +} + +export const CustomHeader: React.FC = ({ collapsed, toggle }) => { + const { snap } = useMyState(); + + const menuItems: MenuProps['items'] = [ + { + key: 'profile', + label: '个人资料', + icon: 👤, + }, + { + key: 'password', + label: '修改密码', + icon: 🔒, + }, + { + type: 'divider', + }, + { + key: 'logout', + label: '退出登录', + icon: 🚪, + danger: true, + onClick: () => { + // 添加退出登录逻辑 + localStorage.removeItem('token'); + window.location.href = '/login'; + }, + }, + ]; + + return ( +
+ {/* 左侧区域 */} +
+ {/* 可以添加面包屑导航或其他内容 */} +
+ + {/* 右侧用户信息区域 */} +
+ +
+ +
+
+
+
+ ); +}; +``` + +- [ ] **Step 2: 添加Header样式** + +在文件末尾添加样式定义: + +```typescript +export const CustomHeader: React.FC = ({ collapsed, toggle }) => { + // ... 组件代码保持不变 +}; + +// 添加样式定义 +export const customHeaderStyles = ` + .custom-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 24px; + background: #ffffff !important; + border-bottom: 1px solid #f0f0f0; + line-height: 64px; + } + + .custom-header .header-left { + flex: 1; + } + + .custom-header .header-right { + display: flex; + align-items: center; + gap: 16px; + } + + .custom-header .header-right > div { + display: flex; + align-items: center; + transition: opacity 0.2s; + } + + .custom-header .header-right > div:hover { + opacity: 0.8; + } +`; +``` + +- [ ] **Step 3: 提交CustomHeader组件** + +```bash +git add src/common/components/layout/CustomHeader.tsx +git commit -m "feat: add CustomHeader component with user dropdown" +``` + +--- + +### Task 6: 创建组件导出索引 + +**Files:** +- Create: `src/common/components/layout/index.ts` + +- [ ] **Step 1: 创建index导出文件** + +```typescript +export { CustomLogo } from './CustomLogo'; +export { CustomHeader } from './CustomHeader'; +export { default as AvatarProps } from './AvatarProps'; +``` + +- [ ] **Step 2: 验证导出正确** + +```bash +npm run build +``` + +Expected: 构建成功,无TypeScript错误 + +- [ ] **Step 3: 提交导出文件** + +```bash +git add src/common/components/layout/index.ts +git commit -m "chore: add layout components export index" +``` + +--- + +### Task 7: 在layoutConfig中集成自定义组件 + +**Files:** +- Modify: `src/common/libs/umi/layoutConfig.tsx:1-80` + +- [ ] **Step 1: 导入自定义组件** + +在文件顶部添加导入: + +```typescript +// import Logo from '@/assets/bitcoin.webp'; +import { MyIcons, MyIconsType, PermissionsType, useMyState } from '@/common'; +import { Link, RuntimeConfig, history } from '@umijs/max'; +import AvatarProps from '../../components/layout/AvatarProps'; +import { CustomHeader, CustomLogo } from '@/common/components/layout'; // 新增 +``` + +- [ ] **Step 2: 添加自定义渲染函数** + +在LayoutConfig函数返回对象中添加headerRender和logoRenderer: + +```typescript +export const LayoutConfig: RuntimeConfig['layout'] = () => { + const { snap } = useMyState(); + + return { + title: snap.session.campus?.name ?? '物业管理系统', + logo: false, + layout: 'side', + colorPrimary: '#1890ff', + siderWidth: 220, + pure: history.location.pathname === '/login', + + // 新增:自定义Header渲染 + headerRender: () => { + return ; + }, + + // 新增:自定义Logo渲染 + logoRenderer: (collapsed: boolean) => { + return ; + }, + + avatarProps: { + render: () => , + }, + collapsedButtonRender: false, + + token: { + bgLayout: '#f5f5f5', + header: { + colorBgHeader: '#ffffff', + colorHeaderTitle: '#262626', + colorTextRightActionsItem: '#595959', + heightLayoutHeader: 64, + }, + sider: { + colorMenuBackground: '#ffffff', + colorMenuText: '#595959', + colorMenuTextSelected: '#1890ff', + colorMenuItemBgSelected: '#e6f7ff', + colorMenuDivider: '#f0f0f0', + }, + }, + + menuItemRender: (item, dom) => {dom}, + + menu: { + params: snap.session.permissions, + request: async () => { + let objjs: any = []; + snap.session.permissions?.forEach((res: any) => { + objjs.push(res); + }); + let data = objjs.sort((a: any, b: any) => { + return a._lft - b._lft; + }); + const menus = loopMenu(data); + return Promise.resolve(menus); + }, + }, + + unAccessible:
unAccessible
, + }; +}; +``` + +- [ ] **Step 3: 测试自定义组件渲染** + +```bash +npm run dev +``` + +Expected: 应用启动,自定义Logo和Header正确显示 + +- [ ] **Step 4: 提交集成修改** + +```bash +git add src/common/libs/umi/layoutConfig.tsx +git commit -m "feat: integrate CustomHeader and CustomLogo into layout" +``` + +--- + +### Task 8: 添加全局样式 + +**Files:** +- Create: `src/global.less` (如果不存在) 或 Modify: `src/global.less` + +- [ ] **Step 1: 检查global.less是否存在** + +```bash +ls -la src/global.less +``` + +如果文件存在,跳过此步。如果不存在,创建文件。 + +- [ ] **Step 2: 创建或修改global.less** + +如果文件不存在,创建它: + +```less +@import '~antd/es/style/reset.css'; + +// 全局样式 +body { + margin: 0; + padding: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, + sans-serif; + font-size: 14px; + line-height: 1.5715; + color: #262626; + background-color: #f5f5f5; +} + +// 自定义Logo样式 +.custom-logo { + display: flex; + align-items: center; + height: 64px; + padding: 0 16px; + border-bottom: 1px solid #f0f0f0; + transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1.000); + background: #ffffff; +} + +.custom-logo .logo-icon { + font-size: 32px; + min-width: 32px; + display: flex; + align-items: center; + justify-content: center; +} + +.custom-logo .logo-text { + margin-left: 12px; + font-size: 16px; + font-weight: 600; + color: #262626; + white-space: nowrap; + opacity: 1; + transition: opacity 0.2s; +} + +// 折叠状态 +.ant-layout-sider-collapsed .custom-logo { + padding: 0; + justify-content: center; +} + +.ant-layout-sider-collapsed .custom-logo .logo-text { + display: none; +} + +// 自定义Header样式 +.custom-header { + display: flex !important; + justify-content: space-between; + align-items: center; + padding: 0 24px !important; + background: #ffffff !important; + border-bottom: 1px solid #f0f0f0; + line-height: 64px; +} + +.custom-header .header-left { + flex: 1; +} + +.custom-header .header-right { + display: flex; + align-items: center; + gap: 16px; +} + +.custom-header .header-right > div { + display: flex; + align-items: center; + transition: opacity 0.2s; +} + +.custom-header .header-right > div:hover { + opacity: 0.8; +} + +// 内容区域 +.ant-pro-grid-content { + padding: 24px; +} + +// 页面容器卡片 +.ant-pro-page-container { + background: transparent; +} + +.ant-pro-page-container .ant-pro-page-container-warp { + background: #ffffff; + border-radius: 8px; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.03); + padding: 24px; +} +``` + +如果文件已存在,在文件末尾添加上述样式。 + +- [ ] **Step 3: 验证样式加载** + +```bash +npm run dev +``` + +Expected: 样式正确应用,布局显示正常 + +- [ ] **Step 4: 提交全局样式** + +```bash +git add src/global.less +git commit -m "style: add global styles for custom layout components" +``` + +--- + +### Task 9: 测试侧边栏折叠功能 + +**Files:** +- Test: Manual testing in browser + +- [ ] **Step 1: 启动应用** + +```bash +npm run dev +``` + +- [ ] **Step 2: 测试侧边栏折叠** + +在浏览器中: +1. 点击侧边栏折叠按钮(如果可见) +2. 或者修改layoutConfig临时添加折叠按钮用于测试 + +Expected: +- 侧边栏宽度从220px变为64px +- Logo文字消失,仅显示图标 +- 菜单文字隐藏,图标居中 + +- [ ] **Step 3: 测试侧边栏展开** + +再次点击折叠按钮 + +Expected: +- 侧边栏宽度从64px恢复为220px +- Logo文字显示 +- 菜单文字显示 + +- [ ] **Step 4: 测试Tooltip** + +折叠状态下,鼠标悬停在菜单图标上 + +Expected: 显示完整菜单项文字的Tooltip + +- [ ] **Step 5: 提交测试结果(如果有问题需修复)** + +如果有问题需要修复,创建新的task。如果测试通过,继续下一步。 + +--- + +### Task 10: 测试菜单导航和权限 + +**Files:** +- Test: Manual testing in browser + +- [ ] **Step 1: 测试菜单点击导航** + +点击各个菜单项 + +Expected: +- 页面正确跳转 +- 菜单项激活状态正确显示(蓝色文字+浅蓝背景) +- 左侧蓝色指示器显示 + +- [ ] **Step 2: 测试子菜单展开** + +点击有子菜单的项 + +Expected: +- 子菜单平滑展开 +- 层级缩进正确(每级20px) + +- [ ] **Step 3: 测试权限控制** + +使用不同权限的账户登录 + +Expected: +- 菜单根据权限正确显示/隐藏 +- 无权限的菜单项不显示 + +- [ ] **Step 4: 提交测试结果(如果有问题需修复)** + +如果有问题需要修复,创建新的task。如果测试通过,继续下一步。 + +--- + +### Task 11: 测试Header功能 + +**Files:** +- Test: Manual testing in browser + +- [ ] **Step 1: 测试用户信息显示** + +Expected: +- 头像正确显示 +- 用户名正确显示 + +- [ ] **Step 2: 测试下拉菜单** + +点击用户信息区域 + +Expected: +- 下拉菜单淡入显示 +- 菜单项:个人资料、修改密码、退出登录 + +- [ ] **Step 3: 测试退出登录** + +点击"退出登录" + +Expected: +- 清除token +- 跳转到登录页面 + +- [ ] **Step 4: 提交测试结果(如果有问题需修复)** + +如果有问题需要修复,创建新的task。如果测试通过,继续下一步。 + +--- + +### Task 12: 响应式测试 + +**Files:** +- Test: Manual testing in browser DevTools + +- [ ] **Step 1: 测试桌面端(>1024px)** + +Expected: 侧边栏宽度220px,完整显示 + +- [ ] **Step 2: 测试平板端(768px-1024px)** + +使用浏览器DevTools切换到平板视图 + +Expected: 布局正常,侧边栏可能自动收起 + +- [ ] **Step 3: 测试移动端(<768px)** + +使用浏览器DevTools切换到移动视图 + +Expected: +- 侧边栏自动收起 +- 内容区域内边距适应 + +- [ ] **Step 4: 提交测试结果(如果有问题需修复)** + +如果有问题需要修复,创建新的task。如果测试通过,继续下一步。 + +--- + +### Task 13: 浏览器兼容性测试 + +**Files:** +- Test: Manual testing in different browsers + +- [ ] **Step 1: Chrome浏览器测试** + +打开Chrome浏览器测试所有功能 + +Expected: 所有功能正常 + +- [ ] **Step 2: Firefox浏览器测试** + +打开Firefox浏览器测试所有功能 + +Expected: 所有功能正常 + +- [ ] **Step 3: Safari浏览器测试(如果有Mac)** + +打开Safari浏览器测试所有功能 + +Expected: 所有功能正常 + +- [ ] **Step 4: Edge浏览器测试** + +打开Edge浏览器测试所有功能 + +Expected: 所有功能正常 + +- [ ] **Step 5: 提交测试结果(如果有问题需修复)** + +如果有问题需要修复,创建新的task。如果测试通过,继续下一步。 + +--- + +### Task 14: 性能检查 + +**Files:** +- Test: Performance testing + +- [ ] **Step 1: 检查折叠动画性能** + +使用浏览器DevTools Performance面板录制折叠动画 + +Expected: 动画流畅,FPS > 30 + +- [ ] **Step 2: 检查首次渲染性能** + +刷新页面,查看DevTools Network和Performance + +Expected: 首次渲染时间 < 2秒 + +- [ ] **Step 3: 检查内存泄漏** + +打开应用,使用一段时间,查看DevTools Memory + +Expected: 无明显内存泄漏 + +- [ ] **Step 4: 提交性能检查结果(如果有问题需优化)** + +如果有问题需要优化,创建新的task。如果性能良好,继续下一步。 + +--- + +### Task 15: 最终验收和文档 + +**Files:** +- Update: `docs/superpowers/specs/2026-03-30-layout-redesign-design.md` + +- [ ] **Step 1: 对照设计文档验收** + +检查以下验收标准: +- [ ] 布局结构符合设计要求(左右分栏) +- [ ] 侧边栏可正常折叠和展开 +- [ ] 白色主题在所有页面正确显示 +- [ ] 菜单权限系统正常工作 +- [ ] 所有页面路由和功能无异常 +- [ ] 响应式布局在不同设备正常 +- [ ] 交互动画流畅自然 +- [ ] 通过所有测试要点 + +- [ ] **Step 2: 更新设计文档状态** + +在设计文档末尾添加: + +```markdown +## 实施状态 + +- [x] 设计完成 +- [x] 实施计划完成 +- [x] 实施完成 +- [x] 测试通过 +- [x] 验收通过 + +**完成日期**: 2026-03-30 +**提交记录**: [commit hash] +``` + +- [ ] **Step 3: 创建实施总结** + +创建 `docs/superpowers/summaries/2026-03-30-layout-redesign-summary.md`: + +```markdown +# Layout结构优化实施总结 + +**日期**: 2026-03-30 +**状态**: 已完成 + +## 实施内容 + +1. 将layout从mix模式优化为side模式 +2. 创建CustomLogo组件,支持折叠时智能显示 +3. 创建CustomHeader组件,保持用户信息功能 +4. 更新主题为白色系,提升视觉体验 +5. 添加全局样式和响应式支持 + +## 修改文件清单 + +- 新建: `src/common/components/layout/CustomHeader.tsx` +- 新建: `src/common/components/layout/CustomLogo.tsx` +- 新建: `src/common/components/layout/index.ts` +- 修改: `src/common/libs/umi/layoutConfig.tsx` +- 修改: `src/global.less` + +## 测试结果 + +- [x] 侧边栏折叠/展开功能正常 +- [x] 菜单导航和权限系统正常 +- [x] Header用户信息功能正常 +- [x] 响应式布局正常 +- [x] 浏览器兼容性良好 +- [x] 性能满足要求 + +## 备注 + +所有功能按设计文档实现,测试通过,可以上线使用。 +``` + +- [ ] **Step 4: 最终提交** + +```bash +git add docs/superpowers/specs/2026-03-30-layout-redesign-design.md +git add docs/superpowers/summaries/2026-03-30-layout-redesign-summary.md +git commit -m "docs: update design document and add implementation summary" +``` + +- [ ] **Step 5: 合并到主分支(如果需要)** + +```bash +git checkout main +git merge develop +git push origin main +``` + +或者根据项目流程创建PR。 + +--- + +## 计划自审查 + +**Spec覆盖检查:** +- ✅ 布局从mix改为side - Task 2 +- ✅ 白色主题 - Task 3 +- ✅ Logo组件(折叠智能显示) - Task 4 +- ✅ Header组件(用户信息) - Task 5 +- ✅ 侧边栏折叠功能 - Task 9 +- ✅ 菜单权限系统 - Task 10 +- ✅ 响应式设计 - Task 12 +- ✅ 样式和动画 - Task 8 +- ✅ 测试验收 - Task 15 + +**占位符扫描:** +- ✅ 无TBD、TODO +- ✅ 所有步骤包含具体代码/命令 +- ✅ 文件路径完整明确 +- ✅ 无"类似Task X"引用 + +**类型一致性检查:** +- ✅ CustomLogo组件在Task 4定义,Task 7导入使用 +- ✅ CustomHeader组件在Task 5定义,Task 7导入使用 +- ✅ layoutConfig配置在Task 2、3、7逐步完善,配置一致 + +**完整性检查:** +- ✅ 每个任务都是独立的可执行单元 +- ✅ 每个步骤都有明确的验证标准 +- ✅ 包含备份、开发、测试、提交的完整流程 +- ✅ 涵盖设计文档的所有需求