LoveChengke
|
11008928a1
|
fix(island,homework,schedule,web): 16 项反馈修复(联合通知点不开 / 设置不生效 / 红点位置 / 看板当天且铺满 / 单双周与周数可调 / Web 手机端与批量通知等)
一、灵动岛
- ①「紧急通知后来了新作业,收起再点开不了新作业」根因有二,都已修:
(a) active 仍是紧急那条,点击只会反复打开它 —— 现在点击胶囊优先打开**最新**那条未处理消息(队列里更晚的);
(b) 上课时段 syncWindow 会把普通通知立刻隐藏(表现为点了没反应)—— 新增 explicitShowId,
"用户主动点开"的那条守卫放行(岛完全隐藏时仍严格不打扰)。
冒烟新增「紧急通知后来了新作业:收起再点击打开的是新作业(联合通知回归)」。
- ② 设置实时预览/保存:补「设置页真实链路」断言(window.desktop.islandSetAppearance → IPC → 主进程 →
渲染进程 CSS 变量 + 窗口尺寸),并断言"岛显示中改尺寸立即生效"(实测均通过)。
- ③ 未读红点移到「通知」图标右上角(此前在文字后面),并加 DOM 几何断言(dx>0 且 dy<0,
没有未读时自动造一条未读通知再断言、断言后删除)。
- 冒烟稳定性:新增 island.setBlurCollapseEnabled()(默认开),测试期间关掉"失焦收起",
避免系统抢焦点导致展开态被收回的随机失败;专门验证失焦的用例仍临时打开。
二、作业看板(学生端)
- ⑥ 只看当天:新增「只看今天」开关(默认开),按 createdAt 的本地日期过滤,昨天的过期作业不再混入。
- ⑧ 完整显示:卡片同时渲染标题 + 作业要求全文(列表模式也加「作业要求」列)。
- ⑨ 铺满不滚动:看板外层高度固定 + overflow hidden,按内容/可用高度算缩放系数用 transform: scale 适配
(工具栏显示当前缩放比例),页面本身不出现滚动条。
- ⑦ 全屏看板标题栏用 #header 插槽:标题左对齐、当天日期时间绝对居中(受「显示时间」开关控制,每分钟刷新)。
三、课表与周数
- ⑤ 学期周数可调:新增 Class.termWeeks(默认 20,迁移 + 维护脚本),班主任在班级管理里改;
GET /api/dashboard/term?classId= 返回该班 maxWeek,课表周次下拉与新建课表的默认 weekEnd 都按它来
(不再固定 30 周)。
- ⑩ 课表管理只保留「导入 ClassIsland 课程表」入口(时间表由课程表 JSON 的 TimeLayouts 一并带入),
「导入时间配置」按钮下线;ui-smoke 第 7.7 段改为断言新弹窗(解析 4 行 + 单双周标签 + 旧入口已下线)。
四、以班级为单位(⑬)与 Web 端
- 个人学生账号登录停用:POST /api/auth/login 对 role=STUDENT 返回 403(改用班级码 + 班级密码);
学生行仍作为个人数据记录键由班级会话代全班读写;e2e 全面切换到班级会话并新增该断言。
- ④ 作业科目过少:新增共享 SUBJECT_CATALOG(16 个常见科目)+ 种子课程扩到全科目;
Web 作业发布弹窗可选「其他科目(新建)」,提交前自动建课(同名复用)。
- ⑪ 通知支持多班批量发布(多选 + 逐班发布 + 汇总结果 + 二次确认覆盖所有选中班);
⑫ 单班只显示已读情况、跨班才显示已读率;⑭ 手机端课表可横向滚动看全 7 天;
⑮ 手机端已连接不再显示孤立绿点(仅未连接时显示文字标签);⑯ 手机端「叫人/发布通知」按钮同宽左对齐;
⑬ Web 学生管理去掉「用户名」列(新建自动生成学号式用户名,导入仍支持显式指定)。
验证:verify:e2e 149/149、verify:web 20/20、verify:desktop 75/75(复跑 68/68,打包便携版 75/75 packaged=true)、
typecheck / lint / format 全绿;服务端与 Web 已重新打包并部署到本机安装目录。
|
2026-09-13 08:39:11 +08:00 |
|
LoveChengke
|
1073436ad6
|
feat(class-account): 学生端主体改为班级(班级码 + 班级密码)+ 数据按班级隔离
服务端:
- Class 新增 code(唯一)/passwordHash 与迁移(老数据回填 C00001 形式, 未设密码禁止登录)
- POST /auth/class-login: 班级码 + 班级密码 -> classSession 会话(sub=classId)
- PATCH /classes/:id/class-account: 管理员改班级码/重置密码(唯一性、格式校验)
- auth 中间件/socket 握手支持班级会话(sub 为 classId, 回查 Class 表, 加入 user:{classId} 房间)
- lib/session.ts: 班级设备代全班操作(通知已读/作业完成/成绩总览按全班读写), 普通学生账号行为不变
- 叫人消息同时广播到 user:{classId}, 班级设备立即上岛
- 班级列表/详情按权限返回班级码与密码状态(哈希不外泄)
客户端:
- 登录页改为班级码 + 班级密码(个人学生入口移除, /auth/login 接口保留兼容)
- 作业按钮/成绩标题按班级会话显示(全班标记完成 / 本班成绩)
- 冒烟脚本自动准备班级账号凭据(兼容全新与升级安装)
Web 管理端:
- 班级管理新增「班级账号」列与设置弹窗(改班级码/重置密码/随机生成)
- 新建班级可选自定义班级码, 默认由服务端生成
验证: verify:e2e 125/125(新增班级账号 18 项) verify:web 18/18 verify:desktop 40/40
(login=高一(1)班 classSession=true)
文档: README 新增「学生端班级账号」章节、API/迁移/验收/默认账号更新; 安装包 README 同步
|
2026-09-12 15:51:08 +08:00 |
|
LoveChengke
|
30e4c36809
|
feat(rbac): 落地角色权限模型(需求 7)——班级/人员/名单/成绩收紧到管理员,班主任管本班课表,科任仅作业·叫人·通知
## 权限矩阵(前后端共用一份)
- 新增 `packages/shared/src/permissions.ts`:`ClassRole`(ADMIN/HEAD/SUBJECT/STUDENT/NONE)、
`resolveClassRole()`、`canManageClasses/AssignTeachers/Roster/Schedule/Courses/PublishContent/ManageGrades/Import`
与 `PERMISSION_MATRIX`(README 与验收脚本据此展开)。
- 后端 `lib/access.ts`:新增 `resolveUserClassRole()`(`Class.teacherId` → 班主任,`ClassTeacher` → 科任)
与 `assertCanManageClasses/AssignTeachers/Roster/Schedule/PublishContent/ManageGrades`;
各 service 在**服务层**断言(路由仅做角色过滤),越权统一 403。
- 收紧项:班级增删改、班主任/科任分配、学生名单与账号 → 仅 ADMIN;
课表/课程增删改 → ADMIN 或本班班主任;成绩录入/修改/批量 → 仅 ADMIN(按需求清单);
作业/通知/叫人 → ADMIN、班主任、科任皆可。
- 读权限保持不变:教师仍可查看自己班级的课表/作业/通知/成绩列表与统计。
## 前端按同一矩阵隐藏入口
- 侧边栏:教师端不再显示「班级管理 / 学生管理 / 成绩录入」(管理员仍是 7 项)。
- 班级页:新建/编辑/删除按钮仅管理员可见;课表页:增删改按钮仅"管理员或本班班主任"可见;
成绩页:录入/批量/删除按钮仅管理员可见。
- **叫人入口调整**:教师需要叫人,而「学生管理」是管理员专属,因此教师入口移到
「通知发布 → 叫人」(选班级 → 选学生 → 快捷短语/自定义消息;名单走 `/classes/:id/students`,
不使用管理员专属的 `/students`);管理员在学生管理页仍保留逐行「叫人」。
## 顺手修掉的两个真实缺陷
- `NotificationsView.openCreate()`:班级列表异步加载期间点「发布通知」会导致「目标班级」为空、
校验失败且**静默不发布**;现在打开弹窗前会确保班级已加载(冒烟同步等待下拉就绪)。
- `desktop-client/scripts/smoke.mjs`:上一次冒烟被强杀后配置目录仍被句柄占用,`rmSync` 报 ENOTEMPTY
直接让冒烟启动失败;改为按进程号使用独立目录并容错清理。
## 验证
- `pnpm verify:e2e` **82/82** ✅:新增 14 项角色权限断言(班主任/科任建班被拒、班主任删班被拒、
班主任/科任分配人员被拒、管理员分配与取消成功、科任管理课表被拒、科任可布置作业、
科任/班主任录入成绩被拒、管理员录入成功),并把历史用例中"仅管理员可执行"的操作切到管理员令牌。
- `pnpm verify:web` **17/17** ✅:新增「教师端隐藏无权入口」断言(可见菜单=仪表盘/课表/作业/通知,
越权入口=[]),叫人入口改到通知页后仍验证弹窗、8 条快捷短语、自定义输入与可选中态。
- `pnpm verify:desktop` **34/34** ✅;`lint` / `format:check` / `typecheck` 全绿。
- 数据清理:清掉历史遗留的测试班级与 4 条探针课表,演示数据恢复为 3 个班级。
|
2026-09-12 15:02:02 +08:00 |
|
LoveChengke
|
f759aac0a2
|
feat(web-admin): 手机小屏适配(1Panel 风格抽屉导航)并补齐移动端自动化验证
## 布局与交互(沿用 1Panel 风格)
- 新增 `src/composables/useResponsive.ts`:断点 768 / 992px + resize/orientationchange 监听
- `AdminLayout.vue`:
- >992px 桌面保持原样(210px 深色侧栏 + 顶栏连接状态 + "已接收 N 条实时事件")
- <=768px 手机:侧边栏不再渲染,顶栏出现汉堡按钮(`aria-expanded` 标记状态),
点击唤出 240px 深色抽屉菜单,点菜单项自动收起;顶栏显示当前页标题,
用户菜单收成头像图标(身份信息移入下拉菜单首行)
- 复用同一套 `.ch-sidebar` 样式,抽屉内容与桌面侧栏视觉一致
- `styles/index.css` 增加全局响应式规则:工具栏控件铺满整行、`.table-card` 表格卡片内横向滚动、
弹窗 `calc(100vw - 24px)`、消息框/抽屉自适应、`.stat-grid` 小屏两列、分页居中、标签页可横滑
- 各视图:7 个表格卡片加 `.table-card`;班级详情/作业详情的 `el-descriptions` 小屏降为单列;
登录页卡片自适应宽度并加安全内边距
## 自动化验证(scripts/ui-smoke)
- 新增 `runMobileChecks`:把窗口真实缩到 390×844,用真实点击验证 7 项——
侧边栏收起 + 汉堡出现、抽屉滑出且菜单完整、抽屉内点击"通知发布"跳转并收起、
页面无横向溢出(表格自身滚动不计入)、表格在卡片内可滚动、工具栏控件铺满、弹窗宽度自适应
- 移动端截图留档到 `docs/screenshots/web-mobile/`(`UI_SMOKE_SHOTS_DIR` 可覆盖)
- 踩坑修复:隐藏窗口下 Chromium 会冻结 CSS transition,Vue `<Transition>` 收不到 transitionend,
Element Plus 抽屉会卡在 `enter-from`(表现为"点了没反应")——移动端检查改为 `showInactive()` 并断言
"抽屉滑到位/收起到位",而不是只看元素是否存在
## 安装包升级健壮性
- `scripts/nsis/server-installer.nsi`:覆盖安装前先 `RMDir /r web|server|node_modules`,
避免旧 hash 分片、旧 dist 模块、旧依赖残留导致"新旧版本混装"
(此前 web/assets 里累积了 4 份 AdminLayout 分片)
## 验证结果(均在安装后的生产实例上)
- `pnpm verify:web` 15/15 ✅(8 项原有 + 7 项移动端)
- `pnpm verify:e2e` 62/62 ✅
- 覆盖安装:`.env` 与数据库保持不变,`web/assets` 只剩当前版本分片,服务 `healthz` 正常
- `pnpm lint` / `format:check` / `typecheck` 全部通过
|
2026-09-12 10:09:11 +08:00 |
|
LoveChengke
|
84ab49de10
|
feat: 班级小助手 阶段1-3(monorepo + 后端 REST/Socket.IO + Web 管理端)
|
2026-09-11 21:57:38 +08:00 |
|