重构项目结构,移除Assignment相关功能,优化Submission模块
Some checks failed
TechAct / explore-gitea-actions (push) Failing after 12s
Some checks failed
TechAct / explore-gitea-actions (push) Failing after 12s
This commit is contained in:
@@ -14,7 +14,7 @@ namespace TechHelper.Client.Exam
|
||||
public class AssignmentCheckQuestion
|
||||
{
|
||||
public string Sequence { get; set; } = string.Empty;
|
||||
public AssignmentQuestionDto AssignmentQuestionDto { get; set; } = new AssignmentQuestionDto();
|
||||
public ExamQuestionDto ExamQuestionDto { get; set; } = new ExamQuestionDto();
|
||||
public float Score { get; set; }
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace TechHelper.Client.Exam
|
||||
|
||||
public static class ExamStructExtensions
|
||||
{
|
||||
public static AssignmentCheckData GetStruct(this AssignmentDto dto)
|
||||
public static AssignmentCheckData GetStruct(this ExamDto dto)
|
||||
{
|
||||
if (dto == null)
|
||||
{
|
||||
@@ -66,7 +66,7 @@ namespace TechHelper.Client.Exam
|
||||
/// <param name="parentSequence">当前题目组的父级序号(例如:"1", "2.1")。如果为空,则表示顶级题目组。</param>
|
||||
/// <param name="allQuestions">用于收集所有生成题目项的列表。</param>
|
||||
private static void GetSeqRecursive(
|
||||
AssignmentQuestionDto currentGroup,
|
||||
ExamQuestionDto currentGroup,
|
||||
string? parentSequence,
|
||||
List<AssignmentCheckQuestion> allQuestions)
|
||||
{
|
||||
@@ -74,7 +74,7 @@ namespace TechHelper.Client.Exam
|
||||
? $"{parentSequence}.{currentGroup.Index}"
|
||||
: currentGroup.Index.ToString();
|
||||
|
||||
foreach (var subGroup in currentGroup.ChildrenAssignmentQuestion)
|
||||
foreach (var subGroup in currentGroup.ChildExamQuestions)
|
||||
{
|
||||
GetSeqRecursive(subGroup, currentGroupSequence, allQuestions);
|
||||
}
|
||||
@@ -83,7 +83,7 @@ namespace TechHelper.Client.Exam
|
||||
|
||||
allQuestions.Add(new AssignmentCheckQuestion
|
||||
{
|
||||
AssignmentQuestionDto = currentGroup,
|
||||
ExamQuestionDto = currentGroup,
|
||||
//Sequence = currentGroupSequence,
|
||||
Sequence = currentGroup.Sequence,
|
||||
Score = currentGroup.Score,
|
||||
|
||||
@@ -16,18 +16,18 @@ namespace TechHelper.Client.Exam
|
||||
.Where(line => !string.IsNullOrWhiteSpace(line)).ToList();
|
||||
}
|
||||
|
||||
public static void SeqIndex(this AssignmentDto dto)
|
||||
public static void SeqIndex(this ExamDto dto)
|
||||
{
|
||||
dto.ExamStruct.SeqQGroupIndex();
|
||||
}
|
||||
|
||||
|
||||
public static void SeqQGroupIndex(this AssignmentQuestionDto dto)
|
||||
public static void SeqQGroupIndex(this ExamQuestionDto dto)
|
||||
{
|
||||
|
||||
foreach (var sqg in dto.ChildrenAssignmentQuestion)
|
||||
foreach (var sqg in dto.ChildExamQuestions)
|
||||
{
|
||||
sqg.Index = (byte)(dto.ChildrenAssignmentQuestion.IndexOf(sqg) + 1);
|
||||
sqg.Index = (byte)(dto.ChildExamQuestions.ToList().IndexOf(sqg) + 1);
|
||||
sqg.SeqQGroupIndex();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Entities.Contracts; // 假设这些实体合约仍然是必需的
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Text;
|
||||
using Entities.DTO;
|
||||
using TechHelper.Client.Services;
|
||||
|
||||
namespace TechHelper.Client.Exam
|
||||
{
|
||||
@@ -41,17 +43,17 @@ namespace TechHelper.Client.Exam
|
||||
}
|
||||
}
|
||||
|
||||
public class AssignmentEx
|
||||
public class ExamEx
|
||||
{
|
||||
public string Title { get; set; } = "Title";
|
||||
public string Description { get; set; } = "Description";
|
||||
public SubjectAreaEnum SubjectArea { get; set; } = SubjectAreaEnum.Unknown;
|
||||
public AssignmentQuestionEx ExamStruct { get; set; } = new AssignmentQuestionEx();
|
||||
public TypeCommonDto Subject { get; set; }
|
||||
public ExamQuestionEx ExamStruct { get; set; } = new ExamQuestionEx();
|
||||
public List<ParseError> Errors { get; set; } = new List<ParseError>();
|
||||
}
|
||||
|
||||
// 试题的包裹器, 或者 单独作为一个试题结构存在
|
||||
public class AssignmentQuestionEx
|
||||
public class ExamQuestionEx
|
||||
{
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
@@ -59,8 +61,8 @@ namespace TechHelper.Client.Exam
|
||||
public float Score { get; set; }
|
||||
public string Sequence { get; set; } = string.Empty;
|
||||
public QuestionEx? Question { get; set; }
|
||||
public AssignmentStructType Type { get; set; }
|
||||
public List<AssignmentQuestionEx> ChildrenAssignmentQuestion { get; set; } = new List<AssignmentQuestionEx>();
|
||||
public TypeCommonDto Type { get; set; }
|
||||
public List<ExamQuestionEx> ChildrenAssignmentQuestion { get; set; } = new List<ExamQuestionEx>();
|
||||
public int Priority { get; set; }
|
||||
}
|
||||
|
||||
@@ -85,10 +87,10 @@ namespace TechHelper.Client.Exam
|
||||
{
|
||||
public string Pattern { get; set; }
|
||||
public int Priority { get; set; }
|
||||
public AssignmentStructType Type { get; set; }
|
||||
public ExamStructType Type { get; set; }
|
||||
public Regex Regex { get; private set; }
|
||||
|
||||
public RegexPatternConfig(string pattern, int priority, AssignmentStructType type = AssignmentStructType.Question)
|
||||
public RegexPatternConfig(string pattern, int priority, ExamStructType type = ExamStructType.Question)
|
||||
{
|
||||
Pattern = pattern;
|
||||
Priority = priority;
|
||||
@@ -113,26 +115,26 @@ namespace TechHelper.Client.Exam
|
||||
// Group 2: 题目/题组标题内容
|
||||
|
||||
// 例如:一. 这是大题一
|
||||
QuestionPatterns.Add(new RegexPatternConfig(@"^([一二三四五六七八九十]+)[.\、]\s*(.+)", 1, AssignmentStructType.Struct));
|
||||
QuestionPatterns.Add(new RegexPatternConfig(@"^([一二三四五六七八九十]+)[.\、]\s*(.+)", 1, ExamStructType.Struct));
|
||||
|
||||
// 例如:(一) 这是第一子题组
|
||||
QuestionPatterns.Add(new RegexPatternConfig(@"^\(([一二三四五六七八九十]{1,2}|十[一二三四五六七八九])\)\s*(.+)", 2, AssignmentStructType.Group));
|
||||
QuestionPatterns.Add(new RegexPatternConfig(@"^\(([一二三四五六七八九十]{1,2}|十[一二三四五六七八九])\)\s*(.+)", 2, ExamStructType.Group));
|
||||
|
||||
// 例如:1. 这是第一道题目 或 1 这是第一道题目
|
||||
QuestionPatterns.Add(new RegexPatternConfig(@"^(\d+)\.?\s*(.+)", 3, AssignmentStructType.Question));
|
||||
QuestionPatterns.Add(new RegexPatternConfig(@"^(\d+)\.?\s*(.+)", 3, ExamStructType.Question));
|
||||
|
||||
// 例如:(1). 这是小问一 或 (1) 这是小问一
|
||||
QuestionPatterns.Add(new RegexPatternConfig(@"^\((\d+)\)\.?\s*(.+)", 4, AssignmentStructType.Question));
|
||||
QuestionPatterns.Add(new RegexPatternConfig(@"^\((\d+)\)\.?\s*(.+)", 4, ExamStructType.Question));
|
||||
|
||||
// 例如:① 这是另一种小问 或 ①. 这是另一种小问 (如果 ① 后面会跟点,这个更通用)
|
||||
// 如果 ① 后面通常没有点,但您希望它也能匹配,则保留原样或根据实际情况调整
|
||||
QuestionPatterns.Add(new RegexPatternConfig(@"^[①②③④⑤⑥⑦⑧⑨⑩]+\.?\s*(.+)", 5, AssignmentStructType.Question));
|
||||
QuestionPatterns.Add(new RegexPatternConfig(@"^[①②③④⑤⑥⑦⑧⑨⑩]+\.?\s*(.+)", 5, ExamStructType.Question));
|
||||
|
||||
|
||||
|
||||
// 选项模式 (保持不变,使用 AssignmentStructType.Option 区分)
|
||||
OptionPatterns.Add(new RegexPatternConfig(@"([A-Z]\.)\s*(.*?)(?=[A-Z]\.|$)", 1, AssignmentStructType.Option));
|
||||
OptionPatterns.Add(new RegexPatternConfig(@"([a-z]\.)\s*(.*?)(?=[a-z]\.|$)", 2, AssignmentStructType.Option));
|
||||
// 选项模式 (保持不变,使用 ExamStructType.Option 区分)
|
||||
OptionPatterns.Add(new RegexPatternConfig(@"([A-Z]\.)\s*(.*?)(?=[A-Z]\.|$)", 1, ExamStructType.Option));
|
||||
OptionPatterns.Add(new RegexPatternConfig(@"([a-z]\.)\s*(.*?)(?=[a-z]\.|$)", 2, ExamStructType.Option));
|
||||
|
||||
// 独立的得分正则表达式:匹配行末尾的 "(X分)" 格式
|
||||
// Group 1: 捕获分数(如 "10" 或 "0.5")
|
||||
@@ -206,7 +208,7 @@ namespace TechHelper.Client.Exam
|
||||
_config = config ?? throw new ArgumentNullException(nameof(config), "ExamParserConfig cannot be null.");
|
||||
}
|
||||
|
||||
public AssignmentEx BuildExam(string fullExamText, List<PotentialMatch> allPotentialMatches)
|
||||
public ExamEx BuildExam(string fullExamText, List<PotentialMatch> allPotentialMatches)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(fullExamText))
|
||||
{
|
||||
@@ -217,7 +219,7 @@ namespace TechHelper.Client.Exam
|
||||
throw new ArgumentNullException(nameof(allPotentialMatches), "Potential matches list cannot be null.");
|
||||
}
|
||||
|
||||
var assignment = new AssignmentEx();
|
||||
var assignment = new ExamEx();
|
||||
try
|
||||
{
|
||||
assignment.Title = GetExamTitle(fullExamText);
|
||||
@@ -228,8 +230,8 @@ namespace TechHelper.Client.Exam
|
||||
assignment.Title = "未识别试卷标题";
|
||||
}
|
||||
|
||||
var assignmentQuestionStack = new Stack<AssignmentQuestionEx>();
|
||||
var rootAssignmentQuestion = new AssignmentQuestionEx { Type = AssignmentStructType.Struct, Priority = 0, Title = "Root Exam Structure" };
|
||||
var assignmentQuestionStack = new Stack<ExamQuestionEx>();
|
||||
var rootAssignmentQuestion = new ExamQuestionEx { Priority = 0, Title = "Root Exam Structure" };
|
||||
assignmentQuestionStack.Push(rootAssignmentQuestion);
|
||||
assignment.ExamStruct = rootAssignmentQuestion;
|
||||
|
||||
@@ -270,7 +272,7 @@ namespace TechHelper.Client.Exam
|
||||
}
|
||||
}
|
||||
|
||||
if (pm.PatternConfig.Type == AssignmentStructType.Option)
|
||||
if (pm.PatternConfig.Type == ExamStructType.Option)
|
||||
{
|
||||
HandleOptionMatch(pm, i, assignmentQuestionStack.Peek(), assignment.Errors);
|
||||
}
|
||||
@@ -337,7 +339,7 @@ namespace TechHelper.Client.Exam
|
||||
return true;
|
||||
}
|
||||
|
||||
private void HandleQuestionGroupMatch(PotentialMatch pm, int index, Stack<AssignmentQuestionEx> assignmentQuestionStack, List<ParseError> errors)
|
||||
private void HandleQuestionGroupMatch(PotentialMatch pm, int index, Stack<ExamQuestionEx> assignmentQuestionStack, List<ParseError> errors)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -379,24 +381,22 @@ namespace TechHelper.Client.Exam
|
||||
string seq = pm.RegexMatch.Groups[1].Value.Trim();
|
||||
seq = string.IsNullOrEmpty(seq) || string.IsNullOrEmpty(sequence) ? seq : " ." + seq;
|
||||
|
||||
AssignmentQuestionEx newAssignmentQuestion;
|
||||
if (pm.PatternConfig.Type == AssignmentStructType.Struct)
|
||||
ExamQuestionEx newAssignmentQuestion;
|
||||
if (pm.PatternConfig.Type == ExamStructType.Struct)
|
||||
{
|
||||
newAssignmentQuestion = new AssignmentQuestionEx
|
||||
newAssignmentQuestion = new ExamQuestionEx
|
||||
{
|
||||
Title = title,
|
||||
Score = score,
|
||||
Sequence = sequence + seq,
|
||||
Priority = pm.PatternConfig.Priority,
|
||||
Type = pm.PatternConfig.Type
|
||||
};
|
||||
}
|
||||
else // AssignmentStructType.Question 类型
|
||||
else // ExamStructType.Question 类型
|
||||
{
|
||||
newAssignmentQuestion = new AssignmentQuestionEx
|
||||
newAssignmentQuestion = new ExamQuestionEx
|
||||
{
|
||||
Priority = pm.PatternConfig.Priority,
|
||||
Type = pm.PatternConfig.Type,
|
||||
Sequence = sequence + seq,
|
||||
Score = score,
|
||||
Question = new QuestionEx
|
||||
@@ -417,7 +417,7 @@ namespace TechHelper.Client.Exam
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleOptionMatch(PotentialMatch pm, int index, AssignmentQuestionEx currentAssignmentQuestion, List<ParseError> errors)
|
||||
private void HandleOptionMatch(PotentialMatch pm, int index, ExamQuestionEx currentAssignmentQuestion, List<ParseError> errors)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -452,7 +452,7 @@ namespace TechHelper.Client.Exam
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessQuestionContent(AssignmentQuestionEx question, string contentText, List<ParseError> errors)
|
||||
private void ProcessQuestionContent(ExamQuestionEx question, string contentText, List<ParseError> errors)
|
||||
{
|
||||
if (question?.Question == null)
|
||||
{
|
||||
@@ -479,12 +479,14 @@ namespace TechHelper.Client.Exam
|
||||
public class ExamParser
|
||||
{
|
||||
private readonly ExamParserConfig _config;
|
||||
private readonly ICommonService _commonService;
|
||||
private readonly ExamDocumentScanner _scanner;
|
||||
private readonly ExamStructureBuilder _builder;
|
||||
|
||||
public ExamParser(ExamParserConfig config)
|
||||
public ExamParser(ExamParserConfig config, ICommonService commonService)
|
||||
{
|
||||
_config = config ?? throw new ArgumentNullException(nameof(config));
|
||||
_commonService = commonService;
|
||||
_scanner = new ExamDocumentScanner(_config);
|
||||
_builder = new ExamStructureBuilder(_config);
|
||||
}
|
||||
@@ -494,9 +496,9 @@ namespace TechHelper.Client.Exam
|
||||
/// </summary>
|
||||
/// <param name="examPaperText">完整的试卷文本</param>
|
||||
/// <returns>解析后的 AssignmentEx 对象</returns>
|
||||
public AssignmentEx ParseExamPaper(string examPaperText)
|
||||
public ExamEx ParseExamPaper(string examPaperText)
|
||||
{
|
||||
var assignment = new AssignmentEx();
|
||||
var assignment = new ExamEx();
|
||||
List<PotentialMatch> allPotentialMatches = _scanner.Scan(examPaperText, assignment.Errors);
|
||||
assignment = _builder.BuildExam(examPaperText, allPotentialMatches);
|
||||
return assignment;
|
||||
|
||||
Reference in New Issue
Block a user