chore: 归档 3 个 change 产物、Design Doc、验证报告、主 spec、项目配置

This commit is contained in:
2026-07-03 10:58:57 +08:00
parent ef805fc823
commit 3b45723877
27 changed files with 641 additions and 0 deletions

10
.claude/CLAUDE.md Normal file
View File

@@ -0,0 +1,10 @@
<!-- CODEGRAPH_START -->
## CodeGraph
In repositories indexed by CodeGraph (a `.codegraph/` directory exists at the repo root), reach for it BEFORE grep/find or reading files when you need to understand or locate code:
- **MCP tool** (when available): `codegraph_explore` answers most code questions in one call — the relevant symbols' verbatim source plus the call paths between them, including dynamic-dispatch hops grep can't follow. Name a file or symbol in the query to read its current line-numbered source. If it's listed but deferred, load it by name via tool search.
- **Shell** (always works): `codegraph explore "<symbol names or question>"` prints the same output.
If there is no `.codegraph/` directory, skip CodeGraph entirely — indexing is the user's decision.
<!-- CODEGRAPH_END -->

19
.claude/settings.json Normal file
View File

@@ -0,0 +1,19 @@
{
"permissions": {
"allow": [
"mcp__codegraph__*"
]
},
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "codegraph prompt-hook"
}
]
}
]
}
}

1
.gitignore vendored
View File

@@ -49,3 +49,4 @@ apps/server/node_modules/
apps/server/dist/
apps/admin/node_modules/
apps/admin/dist/
.codegraph/

12
.mcp.json Normal file
View File

@@ -0,0 +1,12 @@
{
"mcpServers": {
"codegraph": {
"type": "stdio",
"command": "codegraph",
"args": [
"serve",
"--mcp"
]
}
}
}

View File

