Files
gongxue-base/docs/superpowers/specs/2026-07-03-admin-responsive-adaptation-design.md

164 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
comet_change: admin-responsive-adaptation
role: technical-design
canonical_spec: openspec
archived-with: 2026-07-03-admin-responsive-adaptation
status: final
---
# 管理后台三端响应式适配 — 技术设计
## 1. 架构概览
```
┌─────────────────────────────────────────────────────────────────┐
│ Admin Frontend │
├─────────────────────────────────────────────────────────────────┤
│ App.tsx │
│ └─ ConfigProvider (antd theme + locale) │
│ └─ BrowserRouter │
│ ├─ LoginPage │
│ └─ MainLayout │
│ ├─ Sider/Drawer (断点决定) │
│ ├─ Header (用户区域断点隐藏文字) │
│ └─ Content → <Outlet> │
│ ├─ Dashboard (统计卡片 + ECharts) │
│ ├─ RoomVisual (房态网格卡片) │
│ ├─ [14 个表格型页面] (Table + 搜索/操作工具栏) │
│ └─ ClassroomSchedule (HTML 排期大表) │
└─────────────────────────────────────────────────────────────────┘
```
## 2. 断点体系
使用 antd v6 内置 `Grid.useBreakpoint()` hook映射三类设备行为
| 端侧 | antd 断点 | 视口宽度 | 布局行为 |
|------|-----------|---------|---------|
| 手机 | `xs` | < 576px | Drawer 抽屉菜单padding 12px |
| 平板 | `sm`, `md` | 576-991px | 侧栏默认折叠padding 16px |
| 桌面 | `lg`, `xl`, `xxl` | 992px | 侧栏可折叠默认展开padding 24px |
**选择理由:** 使用 antd 内置断点与 `Row/Col` 响应式 props 天然一致避免维护两套断点逻辑992px 与最初规划的 1024px 相差 32px实际设备无感知
## 3. 核心决策
### 3.1 MainLayout 响应式检测
**当前:** `useState(window.innerWidth < 768)` + `resize` 事件 `isMobile` 布尔值
**目标:** `Grid.useBreakpoint()` `{ xs, sm, md, lg, xl, xxl }` 布尔值
```typescript
const screens = Grid.useBreakpoint();
const isMobile = !screens.sm; // < 576px (仅 xs)
const isTablet = (screens.sm || screens.md) && !screens.lg; // 576-991px
const isDesktop = !!screens.lg; // ≥ 992px
```
影响范围 `MainLayout.tsx` 一个文件`useEffect` + `resize` 事件监听可移除
### 3.2 CSS 策略antd Props 优先
| 场景 | 优先方案 | 兜底方案 |
|------|---------|---------|
| 表格列过多 | `scroll={{ x }}` | antd 自带滚动条 |
| 卡片网格 | `Col` 响应式断点 props | `index.css` @media |
| 文字截断 | `ellipsis: true` | `text-overflow: ellipsis` CSS |
| 弹窗宽度 | antd `width` prop | `index.css` `max-width` 约束 |
| 工具栏换行 | `flexWrap: 'wrap'` + `gap` inline style | |
**`index.css` 追加的 @media 规则总计约 40 **
- `(max-width: 575px)`: 表格字体 13px弹窗 max-width 约束Modal body max-height
- `(min-width: 576px) and (max-width: 991px)`: 平板特有的间距微调
- 通用: `.ant-table-wrapper { overflow-x: auto }` 确保所有表格容器可滚动
### 3.3 表格横向滚动
所有 `<Table>` 统一添加 `scroll={{ x }}`具体值
- 列少(≤6 `scroll={{ x: 'max-content' }}` 或省略antd 自动处理
- 列中7-10 `scroll={{ x: 800 }}`
- 列多>10 列或含长文本列):`scroll={{ x: 1000 }}` 或更大
操作列(最后一列)使用 `width` 固定宽度,必要时添加 `fixed: 'right'` 在宽表场景下提升体验。
### 3.4 Dashboard 响应式网格
```
统计卡片 (4 张):
<Col xs={12} sm={12} md={6}> // 手机2列 平板2列 桌面4列
图表卡片 (2 张):
<Col xs={24} sm={12}> // 手机堆叠 平板及以上并排
```
顶部工具栏(标题 + DatePicker在小屏下从 `flex` 横向排列改为 `flexDirection: 'column'` 堆叠。
### 3.5 ECharts 图表
通过 `echarts-for-react` 的内置 `ResizeObserver` 自动适配:
```tsx
<ReactECharts
option={option}
style={{ width: '100%', height: isMobile ? 250 : 300 }}
opts={{ renderer: 'canvas' }}
/>
```
容器宽度由 antd `Col` 响应式断点控制,图表自动跟随。甘特图动态高度逻辑不变(`Math.max(300, data.length * 40)`)。
### 3.6 弹窗适配
**全局 CSSindex.css**
```css
@media (max-width: 575px) {
.ant-modal { max-width: calc(100vw - 24px) !important; }
.ant-modal-body { max-height: 60vh; overflow-y: auto; }
}
```
**组件级别:** 各弹窗 `width` 在桌面端固定值400-600px移动端由全局 CSS 覆盖为 `max-width` 约束。
### 3.7 教室排期表
最复杂的适配场景 — HTML `<table>` 含 31+ 日期列 + sticky 首列:
- 外层 `div` 保持 `overflowX: 'auto'`
- 首列(教室名)`position: sticky; left: 0` 保持已有
- 日期列 `minWidth: 26` 不压窄
- `overflowX` 容器在平板/手机下自动出现横向滚动条
### 3.8 学生字段拆分
学生管理页将 `{ title: '学号/身份证', dataIndex: 'idNumber' }` 一列拆为两列:
```typescript
{ title: '学号', dataIndex: 'studentNumber', width: 120, ellipsis: true },
{ title: '身份证', dataIndex: 'idNumber', width: 180, ellipsis: true },
```
向后兼容:若后端暂未返回 `studentNumber` 字段,该列显示 `-`,不报错。
## 4. 实现顺序
```
Phase 1: 基础
1. index.css 三断点体系
2. MainLayout useBreakpoint 重构
Phase 2: 高优先级页面
3. Dashboard (4 张统计卡 + 3 张图)
4. 学生管理 (表格 + 字段拆分)
5. 入住管理 (表格 + 弹窗多)
Phase 3: 批量页面
6-17. 剩余 12 个表格型页面(模式统一,效率高)
Phase 4: 收尾
18. 教室排期表(特殊 HTML table
19. 登录页(单卡片)
20. 全局验证
```
## 5. 验证计划
- **视觉检查:** Chrome DevTools 响应式模式 → 375 / 768 / 992 / 1440 四个宽度
- **每个页面检查:** 表格有无横向滚动 → 按钮是否错位/溢出 → 弹窗是否出屏 → 文字是否截断
- **编译检查:** `npm run build` 确保 TypeScript 无报错