157 lines
14 KiB
Markdown
157 lines
14 KiB
Markdown
## 实施
|
||
|
||
### 阶段 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` 拼写错误)
|
||
- 导航栏外层容器沿用现有 `<div class="nav">` 结构
|
||
|
||
- [x] 1.2 各 admin 页面引入统一导航模板
|
||
【目标对象】所有 `frontend/admin/*.php` 页面
|
||
【修改目的】移除各页面硬编码的 `<div class="nav">...</div>` 块,替换为 `include nav.php`,统一导航栏
|
||
【修改方式】在以下每个页面中,找到 `<div class="nav">` 到对应的 `</div>` 之间的导航栏块,整块替换为 `<?php include __DIR__ . '/../includes/nav.php'; ?>`
|
||
【相关依赖】`frontend/includes/nav.php`(任务 1.1 创建)
|
||
【修改内容】
|
||
- `frontend/admin/dashboard.php`:替换第 25-43 行的 `<div class="nav">...</div>` 为 include nav.php
|
||
- `frontend/admin/students.php`:替换第 25-43 行的 `<div class="nav">...</div>` 为 include nav.php
|
||
- `frontend/admin/conduct.php`:替换第 31-47 行的 `<div class="nav">...</div>` 为 include nav.php
|
||
- `frontend/admin/homework.php`:替换第 31-47 行的 `<div class="nav">...</div>` 为 include nav.php(注意:此页面后续会在任务 2.2 完全重写,此处仅替换导航栏部分)
|
||
- `frontend/admin/attendance.php`:替换第 31-47 行的 `<div class="nav">...</div>` 为 include nav.php(注意:此页面后续会在任务 3.3 完全重写,此处仅替换导航栏部分)
|
||
- `frontend/admin/history.php`:替换第 25-43 行的 `<div class="nav">...</div>` 为 include nav.php
|
||
- `frontend/admin/subjects.php`:替换第 30-48 行的 `<div class="nav">...</div>` 为 include nav.php
|
||
- `frontend/admin/admins.php`:替换第 30-46 行的 `<div class="nav">...</div>` 为 include nav.php
|
||
- `frontend/admin/password.php`:替换第 25-43 行的 `<div class="nav">...</div>` 为 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>` 中的 JavaScript 逻辑(保留文件头部的 PHP 鉴权部分和 include 结构)
|
||
【相关依赖】
|
||
- `frontend/includes/nav.php`(任务 1.1,导航栏引入)
|
||
- `frontend/assets/js/admin.js`(提供 `submitBatchPoints()`、`showBatchPointsModal()`、`closeModal()`、`escapeHtml()`、`toggleSelectAll()` 等全局复用函数)
|
||
- 后端 API `GET /api/admin/students`(加载学生列表,参见 `conduct.php` 第 77-95 行的 `loadStudents()` 调用方式)
|
||
- 后端 API `POST /api/admin/conduct/add`(加减分接口,请求体:`{ student_ids: number[], points_change: number, reason: string }`)
|
||
【修改内容】
|
||
- 角色权限判断(第 23 行)统一为 `in_array($role, ['班主任', '学习委员'])`(之前是 `科代表`,与后端 `admin.py` 第 228 行的角色检查一致)
|
||
- 移除发布作业按钮和发布作业模态框
|
||
- 移除作业列表和提交记录展示
|
||
- 新增学生列表表格(列:复选框、学号、姓名、当前操行分、操作-加减分按钮),参照 `conduct.php` 第 57-71 行的表格结构
|
||
- 新增批量加减分模态框(复用 `conduct.php` 第 116-143 行和 `students.php` 第 214-241 行的 `batchPointsModal` 模态框结构),包含:
|
||
- 已选学生数量显示
|
||
- 扣分类型快捷选择:未交作业(-2分)、迟交作业(-1分)、自定义(选择后自动填入分数变动输入框)
|
||
- 分数变动输入框(支持正数加分、负数扣分)
|
||
- 原因输入框(textarea)
|
||
- 确认提交按钮
|
||
- 页面级 JS 中定义 `let selectedStudentIds = [];` 和 `loadStudents()`、`showSinglePointsModal()` 函数(与 conduct.php 和 students.php 的页面级变量风格一致)
|
||
- 提交时复用 `admin.js` 中已有的 `submitBatchPoints()` 函数(该函数调用 `POST /api/admin/conduct/add`),`reason` 字段格式如 `"[作业扣分] 未交作业 - 原因内容"` 以区分来源
|
||
- 错误处理遵循仓库既有风格:调用 `apiPost()` 后检查 `res.success`,失败时使用 `showToast(res.message || '操作失败', 'error')` 提示(参见 `admin.js` 第 57-64 行的 `submitBatchPoints` 错误处理模式)
|
||
- 加载学生列表失败时,在表格区域显示错误提示文本
|
||
|
||
### 阶段 3:考勤管理改版
|
||
|
||
- [x] 3.1 清理 `admin.js` 中废弃的考勤管理函数
|
||
【目标对象】`frontend/assets/js/admin.js`
|
||
【修改目的】移除考勤管理改版后不再使用的旧考勤添加函数,避免全局函数污染和潜在冲突
|
||
【修改方式】删除原始文件第 222-268 行的三个函数(因任务 2.1 已删除第 174-220 行,实际操作时行号已前移约 47 行,请按函数名定位):`showAddAttendanceModal()`、`loadStudentsForSelect()`、`submitAddAttendance()`
|
||
【相关依赖】任务 2.1(先删除作业相关函数,行号会偏移)
|
||
【修改内容】
|
||
- 删除 `showAddAttendanceModal()` 函数(原始第 222-227 行)
|
||
- 删除 `loadStudentsForSelect()` 函数(原始第 229-238 行)
|
||
- 删除 `submitAddAttendance()` 函数(原始第 241-268 行)
|
||
- 建议按函数名搜索定位删除,而非依赖行号
|
||
- 注意:attendance.php 页面重写后,所有考勤相关 JS 逻辑将在页面级 `<script>` 中定义,不依赖 `admin.js` 中的旧函数
|
||
|
||
- [x] 3.2 新增考勤方格网格 CSS 样式
|
||
【目标对象】`frontend/assets/css/admin.css`
|
||
【修改目的】为考勤页面的学生方格网格提供样式
|
||
【修改方式】在文件末尾追加新样式规则
|
||
【相关依赖】无
|
||
【修改内容】
|
||
- `.student-grid` 容器:`display: flex; flex-wrap: wrap; gap: 10px;` 布局
|
||
- `.student-cell` 方格:`width: calc(100% / 7 - 10px);`(每行 7 个),带边框、圆角、居中文字、内边距、cursor: pointer
|
||
- `.student-cell.selected` 选中状态:红色/粉色背景高亮(如 `background: #fee2e2; border-color: #ef4444;`)
|
||
- `.student-cell.has-record` 已有考勤记录标记:灰色虚线边框(如 `border: 2px dashed #9ca3af;`),用于标识当天已有考勤记录的学生
|
||
- `.student-cell:hover` 悬停效果:浅色背景变化
|
||
- `.attendance-toolbar` 工具栏样式:flex 布局,按钮间距
|
||
- 移动端响应式:小屏幕下 `.student-cell` 宽度调整为 `calc(100% / 4 - 10px)` 或更宽
|
||
|
||
- [x] 3.3 重写考勤管理前端页面
|
||
【目标对象】`frontend/admin/attendance.php`
|
||
【修改目的】将单个学生下拉选择模式改为学生方格网格模式(一行 7 个),选中扣分制
|
||
【修改方式】完全重写页面 UI 和 `<script>` 中的 JavaScript 逻辑(保留文件头部的 PHP 鉴权部分和 include 结构)
|
||
【相关依赖】
|
||
- `frontend/includes/nav.php`(任务 1.1,导航栏引入)
|
||
- `frontend/assets/css/admin.css`(任务 3.2,方格网格样式)
|
||
- 后端 API `GET /api/admin/students`(加载学生列表)
|
||
- 后端 API `POST /api/admin/attendance`(添加考勤记录,请求体:`{ student_id: number, date: string, status: string, reason?: string, apply_deduction: boolean }`)
|
||
- 后端 API `GET /api/admin/attendance/records`(查询考勤记录,参数:`{ date: string }`)
|
||
【修改内容】
|
||
- 页面顶部工具栏:日期选择器(默认当天)+ 考勤状态选择(缺勤/迟到/请假单选按钮组)+ 原因输入框
|
||
- 主体区域:加载所有学生,以方格网格展示(使用 `.student-grid` 容器和 `.student-cell` 方格)
|
||
- 每个方格显示学生姓名,点击切换选中/取消状态(添加/移除 `.selected` class)
|
||
- 底部工具栏:全选按钮 + 取消全选按钮 + 提交按钮
|
||
- 提交逻辑:遍历所有选中的学生,对每个学生调用 `POST /api/admin/attendance`,参数为 `{ student_id, date, status, reason, apply_deduction: true }`
|
||
- 提交过程中的错误处理:使用 `Promise.allSettled()` 并发提交,提交完成后汇总成功/失败数量,使用 `showToast()` 提示结果(与仓库既有风格一致)
|
||
- 重复考勤记录边界处理:后端 `AttendanceService.add_attendance` 不检查同一学生同一天是否已有考勤记录,允许重复提交。前端在提交前先调用 `GET /api/admin/attendance/records` 获取当天已有记录,对已有考勤记录的学生在方格上添加视觉标记(如 `.has-record` 样式,灰色虚线边框),并在提交时 `confirm()` 提示"以下学生已有考勤记录,是否继续提交?"
|
||
- 下方保留历史考勤记录表格:调用 `GET /api/admin/attendance/records` 查询指定日期的记录并渲染(参照现有 `attendance.php` 第 112-131 行的渲染逻辑)
|
||
- 移除原有的单个学生下拉选择添加考勤模态框
|
||
- 加载学生列表失败时,在网格区域显示错误提示文本
|
||
- 错误提示风格遵循仓库既有模式:使用 `showToast(message, 'error')` 函数
|
||
|
||
### 阶段 4:家长手机号权限控制
|
||
|
||
- [x] 4.1 家长手机号权限控制
|
||
|
||
### 阶段 5:扣分规则配置化
|
||
|
||
- [x] 5.1 作业和考勤扣分规则配置化
|
||
【目标对象】`frontend/.env.example`、`frontend/config.php`、`frontend/includes/header.php`、`frontend/admin/homework.php`、`frontend/admin/attendance.php`
|
||
【修改目的】将作业和考勤的默认扣分量从 .env 文件配置,前端快捷按钮动态读取配置值,作业加减分有上限限制
|
||
【修改方式】
|
||
- .env.example 新增6个扣分配置项(有默认值)
|
||
- config.php 读取并 define 为常量
|
||
- header.php 注入到 JS 全局变量
|
||
- homework.php 快捷按钮使用配置值 + 自定义输入 + ±HOMEWORK_MAX_POINTS 限制
|
||
- attendance.php 状态按钮使用配置值
|
||
【目标对象】`frontend/admin/students.php`
|
||
【修改目的】除班主任角色外,隐藏家长手机号列的显示内容,保护隐私
|
||
【修改方式】在表头 HTML 和 JS 渲染处添加 `$role` 判断
|
||
【相关依赖】`$_SESSION['role']`(已存储在 `$role` 变量中,由各页面顶部从 session 读取)
|
||
【修改内容】
|
||
- 第 68 行表头处:`<th>家长手机号</th>` 改为 `<?php if ($role === '班主任'): ?><th>家长手机号</th><?php endif; ?>`(表头列有条件显示)
|
||
- 在页面 `<script>` 标签开头注入角色信息:`const userRole = '<?php echo $role; ?>';`
|
||
- 第 148 行 JS 渲染处:`<td>${student.parent_phone || '-'}</td>` 改为根据 `userRole` 判断渲染内容:班主任显示真实手机号,其他角色显示 `***`
|
||
- 第 156 行空数据提示处:`colspan="6"` 需根据角色动态调整——班主任 6 列,非班主任 5 列(可用 PHP 输出:`colspan="<?php echo $role === '班主任' ? '6' : '5'; ?>"`)
|
||
- 新增学生表单(第 101-129 行)和导入学生功能中的手机号字段保持不变,任何有学生管理权限的角色都能录入(与 proposal 一致)
|