giteaCICD
This commit is contained in:
@@ -92,7 +92,7 @@
|
||||
"含在 <SQ> 内部,包含一个或多个 <O>。<O> (选项,必需) 包含在 <Os> 内部,具有 V (必需) 属性。";
|
||||
|
||||
|
||||
public static string BreakQuestions = "请识别以下文本中的每一道大题。将其转换为XML格式,你只需要给出转换后的结果,不需要其他任何无关的输出,其中 <EP> 是XML的根元素。用<Q> 和</Q> 标记来包裹每一道大题。请确保标记后的文本保持原始格式和内容。";
|
||||
public static string BreakQuestions = "请识别下面给出的试卷内容,分离并返回每一道大题,并将其转换为XML格式,你只需要给出转换后的结果,不需要其他任何无关的输出,其中 <EP> 是XML的根元素。用<Q> 和</Q> 标记来包裹每一道大题。请确保标记后的文本保持原始格式和内容。";
|
||||
|
||||
|
||||
public static string ParseSignelQuestion = "请将以下提供的一道大题内容,转换为符合以下 C# 类结构的 XML 格式,你只需要给出转换后的结果,不需要其他任何无关的输出:" +
|
||||
@@ -104,5 +104,70 @@
|
||||
" <SQ> 内部的 <Os> 元素列表中的 <O> 元素。如果子题目有选项,则将它们包裹在 <Os> 元素中。对于每个 <O> 元素,填充 V 属性:V:对应 Option.Value" +
|
||||
"(从选项内容中提取)。嵌套题组:如果大题内部包含其他大题,则作为 <QG> 内部的 <SQGs> 元素列表中的 <QG> 元素(即嵌套 <QG>)。" +
|
||||
"请确保生成的 XML 严格遵循上述结构和命名约定,以方便 C# XmlSerializer 进行反序列化。";
|
||||
|
||||
|
||||
public static string ParseSignelQuestion2 =
|
||||
@"请将给定的文本按下面的xml格式要求转换,在返回结果时,只返回XML转换内容,不要输出其他内容,如果给你的文本不能提取有效文本,请直接返回<QG/>,下面是格式:
|
||||
<QG>
|
||||
<T>XML生成规则</T>
|
||||
<SQGs>
|
||||
<QG>
|
||||
<T>1. 根元素与题目组嵌套</T>
|
||||
<Os>
|
||||
<O V=""根元素必须为<QG>。""/>
|
||||
<O V=""所有题目组通过<SQGs>嵌套。""/>
|
||||
<O V=""当题目组不包含子题目组时,直接使用<SQs>包裹单个题目<SQ>,不应再嵌套<SQGs>。""/>
|
||||
</Os>
|
||||
</QG>
|
||||
|
||||
<QG>
|
||||
<T>2. 原文引用规范</T>
|
||||
<Os>
|
||||
<O V=""阅读理解等需要上下文的题目组,原文内容需完整嵌入<QR>标签中。此标签仅在题目组(QG)级别使用。""/>
|
||||
<O V=""示例:
|
||||
<QG>
|
||||
<T> 标题 </T>
|
||||
<QR> 引用正文 </QR>
|
||||
<SQs>
|
||||
<SQ><T>题目</T>
|
||||
<SA> 答案 </SA>
|
||||
</SQ>
|
||||
</SQs>
|
||||
</QG>""/>
|
||||
</Os>
|
||||
</QG>
|
||||
|
||||
<QG>
|
||||
<T>3. 题目封装与答案存储</T>
|
||||
<Os>
|
||||
<O V=""单选题:<SQ><T>...</T><Os><O V='A.'/><O V='B.'/>...</Os><SA>B</SA></SQ>""/>
|
||||
<O V=""简答题:<SQ><T>...</T><SA>...</SA></SQ>""/>
|
||||
<O V=""填空题:<SQ><T>...</T><SA>答案1 答案2</SA></SQ>""/>
|
||||
<O V=""简答题必须保留所有修饰语(如‘用‘____’标注’),并将其包含在<T>或<SQ><T>中。""/>
|
||||
<O V=""多行答案(如简答题或填空题的多个空)使用换行符 分隔。""/>
|
||||
</Os>
|
||||
</QG>
|
||||
|
||||
<QG>
|
||||
<T>4. 选项与答案值</T>
|
||||
<Os>
|
||||
<O V=""<Os>仅用于存储题目中出现的选项,其顺序严格按题目原有的顺序排列。""/>
|
||||
<O V=""<O V=''/'>表示空选项值(如有需要,通常不会出现于实际选项中)。""/>
|
||||
<O V=""<SA>标签用于存储题目的正确答案。单选题的<SA>应存储正确选项的字母(如'B')。""/>
|
||||
</Os>
|
||||
</QG>
|
||||
</SQGs>
|
||||
<SQs>
|
||||
<SQ><T>当不包含子题目时</T>
|
||||
<Os>
|
||||
<O V=""直接使用<SQs>包裹每个题目<SQ>,不再嵌套<SQGs>。""/>
|
||||
</Os>
|
||||
</SQ>
|
||||
</SQs>
|
||||
</QG>";
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -35,17 +35,13 @@ namespace TechHelper.Client.Exam
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonProperty("标题")]
|
||||
[XmlAttribute("T")] // T for Title
|
||||
[XmlElement("T")] // T for Title
|
||||
public string Title { get; set; }
|
||||
|
||||
[JsonProperty("分值")]
|
||||
[XmlAttribute("S")] // S for Score
|
||||
public int Score { get; set; }
|
||||
|
||||
[JsonProperty("分值问题标记")]
|
||||
[XmlAttribute("SPM")] // SPM for ScoreProblemMarker
|
||||
public string ScoreProblemMarker { get; set; } = ""; // 初始化为空字符串,避免 null
|
||||
|
||||
[JsonProperty("题目引用")]
|
||||
[XmlElement("QR")] // QR for QuestionReference,作为 <QR> 元素
|
||||
public string QuestionReference { get; set; } = ""; // 初始化为空字符串
|
||||
@@ -69,26 +65,20 @@ namespace TechHelper.Client.Exam
|
||||
public string SubId { get; set; }
|
||||
|
||||
[JsonProperty("题干")]
|
||||
[XmlAttribute("T")] // T for Text (Stem)
|
||||
[XmlElement("T")] // T for Text (Stem)
|
||||
public string Stem { get; set; }
|
||||
|
||||
[JsonProperty("分值")]
|
||||
[XmlAttribute("S")] // S for Score
|
||||
public int Score { get; set; } // 分值通常为整数
|
||||
|
||||
[JsonProperty("分值问题标记")]
|
||||
[XmlAttribute("SPM")] // SPM for ScoreProblemMarker
|
||||
public string ScoreProblemMarker { get; set; } = "";
|
||||
|
||||
// 注意:这里的 Options 需要适配 XML 结构 <Os><O V="X"/></Os>
|
||||
// 因此它不再是 List<string>,而是 List<Option>
|
||||
[JsonProperty("选项")]
|
||||
[XmlArray("Os")] // Os 包含 <O> 列表
|
||||
[XmlArrayItem("O")]
|
||||
public List<Option> Options { get; set; } = new List<Option>();
|
||||
|
||||
[JsonProperty("示例答案")]
|
||||
[XmlAttribute("SA")] // SA for SampleAnswer
|
||||
[XmlElement("SA")] // SA for SampleAnswer
|
||||
public string SampleAnswer { get; set; } = "";
|
||||
}
|
||||
|
||||
|
36
TechHelper.Client/Exam/QuestionSimple.cs
Normal file
36
TechHelper.Client/Exam/QuestionSimple.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace TechHelper.Client.Exam.QuestionSimple
|
||||
{
|
||||
|
||||
[XmlRoot("QG")]
|
||||
public class QuestionGroup
|
||||
{
|
||||
[XmlElement("T")]
|
||||
public string Title { get; set; }
|
||||
[XmlElement("QR")]
|
||||
public string QuestionReference { get; set; } = "";
|
||||
[XmlArray("SQs")]
|
||||
[XmlArrayItem("SQ")]
|
||||
public List<SubQuestion> SubQuestions { get; set; } = new List<SubQuestion>();
|
||||
[XmlArray("SQGs")]
|
||||
[XmlArrayItem("QG")]
|
||||
public List<QuestionGroup> SubQuestionGroups { get; set; } = new List<QuestionGroup>();
|
||||
}
|
||||
public class SubQuestion
|
||||
{
|
||||
[XmlElement("T")]
|
||||
public string Stem { get; set; }
|
||||
[XmlArray("Os")]
|
||||
[XmlArrayItem("O")]
|
||||
public List<Option> Options { get; set; } = new List<Option>();
|
||||
[XmlElement("SA")]
|
||||
public string SampleAnswer { get; set; } = "";
|
||||
}
|
||||
public class Option
|
||||
{
|
||||
[XmlAttribute("V")]
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
||||
}
|
@@ -21,6 +21,7 @@
|
||||
<MudButton OnClick="ReCorrectXMLAsync">AplyAIResult</MudButton>
|
||||
<MudButton OnClick="ReCorrectXMLAsync">Save</MudButton>
|
||||
<MudButton OnClick="ReCorrectXMLAsync">Public</MudButton>
|
||||
<MudButton OnClick="CopyToClipboard">Copy</MudButton>
|
||||
</MudButtonGroup>
|
||||
|
||||
</MudPaper>
|
||||
@@ -57,8 +58,17 @@
|
||||
@for (int i = 0; i < ParseResult.Count; i++)
|
||||
{
|
||||
int index = i;
|
||||
|
||||
<MudTextField Class="ma-3" AutoGrow="true" @bind-Value="ParseResult[index]"></MudTextField>
|
||||
<MudCard Style="background-color:#ffffff88">
|
||||
<MudCardHeader>
|
||||
<MudCardActions>
|
||||
<MudButton Variant="Variant.Filled" Color ="Color.Primary" OnClick="(()=>DeleteFromParse(index))"> Delete </MudButton>
|
||||
</MudCardActions>
|
||||
</MudCardHeader>
|
||||
<MudCardContent>
|
||||
|
||||
<MudTextField Class="ma-3" AutoGrow="true" @bind-Value="ParseResult[index]"></MudTextField>
|
||||
</MudCardContent>
|
||||
</MudCard>
|
||||
}
|
||||
<MudText>@Error</MudText>
|
||||
</MudPaper>
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using Blazored.TextEditor;
|
||||
using Entities.Contracts;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using MudBlazor;
|
||||
using System.Text.RegularExpressions;
|
||||
using TechHelper.Client.AI;
|
||||
@@ -62,7 +63,7 @@ namespace TechHelper.Client.Pages.Editor
|
||||
|
||||
ProgStatues = ProgEnum.AIPrase.ToString();
|
||||
ProgStatues = $"<22><><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>ȴ<EFBFBD>";
|
||||
Snackbar.Add("<22><><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>ȴ<EFBFBD>");
|
||||
Snackbar.Add("<22><><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>ȴ<EFBFBD>", Severity.Info);
|
||||
StateHasChanged();
|
||||
string respon = await aIService.CallGLM(QuillHTMLContent, AIConfiguration.BreakQuestions);
|
||||
if (respon == null)
|
||||
@@ -81,18 +82,18 @@ namespace TechHelper.Client.Pages.Editor
|
||||
foreach (var item in ParRespon.Items)
|
||||
{
|
||||
ProgStatues = $"<22><><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD>{i}<7D><>, <20><><EFBFBD>ȴ<EFBFBD>";
|
||||
Snackbar.Add($"<22><><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD>{i}<7D><>, <20><><EFBFBD>ȴ<EFBFBD>");
|
||||
Snackbar.Add($"<22><><EFBFBD>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD>{i}<7D><>, <20><><EFBFBD>ȴ<EFBFBD>", Severity.Info);
|
||||
StateHasChanged();
|
||||
i++;
|
||||
try
|
||||
{
|
||||
var parResult = await aIService.CallGLM(item, AIConfiguration.ParseSignelQuestion);
|
||||
var parResult = await aIService.CallGLM(item, AIConfiguration.ParseSignelQuestion2);
|
||||
ParseResult.Add(parResult);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add($"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>{i}<7D><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD>Ժ<EFBFBD><D4BA><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD>Ϊ:{ex.Message}");
|
||||
Snackbar.Add($"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>{i}<7D><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD>Ժ<EFBFBD><D4BA><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD>Ϊ:{ex.Message}", Severity.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,6 +101,7 @@ namespace TechHelper.Client.Pages.Editor
|
||||
AIParseResult = respon;
|
||||
|
||||
ProgStatues = ProgEnum.AIRectify.ToString();
|
||||
Snackbar.Add($"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", Severity.Info);
|
||||
//await ReCorrectXMLAsync();
|
||||
|
||||
|
||||
@@ -124,12 +126,12 @@ namespace TechHelper.Client.Pages.Editor
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add("<22><><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>°<EFBFBD>" + ex.Message);
|
||||
Snackbar.Add("<22><><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>°<EFBFBD>" + ex.Message, Severity.Error);
|
||||
}
|
||||
if (string.IsNullOrEmpty(respon))
|
||||
{
|
||||
lode = false;
|
||||
Snackbar.Add("<22><><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>°<EFBFBD>");
|
||||
Snackbar.Add("<22><><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>°<EFBFBD>", Severity.Error);
|
||||
|
||||
}
|
||||
|
||||
@@ -146,16 +148,58 @@ namespace TechHelper.Client.Pages.Editor
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
Snackbar.Add("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" + ex.Message);
|
||||
Snackbar.Add("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" + ex.Message, Severity.Error);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" + ex.Message);
|
||||
Snackbar.Add("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" + ex.Message, Severity.Error);
|
||||
Error = ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DeleteFromParse(int index)
|
||||
{
|
||||
if (index >= 0 && index < ParseResult.Count)
|
||||
{
|
||||
ParseResult.RemoveAt(index);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[Inject]
|
||||
public IJSRuntime JSRuntime { get; set; }
|
||||
|
||||
private IJSObjectReference jSObjectReference { get; set; }
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
jSObjectReference = await JSRuntime.InvokeAsync<IJSObjectReference>("import",
|
||||
"./scripts/jsTools.js");
|
||||
}
|
||||
|
||||
private async Task CopyToClipboard()
|
||||
{
|
||||
try
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD> JavaScript <20><><EFBFBD><EFBFBD>
|
||||
bool success = await jSObjectReference.InvokeAsync<bool>("copyTextToClipboard", AIConfiguration.ParseSignelQuestion2);
|
||||
|
||||
if (success)
|
||||
{
|
||||
Snackbar.Add("<22>ı<EFBFBD><C4B1>ѳɹ<D1B3><C9B9><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>壡");
|
||||
}
|
||||
else
|
||||
{
|
||||
Snackbar.Add("<22><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܡ<EFBFBD>");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add($"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: {ex.Message}");
|
||||
Console.WriteLine($"<22><><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseQuestions()
|
||||
{
|
||||
ParsedQuestions = new List<ParsedQuestion>();
|
||||
|
@@ -8,10 +8,6 @@
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center">
|
||||
<MudText Typo="@(IsNested ? Typo.h6 : Typo.h5)">@QuestionGroup.Id. </MudText> @* 嵌套时字号稍小 *@
|
||||
<MudText Typo="@(IsNested ? Typo.h6 : Typo.h5)">@QuestionGroup.Title</MudText>
|
||||
@if (!string.IsNullOrEmpty(QuestionGroup.ScoreProblemMarker))
|
||||
{
|
||||
<MudText Typo="Typo.caption" Color="Color.Warning" Class="ml-2">( @QuestionGroup.ScoreProblemMarker )</MudText>
|
||||
}
|
||||
</MudStack>
|
||||
@if (!string.IsNullOrEmpty(QuestionGroup.QuestionReference))
|
||||
{
|
||||
@@ -32,10 +28,6 @@
|
||||
<MudStack Row="true" AlignItems="AlignItems.Baseline" Class="mb-2">
|
||||
<MudText Typo="Typo.body1">@qitem.SubId. </MudText>
|
||||
<MudText Typo="Typo.body1">@qitem.Stem</MudText>
|
||||
@if (!string.IsNullOrEmpty(qitem.ScoreProblemMarker))
|
||||
{
|
||||
<MudText Typo="Typo.caption" Color="Color.Warning" Class="ml-1">( @qitem.ScoreProblemMarker )</MudText>
|
||||
}
|
||||
</MudStack>
|
||||
@if (!string.IsNullOrEmpty(qitem.SampleAnswer))
|
||||
{
|
||||
|
@@ -29,6 +29,7 @@
|
||||
<a href="" class="reload">Reload</a>
|
||||
<a class="dismiss">🗙</a>
|
||||
</div>
|
||||
<script src="scripts/jsTools.js"></script>
|
||||
<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
|
||||
@@ -37,4 +38,5 @@
|
||||
<script src="_content/Blazored.TextEditor/Blazored-BlazorQuill.js"></script>
|
||||
</body>
|
||||
|
||||
|
||||
</html>
|
||||
|
15
TechHelper.Client/wwwroot/scripts/jsTools.js
Normal file
15
TechHelper.Client/wwwroot/scripts/jsTools.js
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
export async function copyTextToClipboard(text) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error('复制失败:', err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function show(message) {
|
||||
alert(message);
|
||||
}
|
Reference in New Issue
Block a user