评阅与成绩:老师看代码、运行学生程序、打分、写评语;成绩表与导出
- 评阅页:全班学生列表(提交状态、得分、是否已评阅);选中学生的代码(只读)、自动评分结果、 规范提示(代码里用到的默认名字控件、注释行数)、老师评分项打分和评语,"保存并看下一个" - "运行他的程序":新标签页里打开学生的提交,可以操作实训台,改动不保存 - 学生能看到老师的各项得分和评语;作业列表显示总分 - 班级管理页"成绩"标签页:学生 × 作业的总分,点分数进入评阅;单个作业和全班成绩导出 CSV - 老师增删评分项后,已打的分按新的评分项对齐 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4e6b0d5cb2
commit
89e9956a22
20 files changed
+999
-127
No files matched your search
+35
-4
@@ -16,6 +16,7 @@ import {
|
||||
updateAssignment,
|
||||
} from './assignments'
|
||||
import { parseChecks } from './grading/checks'
|
||||
import { getReview, gradebook, manualScore, saveReview, studentDetail, submissionFiles } from './reviews'
|
||||
import type { GradingQueue } from './grading/queue'
|
||||
import { listSamples, loadChecks, loadSample } from './samples'
|
||||
import { serveStatic } from './static'
|
||||
@@ -114,7 +115,7 @@ export function createApp(db: Database, gradingQueue: GradingQueue) {
|
||||
return c.json(
|
||||
listAssignments(db, user.classId).map((a) => {
|
||||
const latest = latestSubmission(db, a.id, user.id)
|
||||
return { ...a, latest: latest && { ...latest, result: null } }
|
||||
return { ...a, latest: latest && { ...latest, result: null }, manualScore: manualScore(getReview(db, a.id, user.id)) }
|
||||
}),
|
||||
)
|
||||
})
|
||||
@@ -122,7 +123,8 @@ export function createApp(db: Database, gradingQueue: GradingQueue) {
|
||||
app.get('/api/assignments/:id', (c) => {
|
||||
const assignment = visibleAssignment(c)
|
||||
if (!assignment) return c.json({ message: '作业不存在' }, 404)
|
||||
return c.json({ assignment, template: assignmentTemplate(db, assignment.id), latest: latestSubmission(db, assignment.id, c.get('user').id) })
|
||||
const userId = c.get('user').id
|
||||
return c.json({ assignment, template: assignmentTemplate(db, assignment.id), latest: latestSubmission(db, assignment.id, userId), review: getReview(db, assignment.id, userId) })
|
||||
})
|
||||
|
||||
app.post('/api/assignments/:id/submit', async (c) => {
|
||||
@@ -236,8 +238,37 @@ export function createApp(db: Database, gradingQueue: GradingQueue) {
|
||||
return c.json({})
|
||||
})
|
||||
|
||||
// 全班每个学生最近一次提交的情况
|
||||
app.get('/api/teacher/assignments/:id/submissions', (c) => c.json(classSubmissions(db, id(c))))
|
||||
// 全班每个学生最近一次提交的情况和老师评分
|
||||
app.get('/api/teacher/assignments/:id/submissions', (c) =>
|
||||
c.json(
|
||||
classSubmissions(db, id(c)).map((s) => {
|
||||
const review = getReview(db, id(c), s.userId)
|
||||
return { ...s, manualScore: manualScore(review), review }
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
// 评阅一个学生:最近一次提交(含代码和评分结果)、老师评阅
|
||||
app.get('/api/teacher/assignments/:id/students/:userId', (c) => {
|
||||
const assignment = getAssignment(db, id(c))
|
||||
const detail = assignment && studentDetail(db, assignment.id, Number(c.req.param('userId')))
|
||||
return detail ? c.json({ assignment, ...detail }) : c.json({ message: '找不到这个学生的作业' }, 404)
|
||||
})
|
||||
|
||||
app.put('/api/teacher/assignments/:id/students/:userId/review', async (c) => {
|
||||
const { scores, comment } = await body<{ scores: unknown; comment: unknown }>(c)
|
||||
const userId = Number(c.req.param('userId'))
|
||||
const result = saveReview(db, id(c), userId, scores, comment)
|
||||
return result.error ? c.json({ message: result.error }, 400) : c.json(getReview(db, id(c), userId))
|
||||
})
|
||||
|
||||
// 一份提交的代码(老师在实验页里运行学生的程序)
|
||||
app.get('/api/teacher/submissions/:id', (c) => {
|
||||
const submission = submissionFiles(db, id(c))
|
||||
return submission ? c.json(submission) : c.json({ message: '提交不存在' }, 404)
|
||||
})
|
||||
|
||||
app.get('/api/teacher/classes/:id/gradebook', (c) => c.json(gradebook(db, id(c))))
|
||||
|
||||
app.all('/api/*', (c) => c.json({ message: '接口不存在' }, 404))
|
||||
|
||||
|
||||
Reference in new issue
Block a user