466 lines
12 KiB
Markdown
466 lines
12 KiB
Markdown
|
|
# Layout结构优化设计文档
|
|||
|
|
|
|||
|
|
**日期**: 2026-03-30
|
|||
|
|
**项目**: 物业缴费管理系统后台
|
|||
|
|
**目标**: 优化现有layout布局,改为左右结构,白色主题风格
|
|||
|
|
|
|||
|
|
## 1. 项目背景
|
|||
|
|
|
|||
|
|
当前系统使用UmiJS + Ant Design Pro Layout,采用`mix`混合布局模式。需要优化为更现代、清晰的左右分栏布局,以白色为主色调,提升用户体验。
|
|||
|
|
|
|||
|
|
## 2. 需求概述
|
|||
|
|
|
|||
|
|
### 2.1 布局结构要求
|
|||
|
|
- **左侧区域**(垂直分割):
|
|||
|
|
- 上方:Logo区域(Logo + 项目名称)
|
|||
|
|
- 下方:导航菜单
|
|||
|
|
|
|||
|
|
- **右侧区域**(垂直分割):
|
|||
|
|
- 上方:Header(用户信息、操作按钮)
|
|||
|
|
- 下方:页面内容区域
|
|||
|
|
|
|||
|
|
### 2.2 功能要求
|
|||
|
|
- 侧边栏固定宽度220px,支持折叠收起(折叠至64px)
|
|||
|
|
- Logo区域智能显示:展开时显示Logo+文字,折叠时仅显示Logo
|
|||
|
|
- 白色为主色调,整体风格干净整洁
|
|||
|
|
- 保持现有菜单权限系统不变
|
|||
|
|
- 响应式设计支持
|
|||
|
|
|
|||
|
|
## 3. 设计方案
|
|||
|
|
|
|||
|
|
### 3.1 整体架构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────┐
|
|||
|
|
│ Layout (side mode) │
|
|||
|
|
│ ┌──────────┬─────────────────────────────────────┐ │
|
|||
|
|
│ │ │ Header (64px, white background) │ │
|
|||
|
|
│ │ Left │ ┌───────────────────────────────┐ │ │
|
|||
|
|
│ │ Sidebar │ │ 用户信息区 + 操作按钮 │ │ │
|
|||
|
|
│ │ │ └───────────────────────────────┘ │ │
|
|||
|
|
│ │ ┌──────┐│ ┌───────────────────────────────┐ │ │
|
|||
|
|
│ │ │ Logo ││ │ │ │ │
|
|||
|
|
│ │ │+Text ││ │ 页面内容区域 │ │ │
|
|||
|
|
│ │ │64px ││ │ (children渲染) │ │ │
|
|||
|
|
│ │ ├──────┤│ │ padding: 24px │ │ │
|
|||
|
|
│ │ │ Menu ││ │ │ │ │
|
|||
|
|
│ │ │ ││ │ │ │ │
|
|||
|
|
│ │ └──────┘│ └───────────────────────────────┘ │ │
|
|||
|
|
│ └──────────┴─────────────────────────────────────┘ │
|
|||
|
|
└─────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.2 侧边栏设计(左侧)
|
|||
|
|
|
|||
|
|
#### Logo区域
|
|||
|
|
- **高度**: 64px
|
|||
|
|
- **背景色**: `#ffffff`
|
|||
|
|
- **边框**: 底部 1px solid `#f0f0f0`
|
|||
|
|
- **展开状态**: Logo图标(32px) + 项目名称文字
|
|||
|
|
- **折叠状态**: 仅显示Logo图标,居中显示
|
|||
|
|
- **动画**: 平滑过渡 200ms
|
|||
|
|
|
|||
|
|
#### 菜单区域
|
|||
|
|
- **背景色**: `#ffffff`
|
|||
|
|
- **菜单项高度**: 40px
|
|||
|
|
- **菜单文字颜色**:
|
|||
|
|
- 默认: `#595959`
|
|||
|
|
- 悬停: `#1890ff`
|
|||
|
|
- 激活: `#1890ff` (背景 `#e6f7ff`)
|
|||
|
|
- **图标颜色**: 跟随文字颜色
|
|||
|
|
- **层级缩进**: 每级 20px
|
|||
|
|
- **激活指示器**: 左侧蓝色竖线 3px宽
|
|||
|
|
|
|||
|
|
#### 配置参数
|
|||
|
|
```typescript
|
|||
|
|
siderWidth: 220,
|
|||
|
|
collapsedWidth: 64,
|
|||
|
|
breakpoint: 'lg',
|
|||
|
|
collapsible: true
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.3 Header设计(右侧上方)
|
|||
|
|
|
|||
|
|
#### 布局规格
|
|||
|
|
- **高度**: 64px
|
|||
|
|
- **背景色**: `#ffffff`
|
|||
|
|
- **边框**: 底部 1px solid `#f0f0f0`
|
|||
|
|
- **内边距**: 0 24px
|
|||
|
|
- **布局**: flex左右分布
|
|||
|
|
|
|||
|
|
#### 内容区域
|
|||
|
|
|
|||
|
|
**左侧区域**(可选):
|
|||
|
|
- 面包屑导航或页面标题
|
|||
|
|
|
|||
|
|
**右侧区域**:
|
|||
|
|
- 用户头像(32px圆形)
|
|||
|
|
- 用户名(悬停显示下拉菜单)
|
|||
|
|
- 下拉菜单项:
|
|||
|
|
- 个人资料
|
|||
|
|
- 修改密码
|
|||
|
|
- 退出登录
|
|||
|
|
|
|||
|
|
### 3.4 内容区域设计(右侧下方)
|
|||
|
|
|
|||
|
|
#### 容器规格
|
|||
|
|
- **背景色**: `#f5f5f5`
|
|||
|
|
- **内边距**: 24px
|
|||
|
|
- **最小高度**: `calc(100vh - 64px)`
|
|||
|
|
|
|||
|
|
#### 页面内容(可选包裹)
|
|||
|
|
如果需要卡片包裹:
|
|||
|
|
- **背景色**: `#ffffff`
|
|||
|
|
- **圆角**: 8px
|
|||
|
|
- **阴影**: `0 1px 2px 0 rgba(0, 0, 0, 0.03)`
|
|||
|
|
- **内边距**: 24px
|
|||
|
|
|
|||
|
|
### 3.5 颜色主题规范
|
|||
|
|
|
|||
|
|
#### 主色调
|
|||
|
|
- 主色: `#1890ff`
|
|||
|
|
- 成功: `#52c41a`
|
|||
|
|
- 警告: `#faad14`
|
|||
|
|
- 错误: `#ff4d4f`
|
|||
|
|
- 信息: `#1890ff`
|
|||
|
|
|
|||
|
|
#### 中性色
|
|||
|
|
- 标题文字: `#262626`
|
|||
|
|
- 正文文字: `#595959`
|
|||
|
|
- 次要文字: `#8c8c8c`
|
|||
|
|
- 禁用文字: `#bfbfbf`
|
|||
|
|
- 边框: `#d9d9d9`
|
|||
|
|
- 分割线: `#f0f0f0`
|
|||
|
|
|
|||
|
|
#### 背景色
|
|||
|
|
- 布局背景: `#f5f5f5`
|
|||
|
|
- 侧边栏: `#ffffff`
|
|||
|
|
- Header: `#ffffff`
|
|||
|
|
- 内容卡片: `#ffffff`
|
|||
|
|
|
|||
|
|
### 3.6 字体规范
|
|||
|
|
- **字号**: 14px(基准)
|
|||
|
|
- **行高**: 1.5715
|
|||
|
|
- **字体族**: `-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial`
|
|||
|
|
|
|||
|
|
### 3.7 交互和动画
|
|||
|
|
|
|||
|
|
#### 侧边栏折叠
|
|||
|
|
- **动画时长**: 200ms
|
|||
|
|
- **动画曲线**: `cubic-bezier(0.645, 0.045, 0.355, 1.000)`
|
|||
|
|
- **折叠时**:
|
|||
|
|
- Logo文字淡出
|
|||
|
|
- 菜单文字隐藏,图标居中
|
|||
|
|
- Tooltip显示完整菜单项文字
|
|||
|
|
- **展开时**:
|
|||
|
|
- Logo文字淡入
|
|||
|
|
- 菜单文字从左侧滑入
|
|||
|
|
|
|||
|
|
#### 菜单交互
|
|||
|
|
- 悬停效果:背景色变化 0.2s
|
|||
|
|
- 子菜单展开:平滑动画
|
|||
|
|
- 激活状态:左侧蓝色竖线指示器
|
|||
|
|
|
|||
|
|
#### Header交互
|
|||
|
|
- 下拉菜单:淡入动画
|
|||
|
|
- 按钮悬停:背景色变化
|
|||
|
|
|
|||
|
|
## 4. 技术实现
|
|||
|
|
|
|||
|
|
### 4.1 核心配置修改
|
|||
|
|
|
|||
|
|
修改 `src/common/libs/umi/layoutConfig.tsx`:
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
export const LayoutConfig: RuntimeConfig['layout'] = () => {
|
|||
|
|
return {
|
|||
|
|
// 从 'mix' 改为 'side'
|
|||
|
|
layout: 'side',
|
|||
|
|
|
|||
|
|
title: '物业管理系统',
|
|||
|
|
logo: false, // 禁用默认logo,使用自定义
|
|||
|
|
|
|||
|
|
// 侧边栏配置
|
|||
|
|
siderWidth: 220,
|
|||
|
|
collapsedWidth: 64,
|
|||
|
|
breakpoint: 'lg',
|
|||
|
|
|
|||
|
|
// 主题token配置
|
|||
|
|
token: {
|
|||
|
|
bgLayout: '#f5f5f5',
|
|||
|
|
header: {
|
|||
|
|
colorBgHeader: '#ffffff',
|
|||
|
|
colorHeaderTitle: '#262626',
|
|||
|
|
colorTextRightActionsItem: '#595959',
|
|||
|
|
heightLayoutHeader: 64,
|
|||
|
|
},
|
|||
|
|
sider: {
|
|||
|
|
colorMenuBackground: '#ffffff',
|
|||
|
|
colorMenuText: '#595959',
|
|||
|
|
colorMenuTextSelected: '#1890ff',
|
|||
|
|
colorMenuItemBgSelected: '#e6f7ff',
|
|||
|
|
colorMenuDivider: '#f0f0f0',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 自定义Header渲染
|
|||
|
|
headerRender: (props) => {
|
|||
|
|
return <CustomHeader {...props} />;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 自定义Logo渲染
|
|||
|
|
logoRenderer: (collapsed) => {
|
|||
|
|
return <CustomLogo collapsed={collapsed} />;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 菜单配置保持不变
|
|||
|
|
menu: {
|
|||
|
|
params: snap.session.permissions,
|
|||
|
|
request: async () => {
|
|||
|
|
// 现有菜单权限逻辑
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 其他配置保持不变
|
|||
|
|
avatarProps: {
|
|||
|
|
render: () => <AvatarProps user={snap.session.user} />,
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.2 新增组件
|
|||
|
|
|
|||
|
|
#### CustomHeader.tsx
|
|||
|
|
```typescript
|
|||
|
|
import { Layout, Dropdown, Avatar } from 'antd';
|
|||
|
|
import type { MenuProps } from 'antd';
|
|||
|
|
|
|||
|
|
const { Header } = Layout;
|
|||
|
|
|
|||
|
|
export const CustomHeader = (props: any) => {
|
|||
|
|
const menuItems: MenuProps['items'] = [
|
|||
|
|
{ key: 'profile', label: '个人资料' },
|
|||
|
|
{ key: 'password', label: '修改密码' },
|
|||
|
|
{ type: 'divider' },
|
|||
|
|
{ key: 'logout', label: '退出登录' },
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<Header className="custom-header">
|
|||
|
|
{/* 左侧:面包屑或页面标题 */}
|
|||
|
|
<div className="header-left">
|
|||
|
|
{/* 可选:面包屑导航 */}
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* 右侧:用户信息 */}
|
|||
|
|
<div className="header-right">
|
|||
|
|
<Dropdown menu={{ items: menuItems }} placement="bottomRight">
|
|||
|
|
<AvatarProps user={user} />
|
|||
|
|
</Dropdown>
|
|||
|
|
</div>
|
|||
|
|
</Header>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### CustomLogo.tsx
|
|||
|
|
```typescript
|
|||
|
|
import { MyIcons } from '@/common';
|
|||
|
|
|
|||
|
|
export const CustomLogo = ({ collapsed }: { collapsed: boolean }) => {
|
|||
|
|
return (
|
|||
|
|
<div className="custom-logo">
|
|||
|
|
<div className="logo-icon">
|
|||
|
|
{/* Logo图标或图片 */}
|
|||
|
|
<MyIcons.HomeOutlined />
|
|||
|
|
</div>
|
|||
|
|
{!collapsed && (
|
|||
|
|
<div className="logo-text">
|
|||
|
|
物业管理系统
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.3 样式文件
|
|||
|
|
|
|||
|
|
在 `src/global.less` 或组件内部添加:
|
|||
|
|
|
|||
|
|
```less
|
|||
|
|
.custom-header {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: center;
|
|||
|
|
padding: 0 24px;
|
|||
|
|
background: #ffffff;
|
|||
|
|
border-bottom: 1px solid #f0f0f0;
|
|||
|
|
|
|||
|
|
.header-left {
|
|||
|
|
flex: 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.header-right {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 16px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.custom-logo {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
height: 64px;
|
|||
|
|
padding: 0 16px;
|
|||
|
|
border-bottom: 1px solid #f0f0f0;
|
|||
|
|
transition: all 0.2s;
|
|||
|
|
|
|||
|
|
.logo-icon {
|
|||
|
|
font-size: 32px;
|
|||
|
|
min-width: 32px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.logo-text {
|
|||
|
|
margin-left: 12px;
|
|||
|
|
font-size: 16px;
|
|||
|
|
font-weight: 600;
|
|||
|
|
color: #262626;
|
|||
|
|
white-space: nowrap;
|
|||
|
|
opacity: 1;
|
|||
|
|
transition: opacity 0.2s;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 5. 实施计划
|
|||
|
|
|
|||
|
|
### 5.1 实施步骤
|
|||
|
|
1. 备份当前 `layoutConfig.tsx` 文件
|
|||
|
|
2. 修改 layout 模式:`'mix'` → `'side'`
|
|||
|
|
3. 更新 token 配置为白色主题
|
|||
|
|
4. 创建 `CustomHeader.tsx` 组件
|
|||
|
|
5. 创建 `CustomLogo.tsx` 组件
|
|||
|
|
6. 在 `layoutConfig.tsx` 中集成自定义组件
|
|||
|
|
7. 测试侧边栏折叠/展开功能
|
|||
|
|
8. 测试菜单导航和权限控制
|
|||
|
|
9. 测试响应式布局
|
|||
|
|
10. 调整细节样式和动画
|
|||
|
|
|
|||
|
|
### 5.2 文件修改清单
|
|||
|
|
|
|||
|
|
**需要修改**:
|
|||
|
|
- `src/common/libs/umi/layoutConfig.tsx` - 主要配置修改
|
|||
|
|
|
|||
|
|
**需要新建**:
|
|||
|
|
- `src/common/components/layout/CustomHeader.tsx`
|
|||
|
|
- `src/common/components/layout/CustomLogo.tsx`
|
|||
|
|
|
|||
|
|
**可能修改**:
|
|||
|
|
- `src/global.less` - 全局样式调整
|
|||
|
|
|
|||
|
|
**无需修改**:
|
|||
|
|
- 菜单权限逻辑(`loopMenu` 函数)
|
|||
|
|
- 用户信息组件(`AvatarProps`)
|
|||
|
|
- 页面路由和业务组件
|
|||
|
|
- `src/app.tsx` 配置
|
|||
|
|
|
|||
|
|
### 5.3 兼容性保证
|
|||
|
|
|
|||
|
|
**保持不变的功能**:
|
|||
|
|
- ✅ 菜单权限系统
|
|||
|
|
- ✅ 用户登录状态
|
|||
|
|
- ✅ 路由跳转逻辑
|
|||
|
|
- ✅ 页面内容渲染
|
|||
|
|
- ✅ 现有业务组件
|
|||
|
|
|
|||
|
|
**优化改进的功能**:
|
|||
|
|
- 🎨 布局结构和视觉风格
|
|||
|
|
- 🎨 主题色和配色方案
|
|||
|
|
- 🎨 交互体验和动画效果
|
|||
|
|
|
|||
|
|
## 6. 测试要点
|
|||
|
|
|
|||
|
|
### 6.1 功能测试
|
|||
|
|
- [ ] 侧边栏折叠/展开正常工作
|
|||
|
|
- [ ] 菜单项点击导航正确
|
|||
|
|
- [ ] 菜单激活状态正确显示
|
|||
|
|
- [ ] 用户信息下拉菜单功能正常
|
|||
|
|
- [ ] 所有页面路由可正常访问
|
|||
|
|
|
|||
|
|
### 6.2 样式测试
|
|||
|
|
- [ ] 白色主题在所有页面正常显示
|
|||
|
|
- [ ] Logo展开/折叠切换流畅
|
|||
|
|
- [ ] 菜单悬停和激活状态样式正确
|
|||
|
|
- [ ] Header样式和布局正确
|
|||
|
|
- [ ] 内容区域内边距和背景正确
|
|||
|
|
|
|||
|
|
### 6.3 响应式测试
|
|||
|
|
- [ ] 桌面端(>1024px)显示正常
|
|||
|
|
- [ ] 平板端(768px-1024px)显示正常
|
|||
|
|
- [ ] 移动端(<768px)侧边栏自动收起
|
|||
|
|
- [ ] 各断点下布局无错位
|
|||
|
|
|
|||
|
|
### 6.4 兼容性测试
|
|||
|
|
- [ ] 表单页面显示正常
|
|||
|
|
- [ ] 表格页面显示正常
|
|||
|
|
- [ ] 弹窗和抽屉组件正常
|
|||
|
|
- [ ] 现有业务功能无异常
|
|||
|
|
|
|||
|
|
## 7. 风险和注意事项
|
|||
|
|
|
|||
|
|
### 7.1 潜在风险
|
|||
|
|
- **样式冲突**: Ant Design版本升级可能导致样式变化
|
|||
|
|
- **浏览器兼容**: CSS动画在旧浏览器可能不支持
|
|||
|
|
- **性能影响**: 过多动画可能影响低端设备性能
|
|||
|
|
|
|||
|
|
### 7.2 缓解措施
|
|||
|
|
- 在主流浏览器中测试(Chrome, Firefox, Safari, Edge)
|
|||
|
|
- 使用CSS `@supports`检测动画支持
|
|||
|
|
- 优化动画性能,使用 `transform` 和 `opacity`
|
|||
|
|
- 提供关闭动画的选项(如果需要)
|
|||
|
|
|
|||
|
|
### 7.3 回滚方案
|
|||
|
|
- 保留原 `layoutConfig.tsx` 备份
|
|||
|
|
- 使用git版本控制,可随时回退
|
|||
|
|
- 分阶段发布,先在测试环境验证
|
|||
|
|
|
|||
|
|
## 8. 后续优化建议
|
|||
|
|
|
|||
|
|
### 8.1 短期优化
|
|||
|
|
- 添加暗色模式切换(可选)
|
|||
|
|
- 优化移动端触摸体验
|
|||
|
|
- 添加快捷键支持
|
|||
|
|
|
|||
|
|
### 8.2 长期优化
|
|||
|
|
- 考虑使用ProLayout替代UmiJS Layout(如需要更多功能)
|
|||
|
|
- 添加主题定制功能
|
|||
|
|
- 实现布局配置持久化(记住用户的折叠状态等)
|
|||
|
|
|
|||
|
|
## 9. 验收标准
|
|||
|
|
|
|||
|
|
项目完成需满足以下标准:
|
|||
|
|
|
|||
|
|
1. ✅ 布局结构符合设计要求(左右分栏)
|
|||
|
|
2. ✅ 侧边栏可正常折叠和展开
|
|||
|
|
3. ✅ 白色主题在所有页面正确显示
|
|||
|
|
4. ✅ 菜单权限系统正常工作
|
|||
|
|
5. ✅ 所有页面路由和功能无异常
|
|||
|
|
6. ✅ 响应式布局在不同设备正常
|
|||
|
|
7. ✅ 交互动画流畅自然
|
|||
|
|
8. ✅ 通过所有测试要点
|
|||
|
|
|
|||
|
|
## 10. 附录
|
|||
|
|
|
|||
|
|
### 10.1 参考文档
|
|||
|
|
- [UmiJS Layout配置](https://umijs.org/docs/max/layout-menu)
|
|||
|
|
- [Ant Design Layout组件](https://ant.design/components/layout-cn)
|
|||
|
|
- [Ant Design 主题定制](https://ant.design/docs/react/customize-theme-cn)
|
|||
|
|
|
|||
|
|
### 10.2 设计原则
|
|||
|
|
- **简洁**: 去除不必要的装饰和元素
|
|||
|
|
- **一致**: 保持整体风格统一
|
|||
|
|
- **高效**: 快速加载和响应
|
|||
|
|
- **易用**: 直观的交互和导航
|