@@ -2,6 +2,7 @@
change: migrate-to-turborepo
design-doc: docs/superpowers/specs/2026-07-02-migrate-to-turborepo-design.md
base-ref: 72db78daed6d840f2ddc7c0103f69325253b9098
archived-with: 2026-07-02-migrate-to-turborepo
---
# Turborepo 单体仓库迁移实施计划
@@ -23,6 +24,7 @@ base-ref: 72db78daed6d840f2ddc7c0103f69325253b9098
- 所有 workspace 统一使用 `lint` / `format` / `build` / `dev` / `test` 脚本名
- 每个任务完成后立即 `git commit`,便于独立审查和回滚
archived-with: 2026-07-02-migrate-to-turborepo
---
### Task 1: 目录重组
@@ -155,6 +157,7 @@ git commit -m "feat(task1): restructure directories for turborepo monorepo
- Create packages/typescript-config/ with base, nestjs, and react-vite presets"
```
archived-with: 2026-07-02-migrate-to-turborepo
---
### Task 2: 根配置
@@ -270,6 +273,7 @@ git commit -m "feat(task2): add root turborepo and npm workspaces configuration
- Update .gitignore for turborepo artifacts"
```
archived-with: 2026-07-02-migrate-to-turborepo
---
### Task 3: 工具链迁移oxlint + oxfmt
@@ -469,6 +473,7 @@ git commit -m "feat(task3): migrate toolchain to oxfmt + oxlint
- Delete server .prettierrc and admin eslint.config.js"
```
archived-with: 2026-07-02-migrate-to-turborepo
---
### Task 4: TypeScript 配置更新
@@ -583,6 +588,7 @@ git commit -m "feat(task4): update TypeScript configs to use shared presets
- Align server TypeScript to ~6.0.2"
```
archived-with: 2026-07-02-migrate-to-turborepo
---
### Task 5: Docker 适配
@@ -631,6 +637,7 @@ git commit -m "feat(task5): update docker-compose build.context paths
- Container names unchanged: dorm_billing_backend, dorm_billing_frontend"
```
archived-with: 2026-07-02-migrate-to-turborepo
---
### Task 6: 验证

View File

@@ -2,6 +2,7 @@
change: admin-responsive-adaptation
design-doc: docs/superpowers/specs/2026-07-03-admin-responsive-adaptation-design.md
base-ref: 779cedb8a07bbfe1c50871526f9b99f8bc008acc
archived-with: 2026-07-03-admin-responsive-adaptation
---
# 管理后台三端响应式适配 Implementation Plan
@@ -23,6 +24,7 @@ base-ref: 779cedb8a07bbfe1c50871526f9b99f8bc008acc
- 编译必须通过:`npm run build` 无 TypeScript 错误
- 命名约定:从 `expenseTypeMap` 等现有映射扩展,不新建无意义的变量名
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 1: 全局 CSS 三断点体系
@@ -123,6 +125,7 @@ git add apps/admin/src/index.css
git commit -m "feat: 建立三断点 CSS 体系,替换单断点移动端样式"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 2: MainLayout 三端布局重构
@@ -280,6 +283,7 @@ git add apps/admin/src/layouts/MainLayout.tsx
git commit -m "feat: MainLayout 三端布局重构,使用 antd Grid.useBreakpoint()"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 3: Dashboard 响应式网格和图表
@@ -443,6 +447,7 @@ git add apps/admin/src/pages/Dashboard/index.tsx
git commit -m "feat: Dashboard 响应式网格,统计卡片/图表/工具栏适配三端"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 4: 学生管理字段拆分和响应式适配
@@ -553,6 +558,7 @@ git add apps/admin/src/pages/Students/index.tsx
git commit -m "feat: 学生管理字段拆分(学号/身份证分列),表格和工具栏响应式适配"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 5: 宿舍总览 RoomVisual 复查
@@ -597,6 +603,7 @@ git commit -m "chore: RoomVisual 三端断点复查确认,无改动"
注:如果复查无改动,可跳过此 commit或提交一个空 commit 标记完成。
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 6: 入住管理 Occupancies 响应式适配
@@ -651,6 +658,7 @@ git add apps/admin/src/pages/Occupancies/index.tsx
git commit -m "feat: 入住管理表格添加 scroll工具栏/弹窗响应式适配"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 7: 宿舍管理 Rooms 响应式适配
@@ -696,6 +704,7 @@ git add apps/admin/src/pages/Rooms/index.tsx
git commit -m "feat: 宿舍管理表格添加 scroll 横向滚动"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 8: 费用录入 Expenses 响应式适配
@@ -762,6 +771,7 @@ git add apps/admin/src/pages/Expenses/index.tsx
git commit -m "feat: 费用录入两个表格添加 scroll 横向滚动"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 9: 押金管理 Deposits 响应式适配
@@ -803,6 +813,7 @@ git add apps/admin/src/pages/Deposits/index.tsx
git commit -m "feat: 押金管理表格添加 scroll 横向滚动"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 10: 账单管理 Bills 响应式适配
@@ -886,6 +897,7 @@ git add apps/admin/src/pages/Bills/index.tsx
git commit -m "feat: 账单管理表格添加 scroll详情内嵌表格也添加 scroll"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 11: 教室管理 Classrooms 响应式适配
@@ -925,6 +937,7 @@ git add apps/admin/src/pages/Classrooms/index.tsx
git commit -m "feat: 教室管理表格添加 scroll 横向滚动"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 12: 租赁订单 ClassroomRentals 响应式适配
@@ -955,6 +968,7 @@ git commit -m "chore: ClassroomRentals 复查 scroll 和 wrap确认无需修
注:如果复查无改动,可跳过此 commit。
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 13: 租赁方 Tenants 响应式适配
@@ -996,6 +1010,7 @@ git add apps/admin/src/pages/Tenants/index.tsx
git commit -m "feat: 租赁方表格添加 scroll 横向滚动"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 14: 操作日志 OperationLogs 响应式适配
@@ -1024,6 +1039,7 @@ git add apps/admin/src/pages/OperationLogs/index.tsx
git commit -m "chore: OperationLogs 复查 scroll 和 wrap确认无需修改"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 15: 角色管理 Roles 响应式适配
@@ -1072,6 +1088,7 @@ git add apps/admin/src/pages/Roles/index.tsx
git commit -m "feat: 角色管理工具栏添加 flexWrap 响应式适配"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 16: 权限一览 Permissions 响应式适配
@@ -1112,6 +1129,7 @@ git add apps/admin/src/pages/Permissions/index.tsx
git commit -m "feat: 权限一览工具栏添加 flexWrap 响应式适配"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 17: 账号管理 Users 响应式适配
@@ -1156,6 +1174,7 @@ git add apps/admin/src/pages/Users/index.tsx
git commit -m "feat: 账号管理工具栏添加 flexWrap 响应式适配"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 18: 教室排期 ClassroomSchedule 特殊适配
@@ -1188,6 +1207,7 @@ git add apps/admin/src/pages/ClassroomSchedule/index.tsx
git commit -m "chore: ClassroomSchedule 复查 sticky 列和日期列 minWidth确认无需修改"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 19: 登录页 Login 响应式适配
@@ -1226,6 +1246,7 @@ git add apps/admin/src/pages/Login/index.tsx
git commit -m "feat: 登录卡片改为 maxWidth + calc 响应式宽度"
```
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Task 20: 全局验证与编译检查
@@ -1302,6 +1323,7 @@ git commit -m "chore: 全局响应式适配验证完成"
如果验证中发现问题需要修复,则在对应页面进行修复后单独 commit。
archived-with: 2026-07-03-admin-responsive-adaptation
---
### Critical Files for Implementation

