diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 100644 index 0000000..f3fca9a --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1,10 @@ + +## 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 ""` prints the same output. + +If there is no `.codegraph/` directory, skip CodeGraph entirely — indexing is the user's decision. + diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..1e9033f --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,19 @@ +{ + "permissions": { + "allow": [ + "mcp__codegraph__*" + ] + }, + "hooks": { + "UserPromptSubmit": [ + { + "hooks": [ + { + "type": "command", + "command": "codegraph prompt-hook" + } + ] + } + ] + } +} diff --git a/.gitignore b/.gitignore index 7980f69..530fccb 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,4 @@ apps/server/node_modules/ apps/server/dist/ apps/admin/node_modules/ apps/admin/dist/ +.codegraph/ diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..87ca7de --- /dev/null +++ b/.mcp.json @@ -0,0 +1,12 @@ +{ + "mcpServers": { + "codegraph": { + "type": "stdio", + "command": "codegraph", + "args": [ + "serve", + "--mcp" + ] + } + } +} diff --git a/docs/superpowers/plans/2026-07-02-migrate-to-turborepo.md b/docs/superpowers/plans/2026-07-02-migrate-to-turborepo.md index cf55350..58386da 100644 --- a/docs/superpowers/plans/2026-07-02-migrate-to-turborepo.md +++ b/docs/superpowers/plans/2026-07-02-migrate-to-turborepo.md @@ -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: 验证 diff --git a/docs/superpowers/plans/2026-07-03-admin-responsive-adaptation.md b/docs/superpowers/plans/2026-07-03-admin-responsive-adaptation.md index dbee0a3..dfd318b 100644 --- a/docs/superpowers/plans/2026-07-03-admin-responsive-adaptation.md +++ b/docs/superpowers/plans/2026-07-03-admin-responsive-adaptation.md @@ -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 diff --git a/docs/superpowers/reports/2026-07-02-add-tsbuildinfo-to-gitignore-verify.md b/docs/superpowers/reports/2026-07-02-add-tsbuildinfo-to-gitignore-verify.md new file mode 100644 index 0000000..b3e188d --- /dev/null +++ b/docs/superpowers/reports/2026-07-02-add-tsbuildinfo-to-gitignore-verify.md @@ -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. diff --git a/docs/superpowers/reports/2026-07-03-admin-responsive-adaptation-verify.md b/docs/superpowers/reports/2026-07-03-admin-responsive-adaptation-verify.md new file mode 100644 index 0000000..b6bcda7 --- /dev/null +++ b/docs/superpowers/reports/2026-07-03-admin-responsive-adaptation-verify.md @@ -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. diff --git a/docs/superpowers/specs/2026-07-02-migrate-to-turborepo-design.md b/docs/superpowers/specs/2026-07-02-migrate-to-turborepo-design.md index 9202ae6..767efe3 100644 --- a/docs/superpowers/specs/2026-07-02-migrate-to-turborepo-design.md +++ b/docs/superpowers/specs/2026-07-02-migrate-to-turborepo-design.md @@ -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 diff --git a/docs/superpowers/specs/2026-07-03-admin-responsive-adaptation-design.md b/docs/superpowers/specs/2026-07-03-admin-responsive-adaptation-design.md new file mode 100644 index 0000000..b880cb6 --- /dev/null +++ b/docs/superpowers/specs/2026-07-03-admin-responsive-adaptation-design.md @@ -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 → │ +│ ├─ 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 表格横向滚动 + +所有 `` 统一添加 `scroll={{ x }}`。具体值: +- 列少(≤6 列):`scroll={{ x: 'max-content' }}` 或省略(antd 自动处理) +- 列中(7-10 列):`scroll={{ x: 800 }}` +- 列多(>10 列或含长文本列):`scroll={{ x: 1000 }}` 或更大 + +操作列(最后一列)使用 `width` 固定宽度,必要时添加 `fixed: 'right'` 在宽表场景下提升体验。 + +### 3.4 Dashboard 响应式网格 + +``` +统计卡片 (4 张): + // 手机2列 平板2列 桌面4列 + +图表卡片 (2 张): + // 手机堆叠 平板及以上并排 +``` + +顶部工具栏(标题 + DatePicker)在小屏下从 `flex` 横向排列改为 `flexDirection: 'column'` 堆叠。 + +### 3.5 ECharts 图表 + +通过 `echarts-for-react` 的内置 `ResizeObserver` 自动适配: +```tsx + +``` +容器宽度由 antd `Col` 响应式断点控制,图表自动跟随。甘特图动态高度逻辑不变(`Math.max(300, data.length * 40)`)。 + +### 3.6 弹窗适配 + +**全局 CSS(index.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 `
` 含 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 无报错 diff --git a/openspec/changes/add-tsbuildinfo-to-gitignore/.openspec.yaml b/openspec/changes/archive/2026-07-02-add-tsbuildinfo-to-gitignore/.openspec.yaml similarity index 100% rename from openspec/changes/add-tsbuildinfo-to-gitignore/.openspec.yaml rename to openspec/changes/archive/2026-07-02-add-tsbuildinfo-to-gitignore/.openspec.yaml diff --git a/openspec/changes/add-tsbuildinfo-to-gitignore/design.md b/openspec/changes/archive/2026-07-02-add-tsbuildinfo-to-gitignore/design.md similarity index 100% rename from openspec/changes/add-tsbuildinfo-to-gitignore/design.md rename to openspec/changes/archive/2026-07-02-add-tsbuildinfo-to-gitignore/design.md diff --git a/openspec/changes/add-tsbuildinfo-to-gitignore/proposal.md b/openspec/changes/archive/2026-07-02-add-tsbuildinfo-to-gitignore/proposal.md similarity index 100% rename from openspec/changes/add-tsbuildinfo-to-gitignore/proposal.md rename to openspec/changes/archive/2026-07-02-add-tsbuildinfo-to-gitignore/proposal.md diff --git a/openspec/changes/add-tsbuildinfo-to-gitignore/tasks.md b/openspec/changes/archive/2026-07-02-add-tsbuildinfo-to-gitignore/tasks.md similarity index 100% rename from openspec/changes/add-tsbuildinfo-to-gitignore/tasks.md rename to openspec/changes/archive/2026-07-02-add-tsbuildinfo-to-gitignore/tasks.md diff --git a/openspec/changes/migrate-to-turborepo/.openspec.yaml b/openspec/changes/archive/2026-07-02-migrate-to-turborepo/.openspec.yaml similarity index 100% rename from openspec/changes/migrate-to-turborepo/.openspec.yaml rename to openspec/changes/archive/2026-07-02-migrate-to-turborepo/.openspec.yaml diff --git a/openspec/changes/migrate-to-turborepo/design.md b/openspec/changes/archive/2026-07-02-migrate-to-turborepo/design.md similarity index 100% rename from openspec/changes/migrate-to-turborepo/design.md rename to openspec/changes/archive/2026-07-02-migrate-to-turborepo/design.md diff --git a/openspec/changes/migrate-to-turborepo/proposal.md b/openspec/changes/archive/2026-07-02-migrate-to-turborepo/proposal.md similarity index 100% rename from openspec/changes/migrate-to-turborepo/proposal.md rename to openspec/changes/archive/2026-07-02-migrate-to-turborepo/proposal.md diff --git a/openspec/changes/migrate-to-turborepo/specs/monorepo-structure/spec.md b/openspec/changes/archive/2026-07-02-migrate-to-turborepo/specs/monorepo-structure/spec.md similarity index 100% rename from openspec/changes/migrate-to-turborepo/specs/monorepo-structure/spec.md rename to openspec/changes/archive/2026-07-02-migrate-to-turborepo/specs/monorepo-structure/spec.md diff --git a/openspec/changes/migrate-to-turborepo/specs/oxlint-oxfmt-toolchain/spec.md b/openspec/changes/archive/2026-07-02-migrate-to-turborepo/specs/oxlint-oxfmt-toolchain/spec.md similarity index 100% rename from openspec/changes/migrate-to-turborepo/specs/oxlint-oxfmt-toolchain/spec.md rename to openspec/changes/archive/2026-07-02-migrate-to-turborepo/specs/oxlint-oxfmt-toolchain/spec.md diff --git a/openspec/changes/migrate-to-turborepo/specs/turborepo-pipeline/spec.md b/openspec/changes/archive/2026-07-02-migrate-to-turborepo/specs/turborepo-pipeline/spec.md similarity index 100% rename from openspec/changes/migrate-to-turborepo/specs/turborepo-pipeline/spec.md rename to openspec/changes/archive/2026-07-02-migrate-to-turborepo/specs/turborepo-pipeline/spec.md diff --git a/openspec/changes/migrate-to-turborepo/tasks.md b/openspec/changes/archive/2026-07-02-migrate-to-turborepo/tasks.md similarity index 100% rename from openspec/changes/migrate-to-turborepo/tasks.md rename to openspec/changes/archive/2026-07-02-migrate-to-turborepo/tasks.md diff --git a/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/.openspec.yaml b/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/.openspec.yaml new file mode 100644 index 0000000..43e65ca --- /dev/null +++ b/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-07-03 diff --git a/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/design.md b/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/design.md new file mode 100644 index 0000000..6a33896 --- /dev/null +++ b/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/design.md @@ -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` +- 所有页面的 `
` 在小屏下可通过横向滚动查看全部列 +- 仪表盘统计卡片在平板和手机端自动调整列数 +- 登录页在手机上不溢出 +- 弹窗在所有端侧不超出屏幕 +- ECharts 图表响应容器宽度变化 +- 学生管理页「学号/身份证」拆分为两列 +- API/数据获取层不变,仅改 UI 渲染层 + +**Non-Goals:** +- 不更换组件库或引入 Tailwind CSS 等新样式框架 +- 不做列响应式隐藏(表格列全部保留,靠横向滚动) +- 不改变路由和权限体系 +- 不涉及服务端渲染或 SSR +- 不添加视觉主题切换能力 + +## Decisions + +### 1. 断点定义与 CSS 组织 + +| 断点 | 范围 | 典型设备 | +|------|------|---------| +| `xs` (手机) | < 768px | iPhone、Android 手机 | +| `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. 表格横向滚动策略 + +**决策:** 所有 `
` 统一添加 `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 + +- 无。三端断点、表格策略、拆分字段均已与需求方确认。 diff --git a/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/proposal.md b/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/proposal.md new file mode 100644 index 0000000..7f2b0bd --- /dev/null +++ b/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/proposal.md @@ -0,0 +1,30 @@ +## Why + +管理后台当前仅在布局层有一个 768px 的移动端断点,大多数页面使用固定列宽、硬编码 `Col span` 和多列表格,导致在手机和平板上文字溢出、按钮换行错位、表格内容被截断。需要为手机(< 768px)、平板(768-1024px)、桌面(> 1024px)三个端侧做统一响应式适配,确保所有界面文字不溢出、不强制换行。 + +## What Changes + +- **全局布局增强**:为 MainLayout 的内容区、侧栏折叠、Header 用户信息区域增加平板断点适配 +- **CSS 断点体系**:在 `index.css` 中建立三断点响应式体系(`@media` 规则),覆盖表格、卡片、按钮、弹窗等全局组件 +- **全页面表格适配**:为所有页面的 `
` 添加 `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,不涉及业务逻辑变更 diff --git a/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/specs/responsive-layout/spec.md b/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/specs/responsive-layout/spec.md new file mode 100644 index 0000000..ade84db --- /dev/null +++ b/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/specs/responsive-layout/spec.md @@ -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 `
` 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 diff --git a/openspec/changes/admin-responsive-adaptation/tasks.md b/openspec/changes/archive/2026-07-03-admin-responsive-adaptation/tasks.md similarity index 100% rename from openspec/changes/admin-responsive-adaptation/tasks.md rename to openspec/changes/archive/2026-07-03-admin-responsive-adaptation/tasks.md diff --git a/openspec/specs/responsive-layout/spec.md b/openspec/specs/responsive-layout/spec.md new file mode 100644 index 0000000..3604daf --- /dev/null +++ b/openspec/specs/responsive-layout/spec.md @@ -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 `
` 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 +