已按“实验成绩独立管理”完成修改。

每个实验项目独立建成绩单,支持评分项、参与状态、补做次数、安全违规、报告地址和教师评语。
流程为:录入 → 学院审核 → 教务发布;学生只能查看已发布成绩。
自主预约实验支持同步有效预约名单,已评分记录不会被误删。
课程成绩可将已发布实验成绩汇总为快照导入指定分项;导入后锁定,不能手工篡改。
实验项目成绩不完整时,对应课程分项保持空白,不按 0 分处理。
一级“实验管理”菜单下增加“项目与场次”“实验成绩”;学生端增加“实验安排”“实验成绩”。
已生成 MySQL 正式迁移及 SQLite 开发迁移,尚未操作生产数据库。
界面采用“实验项目 → 独立评分 → 审核发布”工作台设计。
This commit is contained in:
2026-07-28 22:21:18 +08:00 Unverified
parent 51c3b81e27
commit 8f56548b54
17 changed files with 9239 additions and 14 deletions
@@ -19,6 +19,7 @@ public sealed class ExperimentProject : EntityBase
public DateTime? ClosedAt { get; set; }
public ICollection<ExperimentSession> Sessions { get; set; } = [];
public ICollection<ExperimentBooking> Bookings { get; set; } = [];
public ExperimentGradeSheet? GradeSheet { get; set; }
}
public sealed class ExperimentSession : EntityBase
@@ -0,0 +1,92 @@
using Jiaowu.Api.Domain.Common;
namespace Jiaowu.Api.Domain.Academic;
public sealed class ExperimentGradeSheet : EntityBase
{
public Guid ExperimentProjectId { get; set; }
public ExperimentProject? ExperimentProject { get; set; }
public decimal ContributionWeight { get; set; } = 1;
public decimal PassScore { get; set; } = 60;
public ExperimentGradeSheetStatus Status { get; set; } =
ExperimentGradeSheetStatus.Draft;
public string? ReviewComment { get; set; }
public DateTime? SubmittedAt { get; set; }
public DateTime? ReviewedAt { get; set; }
public DateTime? PublishedAt { get; set; }
public ICollection<ExperimentGradeItem> Items { get; set; } = [];
public ICollection<ExperimentGradeRecord> Records { get; set; } = [];
}
public sealed class ExperimentGradeItem : EntityBase
{
public Guid ExperimentGradeSheetId { get; set; }
public ExperimentGradeSheet? ExperimentGradeSheet { get; set; }
public required string Name { get; set; }
public ExperimentGradeItemKind Kind { get; set; } =
ExperimentGradeItemKind.Other;
public decimal Weight { get; set; }
public int SortOrder { get; set; }
public ICollection<ExperimentGradeItemScore> Scores { get; set; } = [];
}
public sealed class ExperimentGradeRecord : EntityBase
{
public Guid ExperimentGradeSheetId { get; set; }
public ExperimentGradeSheet? ExperimentGradeSheet { get; set; }
public Guid StudentId { get; set; }
public Student? Student { get; set; }
public Guid? ExperimentSessionId { get; set; }
public ExperimentSession? ExperimentSession { get; set; }
public ExperimentParticipationStatus ParticipationStatus { get; set; } =
ExperimentParticipationStatus.Pending;
public decimal? TotalScore { get; set; }
public bool? IsPassed { get; set; }
public bool SafetyViolation { get; set; }
public int AttemptNumber { get; set; } = 1;
public string? SubmissionReference { get; set; }
public DateTime? SubmittedAt { get; set; }
public bool IsLate { get; set; }
public string? TeacherComment { get; set; }
public ICollection<ExperimentGradeItemScore> ItemScores { get; set; } = [];
}
public sealed class ExperimentGradeItemScore
{
public Guid ExperimentGradeRecordId { get; set; }
public ExperimentGradeRecord? ExperimentGradeRecord { get; set; }
public Guid ExperimentGradeItemId { get; set; }
public ExperimentGradeItem? ExperimentGradeItem { get; set; }
public decimal? Score { get; set; }
public string? Comment { get; set; }
}
public enum ExperimentGradeSheetStatus
{
Draft = 1,
Submitted = 2,
Approved = 3,
Published = 4,
Returned = 5
}
public enum ExperimentGradeItemKind
{
Operation = 1,
Report = 2,
Result = 3,
Defense = 4,
Attendance = 5,
Safety = 6,
Other = 7
}
public enum ExperimentParticipationStatus
{
Pending = 1,
Completed = 2,
Absent = 3,
Excused = 4,
Makeup = 5,
Exempt = 6
}
@@ -24,6 +24,9 @@ public sealed class GradeItem : EntityBase
public required string Name { get; set; }
public decimal Weight { get; set; }
public int SortOrder { get; set; }
public GradeItemSourceType SourceType { get; set; } =
GradeItemSourceType.Manual;
public DateTime? SourceSnapshotAt { get; set; }
public ICollection<GradeItemScore> Scores { get; set; } = [];
}
@@ -68,3 +71,9 @@ public enum GradeExamStatus
Exempt = 4,
Makeup = 5
}
public enum GradeItemSourceType
{
Manual = 1,
ExperimentSummary = 2
}