View File

@@ -0,0 +1,26 @@
# Verification Report: add-tsbuildinfo-to-gitignore
**Date**: 2026-07-02
**Verify Mode**: light
**Change**: Add `*.tsbuildinfo` to `.gitignore`
## Checks
| # | Check | Result | Detail |
|---|-------|--------|--------|
| 1 | Tasks complete | ✅ PASS | 3/3 tasks `[x]` |
| 2 | Diff matches tasks | ✅ PASS | Only `.gitignore` modified |
| 3 | Build passes | ✅ PASS | `npm run build` — 2 tasks, 2 cached |
| 4 | Tests pass | ✅ PASS | 1 suite, 1 test, 0 failures |
| 5 | No security issues | ✅ PASS | No secrets, no unsafe ops |
| 6 | Code review | ⏭️ SKIP | `review_mode: off` |
## Branch Handling
- **Status**: handled
- **Action**: Committed directly to `main` (local-only repo, no remote configured)
- **Commit**: `a671980``tweak: add *.tsbuildinfo to .gitignore to prevent stale incremental cache`
## Summary
All light verification checks passed. The change is minimal (1 line in `.gitignore`) and safe.

View File

@@ -0,0 +1,76 @@
# Verification Report: admin-responsive-adaptation
**Date:** 2026-07-03
**Verify Mode:** full
**Review Mode:** off (纯 UI/CSS props 改动,无业务逻辑变更)
## Summary
| Dimension | Status |
|-----------|--------|
| Completeness | 56/56 tasks ✅ |
| Correctness | 8/8 requirements covered ✅ |
| Coherence | Design decisions followed ✅ |
| Build | Pass ✅ (`npm run build` exit 0) |
| Code Review | Skipped — review_mode:off |
## Completeness
All 56 tasks completed and checked off in tasks.md.
**Implementation commits (15):**
```
dff74fc feat: 建立三断点 CSS 体系,替换单断点移动端样式
3a1c406 feat: MainLayout 三端布局重构,使用 antd Grid.useBreakpoint()
456261e feat: Dashboard 响应式网格,统计卡片/图表/工具栏适配三端
339ff47 feat: 学生管理字段拆分(学号/身份证分列),表格和工具栏响应式适配
49f8044 feat: 宿舍管理表格添加 scroll 横向滚动
db4fcf1 feat: 入住管理表格添加 scroll 横向滚动
b5a97ab feat: 费用录入两个表格添加 scroll 横向滚动
a5c4570 feat: 押金管理表格添加 scroll 横向滚动
4e6a3f4 feat: 账单管理表格添加 scroll详情内嵌表格也添加 scroll
8c555a4 feat: 教室管理表格添加 scroll 横向滚动
39b3df0 feat: 租赁方表格添加 scroll 横向滚动
a6165fd feat: 角色管理工具栏添加 flexWrap 响应式适配
ea42b72 feat: 权限一览工具栏添加 flexWrap 响应式适配
2137c7a feat: 账号管理工具栏添加 flexWrap 响应式适配
4993d2b feat: 登录卡片改为 maxWidth + calc 响应式宽度
```
**Changed files:** 17 (15 source + 2 documentation)
## Correctness — Requirement Implementation
| Requirement | Status | Evidence |
|-------------|--------|----------|
| 1. Three-breakpoint responsive system | ✅ | `index.css` @media rules + `MainLayout.tsx` useBreakpoint() |
| 2. Table horizontal scroll on narrow screens | ✅ | All 12 table pages have `scroll={{ x }}` |
| 3. Login page responsiveness | ✅ | `Login/index.tsx` maxWidth + calc |
| 4. Dashboard responsive grid | ✅ | `Dashboard/index.tsx` Col xs/sm/md |
| 5. Modal responsiveness | ✅ | `index.css` max-width: calc(100vw - 24px) |
| 6. Page toolbar responsive wrapping | ✅ | All pages have flexWrap + gap |
| 7. Student fields separation | ✅ | 学号/身份证 split into two columns |
| 8. Classroom schedule table scrolling | ✅ | Existing overflowX:auto + sticky column |
## Coherence — Design Adherence
| Design Decision | Status |
|----------------|--------|
| antd Grid.useBreakpoint() | ✅ Followed |
| CSS: antd Props first, @media fallback | ✅ Followed |
| Table scroll={{ x }} on all tables | ✅ Followed |
| Modal CSS max-width global constraint | ✅ Followed |
| Dashboard Col responsive breakpoints | ✅ Followed |
| ECharts width: 100% | ✅ Followed |
| Login card maxWidth + calc | ✅ Followed |
| Student field split with ellipsis | ✅ Followed |
## Issues
**CRITICAL:** 0
**WARNING:** 0
**SUGGESTION:** 0
## Final Assessment
All checks passed. No critical issues, no warnings. Ready for archive.

