## 实施
### 阶段 1:统一导航栏
- [x] 1.1 创建统一导航栏模板
【目标对象】`frontend/includes/nav.php`(新建)
【修改目的】将所有 admin 页面硬编码的导航栏抽取为共享模板,解决各页面导航不一致的问题;同时修复 dashboard.php 中密码链接 `passwork.php` 的拼写错误
【修改方式】新建 PHP 文件,定义导航栏 HTML 结构,直接读取 `$role` 和 `$current_page` 变量(已由 `header.php` 第 17-19 行定义)来动态生成导航项和 active 状态
【相关依赖】`frontend/includes/header.php`(第 17-19 行已定义 `$current_page`、`$user_type`、`$role` 变量,在 include nav.php 之前已可用)
【修改内容】
- 直接使用 `$role` 和 `$current_page` 变量(无需参数传递,因为 header.php 在 nav.php 之前被 include)
- 导航项及角色条件统一为:
- 首页(dashboard):所有管理员可见
- 学生管理(students):所有管理员可见
- 操行分管理(conduct):$role==='班主任' || $role==='班长'
- 作业管理(homework):$role==='班主任' || $role==='学习委员'
- 考勤管理(attendance):$role==='班主任' || $role==='考勤委员'
- 科目管理(subjects):$role==='班主任' || $role==='学习委员'
- 管理员管理(admins):$role==='班主任'
- 历史记录(history):所有管理员可见
- 修改密码(password):所有管理员可见
- 根据 `$current_page`(值为不含 `.php` 后缀的文件名,如 `dashboard`、`students`)为当前页面对应的导航项添加 `active` class
- 密码链接统一写为 `password.php`(修复 dashboard 中 `passwork.php` 拼写错误)
- 导航栏外层容器沿用现有 `
` 结构
- [x] 1.2 各 admin 页面引入统一导航模板
【目标对象】所有 `frontend/admin/*.php` 页面
【修改目的】移除各页面硬编码的 `
...
` 块,替换为 `include nav.php`,统一导航栏
【修改方式】在以下每个页面中,找到 `
` 到对应的 `
` 之间的导航栏块,整块替换为 ``
【相关依赖】`frontend/includes/nav.php`(任务 1.1 创建)
【修改内容】
- `frontend/admin/dashboard.php`:替换第 25-43 行的 `
...
` 为 include nav.php
- `frontend/admin/students.php`:替换第 25-43 行的 `
...
` 为 include nav.php
- `frontend/admin/conduct.php`:替换第 31-47 行的 `
...
` 为 include nav.php
- `frontend/admin/homework.php`:替换第 31-47 行的 `
...
` 为 include nav.php(注意:此页面后续会在任务 2.2 完全重写,此处仅替换导航栏部分)
- `frontend/admin/attendance.php`:替换第 31-47 行的 `
...
` 为 include nav.php(注意:此页面后续会在任务 3.3 完全重写,此处仅替换导航栏部分)
- `frontend/admin/history.php`:替换第 25-43 行的 `
...
` 为 include nav.php
- `frontend/admin/subjects.php`:替换第 30-48 行的 `
...
` 为 include nav.php
- `frontend/admin/admins.php`:替换第 30-46 行的 `
...
` 为 include nav.php
- `frontend/admin/password.php`:替换第 25-43 行的 `
...
` 为 include nav.php
- 替换后需确认 include 语句位于 `include header.php;` 之后、页面主体内容之前
### 阶段 2:作业管理改版
- [x] 2.1 清理 `admin.js` 中废弃的作业管理函数
【目标对象】`frontend/assets/js/admin.js`
【修改目的】移除作业管理改版后不再使用的旧作业管理函数,避免全局函数污染和潜在冲突
【修改方式】删除第 174-220 行的三个函数:`showAddAssignmentModal()`、`loadSubjectsForSelect()`、`submitAddAssignment()`
【相关依赖】无(homework.php 将在任务 2.2 完全重写,不再依赖这些全局函数)
【修改内容】
- 删除第 174-178 行的 `showAddAssignmentModal()` 函数
- 删除第 180-192 行的 `loadSubjectsForSelect()` 函数
- 删除第 194-220 行的 `submitAddAssignment()` 函数
- 注意:`admin.js` 中其他通用函数(如 `submitBatchPoints()`、`closeModal()`、`escapeHtml()`、`toggleSelectAll()`)保持不变,仍被 conduct.php 和 students.php 使用
- [x] 2.2 重写作业管理前端页面
【目标对象】`frontend/admin/homework.php`
【修改目的】将作业发布/提交管理模式改为单纯的加减操行分模式,交互方式参照 `conduct.php`
【修改方式】完全重写页面 HTML 内容和 `` 移到内联script之前;删除局部 `const API_BASE_URL` 和 `const JWT_STORAGE_KEY`/`USER_STORAGE_KEY`,改用 `window.API_BASE_URL = ''` 等全局变量(在common.js加载之前设置);将 `hw.subject` 改为 `hw.subject_name`
- save_session.php: 第106行 `$_SESSION['student_id'] = $data['user_id'];` 改为从请求中获取实际student_id:`$_SESSION['student_id'] = $data['student_id'] ?? $data['user_id'];`;同时添加student_id到requiredFields验证(仅学生时必须)
- index.php: 登录成功后save_session调用中添加 `student_id: userData.student_id` 参数
- student/attendance.php: 第21行 `$student_id = $_SESSION['student_id'];` 保持不变(修复save_session后此值会正确)
- admin/homework.php: 删除第176行重复的 `loadStudents();` 调用
- config.php: 第61行 `define('ICP_ENABLED', $config['ICP_ENABLED'] === 'false');` 改为 `define('ICP_ENABLED', $config['ICP_ENABLED'] !== 'false');`
- student/conduct_history.php: 文件为空,需要重定向到dashboard或创建基本页面。最简方案:创建一个重定向到 /student/dashboard.php 的页面
【目标对象】`backend/models/attendance.py`、`backend/services/attendance_service.py`、`backend/models/conduct.py`、`backend/services/conduct_service.py`、`backend/models/homework.py`、`backend/services/homework_service.py`、`backend/models/student.py`、`backend/middleware/permission.py`、`backend/services/auth_service.py`、`backend/schemas/student.py`、`backend/schemas/admin.py`、`backend/services/student_service.py`、`backend/routes/student.py`
【修改目的】数据库 schema(单班级系统)中 `students` 和 `assignments` 表没有 `class_id` 列,但后端代码中大量 SQL 引用了该列,导致 MySQL 报错 → 500 Internal Server Error。同时 `PermissionChecker.get_user_subject_ids()` 和 `check_can_manage_student()` 方法不存在但被调用。
【修改方式】全面移除所有 `class_id` 引用(单班级系统不需要),添加缺失的方法
【修改内容】
- attendance.py: get_class_records 移除 class_id 参数和 WHERE 条件
- attendance_service.py: 移除 class_id 传参和 check_can_manage_student 调用
- conduct.py: 移除 class_id 过滤条件
- conduct_service.py: 移除 class_id 传参和 check_can_manage_student 调用
- homework.py: 所有方法移除 class_id,get_assignments_by_class 重命名为 get_all_assignments
- homework_service.py: 移除 class_id 传参
- student.py: create 方法移除 class_id 参数和 INSERT 列
- permission.py: 添加 get_user_subject_ids 和 check_can_manage_student 方法
- auth_service.py: 移除 class_id 和 class_name 引用
- schemas/student.py 和 schemas/admin.py: 移除 class_id 和 class_name 字段
- student_service.py 和 routes/student.py: 移除 class_id 参数
- [x] 12.3 修复CRITICAL: total_points在所有Service中从未更新(操行分系统完全失效)
【目标对象】`backend/services/conduct_service.py`、`backend/services/attendance_service.py`、`backend/services/homework_service.py`
【修改目的】`StudentModel.update_total_points()` 方法已存在但从未被调用,导致 `students.total_points` 永远保持初始值60分,排行榜、仪表盘、家长端显示的所有总分都是错误的
【修改方式】
- conduct_service.py add_points: 在 `ConductModel.create_record()` 后添加 `await StudentModel.update_total_points(student_id, points_change)`
- conduct_service.py revoke_record: 重写撤销逻辑,先获取原记录,撤销后调用 `await StudentModel.update_total_points(record["student_id"], -record["points_change"])` 反向恢复总分
- attendance_service.py add_attendance: 在 `ConductModel.create_record()` 后添加 `await StudentModel.update_total_points(student_id, points_change)`
- homework_service.py update_submission_status: 在 `ConductModel.create_record()` 后添加 `await StudentModel.update_total_points(submission["student_id"], points_change)`
- [x] 12.4 修复前端: student/homework.php字段名 + nav.php劳动委员 + parent/attendance.php死链
【目标对象】`frontend/student/homework.php`、`frontend/includes/nav.php`、`frontend/parent/attendance.php`
【修改目的】1) homework.php中hw.subject字段名与后端API不匹配;2) 劳动委员无法在导航栏看到操行分管理入口(README要求±1分权限);3) parent/attendance.php有指向不存在的/parent/homework.php的死链接
【修改方式】
- student/homework.php 第56行: `hw.subject` → `hw.subject_name`
- nav.php 第4行: 添加 `|| $role === '劳动委员'` 到操行分管理导航条件
- parent/attendance.php: 删除指向不存在的 /parent/homework.php 的死链接,导航只保留"首页"和"考勤记录"
- [x] 12.5 修复学生端导航死链接: 3个页面的"操行分"链接指向不存在的/student/conduct.php
【目标对象】`frontend/student/homework.php`、`frontend/student/attendance.php`、`frontend/student/password.php`
【修改目的】学生端3个子页面导航栏中的"操行分"链接指向 `/student/conduct.php`,但实际文件名是 `conduct_history.php`,导致404
【修改方式】
- password.php 第26行: `/student/conduct.php` → `/student/conduct_history.php`
- [x] 12.6 修复劳动委员页面级权限被拦截 + 仪表盘快捷操作缺失
【目标对象】`frontend/admin/conduct.php`、`frontend/admin/dashboard.php`
【修改目的】README规定劳动委员有操行分管理权限(±1分),但conduct.php页面级权限检查只允许班主任和班长访问,劳动委员会被重定向到dashboard;dashboard.php快捷操作也缺少劳动委员
【修改方式】
- conduct.php 第23行: `['班主任', '班长']` → `['班主任', '班长', '劳动委员']`
- conduct.php 第115行: 分数变动提示文字改为 if/elseif/else 结构,劳动委员显示"劳动委员仅限±1分"
- dashboard.php 第61行: 快捷操作条件添加劳动委员
- attendance.php 第27行: `/student/conduct.php` → `/student/conduct_history.php`
- password.php 第26行: `/student/conduct.php` → `/student/conduct_history.php`