View File

@@ -2,6 +2,8 @@
comet_change: migrate-to-turborepo
role: technical-design
canonical_spec: openspec
archived-with: 2026-07-02-migrate-to-turborepo
status: final
---
# Migrate to Turborepo Monorepo — Technical Design

View File

@@ -0,0 +1,163 @@
---
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 无报错

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-03

View File

@@ -0,0 +1,95 @@
## Context
恭学教育基地管理后台是一个基于 React 19 + Ant Design v6 的单页应用,服务对象为基地管理人员。当前前端仅有一个 768px 的移动端断点(`MainLayout` 中),且页面级适配不完整:多列表格无横向滚动、仪表盘卡片使用硬编码 `Col span`、弹窗无宽度约束等。管理场景中操作人员可能使用手机、iPad/平板、桌面电脑等不同设备,需要统一的三端响应式体验。
**技术约束:**
- 不引入新的 UI 依赖,保持使用 Ant Design v6
- 不改动后端 API 和后端逻辑
- 使用纯 CSS`@media` queries+ antd 响应式 props`Row/Col` 断点、`Table scroll`
## Goals / Non-Goals
**Goals:**
- 建立统一的三断点体系:手机 `< 768px`、平板 `768-1024px`、桌面 `> 1024px`
- 所有页面的 `<Table>` 在小屏下可通过横向滚动查看全部列
- 仪表盘统计卡片在平板和手机端自动调整列数
- 登录页在手机上不溢出
- 弹窗在所有端侧不超出屏幕
- ECharts 图表响应容器宽度变化
- 学生管理页「学号/身份证」拆分为两列
- API/数据获取层不变,仅改 UI 渲染层
**Non-Goals:**
- 不更换组件库或引入 Tailwind CSS 等新样式框架
- 不做列响应式隐藏(表格列全部保留,靠横向滚动)
- 不改变路由和权限体系
- 不涉及服务端渲染或 SSR
- 不添加视觉主题切换能力
## Decisions
### 1. 断点定义与 CSS 组织
| 断点 | 范围 | 典型设备 |
|------|------|---------|
| `xs` (手机) | < 768px | iPhoneAndroid 手机 |
| `sm` (平板) | 768px - 1024px | iPad 竖屏小型平板 |
| `md+` (桌面) | > 1024px | 笔记本、台式显示器 |
**策略:**
- 全局样式放在 `index.css`,使用 `@media` 规则
- antd `Row/Col` 组件使用内置 `xs/sm/md/lg` 断点 props
- 避免组件内联 style 中的固定像素值,改为 CSS class 或 antd 响应式 props
**为什么不引入 CSS 变量/主题系统?**
当前项目规模适中(~16 页面),引入 CSS 变量体系增加复杂度但收益有限。直接用 `@media` queries + antd 响应式 props 即可覆盖。
### 2. 表格横向滚动策略
**决策:** 所有 `<Table>` 统一添加 `scroll={{ x: 'max-content' }}` 或基于列宽计算的 `x` 值,移动端通过手指滑动查看全部列。
**列宽优化:**
- 操作列固定宽度(`width: 120-200`),配合 `fixed: 'right'` 可选
- 数据列设置合理的 `width` 避免过窄或过宽
- 使用 `ellipsis: true` 防止长文本撑开列宽
**为什么不用 antd 的 `responsive` 列隐藏?**
用户明确要求保留全部列、用横向滚动。管理后台数据密集场景下,隐藏列可能导致信息缺失。
### 3. 布局与侧栏
**桌面(> 1024px** 保持当前 `Sider` + 内容区布局侧栏可折叠content margin 24px。
**平板768-1024px** `Sider` 默认折叠(`collapsed: true`减少侧栏占用宽度content margin 16px。
**手机(< 768px** 当前已有 `Drawer` 替代 `Sider`content margin 12px。
### 4. 仪表盘与图表
统计卡片:
```
xs={12} sm={12} md={6} // 手机: 2列, 平板: 2列, 桌面: 4列
```
图表卡片:
```
xs={24} sm={12} // 手机: 堆叠, 平板及以上: 并排
```
ECharts 通过 `echarts-for-react``style={{ width: '100%' }}` 自动跟随容器宽度。
### 5. 弹窗与表单
- Modal 添加 `width` 在桌面固定400-600平板/手机使用百分比或 `max-width` 约束
- 全局 CSS: `.ant-modal { max-width: calc(100vw - 32px); }`
- Form 保持 `layout="vertical"`,天然适配窄屏
## Risks / Trade-offs
| 风险 | 缓解 |
|------|------|
| 表格横向滚动在手机上交互不直观 | 添加 `scroll={{ x }}` 后 antd 自动显示滚动条;操作列可用 `fixed: 'right'` 固定 |
| ECharts 甘特图在窄屏可能挤缩 | 设置最小高度,必要时在容器上 `overflowX: auto` |
| 教室排期表31 天列)表格极宽 | 已有 `overflowX: auto`,优化列 minWidth 和 sticky 首列 |
| 修改涉及文件多(~18 个),可能引入 layout 抖动 | 每个页面改动后手动验证改动粒度小CSS + props回滚简单 |
## Open Questions
- 无。三端断点、表格策略、拆分字段均已与需求方确认。

View File

@@ -0,0 +1,30 @@
## Why
管理后台当前仅在布局层有一个 768px 的移动端断点,大多数页面使用固定列宽、硬编码 `Col span` 和多列表格,导致在手机和平板上文字溢出、按钮换行错位、表格内容被截断。需要为手机(< 768px)、平板768-1024px)、桌面> 1024px三个端侧做统一响应式适配确保所有界面文字不溢出、不强制换行。
## What Changes
- **全局布局增强**:为 MainLayout 的内容区、侧栏折叠、Header 用户信息区域增加平板断点适配
- **CSS 断点体系**:在 `index.css` 中建立三断点响应式体系(`@media` 规则),覆盖表格、卡片、按钮、弹窗等全局组件
- **全页面表格适配**:为所有页面的 `<Table>` 添加 `scroll={{ x }}` 确保窄屏横向滚动,列宽优化防止数据截断
- **仪表盘响应式**:将 `Col span={6}` 改为响应式断点(`xs/sm/md`ECharts 图表跟随窗口 resize
- **登录页适配**:登录卡片从固定宽度改为响应式最大宽度
- **工具栏/搜索栏适配**:统一所有页面顶部操作栏的 wrap 和 gap 行为
- **弹窗响应式**:所有 Modal 添加平板/手机下的最大宽度和高度约束
- **排期表适配**:教室排期的大 HTML 表格优化列宽和滚动体验
- **学生字段拆分**:将学生管理页的「学号/身份证」列拆分为「学号」和「身份证」两个独立列
- 保持使用 Ant Design v6 组件库,不引入新的 UI 依赖
## Capabilities
### New Capabilities
- `responsive-layout`: 管理后台三端(手机 < 768px / 平板 768-1024px / 桌面 > 1024px响应式布局包括全局 CSS 断点、布局适配、表格横向滚动、组件响应式行为
### Modified Capabilities
(无现有前端相关 spec不需要 delta spec
## Impact
- **受影响文件**: `apps/admin/src/` 下所有页面组件16 个页面 + 1 个布局)、`index.css`、部分组件文件
- **不涉及**: 后端 API、数据库 schema、部署配置、认证/权限逻辑
- **风险**: 低——改动限于 CSS 和组件 props不涉及业务逻辑变更

View File

@@ -0,0 +1,86 @@
## ADDED Requirements
### Requirement: Three-breakpoint responsive system
The admin frontend SHALL adapt its layout to three device tiers: mobile (< 768px), tablet (768-1024px), and desktop (> 1024px). All pages and components MUST render without text overflow, forced line wrapping, or content clipping at any breakpoint.
#### Scenario: Mobile layout (< 768px)
- **WHEN** viewport width is less than 768px
- **THEN** sidebar is replaced by a Drawer triggered via hamburger button
- **AND** content area padding reduces to 12px
- **AND** tables scroll horizontally with touch gesture
- **AND** dashboard stat cards display in 2-column grid
#### Scenario: Tablet layout (768-1024px)
- **WHEN** viewport width is between 768px and 1024px
- **THEN** sidebar defaults to collapsed state
- **AND** content area padding is 16px
- **AND** dashboard stat cards display in 2-column grid
- **AND** chart cards display side-by-side
#### Scenario: Desktop layout (> 1024px)
- **WHEN** viewport width is greater than 1024px
- **THEN** sidebar is fully visible and collapsible
- **AND** content area padding is 24px
- **AND** dashboard stat cards display in 4-column grid
- **AND** chart cards display side-by-side
### Requirement: Table horizontal scroll on narrow screens
All `<Table>` components SHALL support horizontal scrolling when content exceeds viewport width. The scroll behavior MUST be enabled via scroll={{ x }} prop, and all table columns MUST remain visible (no responsive column hiding).
#### Scenario: Wide table on mobile
- **WHEN** a table has more columns than fit within the viewport width
- **THEN** the table container renders a horizontal scrollbar
- **AND** users can scroll horizontally to view all columns
- **AND** action column (if present) remains accessible without scrolling via fixed position
### Requirement: Login page responsiveness
The login page card SHALL not overflow the viewport on any screen size. On mobile devices, the card MUST fit within the screen with comfortable margins.
#### Scenario: Login on small mobile screen (320px)
- **WHEN** viewport width is 320px
- **THEN** login card width does not exceed `calc(100vw - 32px)`
- **AND** the login form remains fully visible and usable
### Requirement: Dashboard responsive grid
Dashboard stat cards and chart cards SHALL use antd responsive Col breakpoints (xs/sm/md) instead of fixed span values. Charts SHALL re-render to fit container width on window resize.
#### Scenario: Dashboard on tablet
- **WHEN** viewing dashboard on a 800px wide tablet
- **THEN** stat cards render 2 per row
- **AND** pie chart and bar chart render side by side
- **AND** gantt chart fits within the content area width
### Requirement: Modal responsiveness
All Modal dialogs SHALL have a max-width constraint preventing overflow beyond the viewport on small screens.
#### Scenario: Modal on mobile
- **WHEN** a modal is opened on a viewport < 768px wide
- **THEN** the modal width does not exceed `calc(100vw - 24px)`
- **AND** the modal body has a max-height of 60vh with vertical scroll
- **AND** modal mask covers the full viewport
### Requirement: Page toolbar responsive wrapping
All page-level toolbars with search/filter/action controls SHALL wrap gracefully on narrow screens using flexWrap and gap spacing, preventing button group clipping or overlap.
#### Scenario: Toolbar with search and action buttons on tablet
- **WHEN** a page toolbar contains a search input group and action button group
- **AND** viewport width is 800px
- **THEN** toolbar items wrap to multiple lines without overflow
- **AND** all buttons remain clickable with adequate spacing
### Requirement: Student fields separation
The Students page SHALL display "学号" (student ID) and "身份证" (ID card number) as two separate table columns instead of a single combined column. Both columns SHALL support ellipsis truncation for long values.
#### Scenario: Student table column display
- **WHEN** viewing the student list
- **THEN** the table includes a "学号" column and a "身份证" column as separate headers
- **AND** long ID numbers are truncated with ellipsis and tooltip on hover
### Requirement: Classroom schedule table scrolling
The classroom schedule grid table SHALL support horizontal scrolling with a sticky first column (classroom name) to aid navigation when viewing beyond the visible date range.
#### Scenario: Schedule table on month with 31 days
- **WHEN** viewing a month schedule on a tablet (800px)
- **THEN** the classroom name column remains fixed on the left
- **AND** date columns scroll horizontally
- **AND** no text overflows or wraps within date cells

View File

@@ -0,0 +1,90 @@
# responsive-layout Specification
## Purpose
TBD - created by archiving change admin-responsive-adaptation. Update Purpose after archive.
## Requirements
### Requirement: Three-breakpoint responsive system
The admin frontend SHALL adapt its layout to three device tiers: mobile (< 768px), tablet (768-1024px), and desktop (> 1024px). All pages and components MUST render without text overflow, forced line wrapping, or content clipping at any breakpoint.
#### Scenario: Mobile layout (< 768px)
- **WHEN** viewport width is less than 768px
- **THEN** sidebar is replaced by a Drawer triggered via hamburger button
- **AND** content area padding reduces to 12px
- **AND** tables scroll horizontally with touch gesture
- **AND** dashboard stat cards display in 2-column grid
#### Scenario: Tablet layout (768-1024px)
- **WHEN** viewport width is between 768px and 1024px
- **THEN** sidebar defaults to collapsed state
- **AND** content area padding is 16px
- **AND** dashboard stat cards display in 2-column grid
- **AND** chart cards display side-by-side
#### Scenario: Desktop layout (> 1024px)
- **WHEN** viewport width is greater than 1024px
- **THEN** sidebar is fully visible and collapsible
- **AND** content area padding is 24px
- **AND** dashboard stat cards display in 4-column grid
- **AND** chart cards display side-by-side
### Requirement: Table horizontal scroll on narrow screens
All `<Table>` components SHALL support horizontal scrolling when content exceeds viewport width. The scroll behavior MUST be enabled via scroll={{ x }} prop, and all table columns MUST remain visible (no responsive column hiding).
#### Scenario: Wide table on mobile
- **WHEN** a table has more columns than fit within the viewport width
- **THEN** the table container renders a horizontal scrollbar
- **AND** users can scroll horizontally to view all columns
- **AND** action column (if present) remains accessible without scrolling via fixed position
### Requirement: Login page responsiveness
The login page card SHALL not overflow the viewport on any screen size. On mobile devices, the card MUST fit within the screen with comfortable margins.
#### Scenario: Login on small mobile screen (320px)
- **WHEN** viewport width is 320px
- **THEN** login card width does not exceed `calc(100vw - 32px)`
- **AND** the login form remains fully visible and usable
### Requirement: Dashboard responsive grid
Dashboard stat cards and chart cards SHALL use antd responsive Col breakpoints (xs/sm/md) instead of fixed span values. Charts SHALL re-render to fit container width on window resize.
#### Scenario: Dashboard on tablet
- **WHEN** viewing dashboard on a 800px wide tablet
- **THEN** stat cards render 2 per row
- **AND** pie chart and bar chart render side by side
- **AND** gantt chart fits within the content area width
### Requirement: Modal responsiveness
All Modal dialogs SHALL have a max-width constraint preventing overflow beyond the viewport on small screens.
#### Scenario: Modal on mobile
- **WHEN** a modal is opened on a viewport < 768px wide
- **THEN** the modal width does not exceed `calc(100vw - 24px)`
- **AND** the modal body has a max-height of 60vh with vertical scroll
- **AND** modal mask covers the full viewport
### Requirement: Page toolbar responsive wrapping
All page-level toolbars with search/filter/action controls SHALL wrap gracefully on narrow screens using flexWrap and gap spacing, preventing button group clipping or overlap.
#### Scenario: Toolbar with search and action buttons on tablet
- **WHEN** a page toolbar contains a search input group and action button group
- **AND** viewport width is 800px
- **THEN** toolbar items wrap to multiple lines without overflow
- **AND** all buttons remain clickable with adequate spacing
### Requirement: Student fields separation
The Students page SHALL display "学号" (student ID) and "身份证" (ID card number) as two separate table columns instead of a single combined column. Both columns SHALL support ellipsis truncation for long values.
#### Scenario: Student table column display
- **WHEN** viewing the student list
- **THEN** the table includes a "学号" column and a "身份证" column as separate headers
- **AND** long ID numbers are truncated with ellipsis and tooltip on hover
### Requirement: Classroom schedule table scrolling
The classroom schedule grid table SHALL support horizontal scrolling with a sticky first column (classroom name) to aid navigation when viewing beyond the visible date range.
#### Scenario: Schedule table on month with 31 days
- **WHEN** viewing a month schedule on a tablet (800px)
- **THEN** the classroom name column remains fixed on the left
- **AND** date columns scroll horizontally
- **AND** no text overflows or wraps within date cells