123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- using IES.ExamServer.DI;
- using IES.ExamServer.DI.SignalRHost;
- using IES.ExamServer.Helper;
- using IES.ExamServer.Helpers;
- using IES.ExamServer.Models;
- using Microsoft.AspNetCore.SignalR;
- using Microsoft.Extensions.Caching.Memory;
- using System.IO;
- using System.Net.Http;
- using System.Text.Json.Nodes;
- using System.Text.RegularExpressions;
- namespace IES.ExamServer.Services
- {
- public class ManageService
- {
- public async static Task<(EvaluationClient? evaluationCloud, string centerCode, string centerMsg)> GetEvaluationFromCenter(string? x_auth_token, IConfiguration _configuration,IHttpClientFactory _httpClientFactory, string shortCode, string evaluationId)
- {
- EvaluationClient? evaluationCloud = null;
- string centerCode = string.Empty, centerMsg = string.Empty;
- string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
- var client = _httpClientFactory.CreateClient();
- if (client.DefaultRequestHeaders.Contains(Constant._X_Auth_AuthToken))
- {
- client.DefaultRequestHeaders.Remove(Constant._X_Auth_AuthToken);
- }
- client.DefaultRequestHeaders.Add(Constant._X_Auth_AuthToken, x_auth_token);
- try
- {
- HttpResponseMessage message = await client.PostAsJsonAsync($"{CenterUrl}/evaluation-sync/find-sync-info", new { shortCode, evaluationId });
- if (message.IsSuccessStatusCode)
- {
- string content = await message.Content.ReadAsStringAsync();
- JsonNode? jsonNode = content.ToObject<JsonNode>();
- if (jsonNode != null)
- {
- centerCode = $"{jsonNode["code"]}";
- centerMsg = $"{jsonNode["msg"]}";
- if ($"{jsonNode["code"]}".Equals("200"))
- {
- evaluationCloud = jsonNode["evaluation"]?.ToObject<EvaluationClient>();
- }
- }
- else
- {
- centerCode = "500";
- centerMsg = "数据转换异常";
- }
- }
- else
- {
- centerCode = $"{message.StatusCode}";
- centerMsg = "数据中心访问异常";
- }
- }
- catch (Exception ex)
- {
- centerCode = $"500";
- centerMsg = $"数据中心访问异常:{ex.Message}";
- }
- return (evaluationCloud, centerCode, centerMsg);
- }
- /// <summary>
- /// 检查本地评测文件,文件包,名单信息
- /// </summary>
- /// <param name="evaluationLocal"></param>
- /// <param name="evaluationCloud"></param>
- /// <param name="msgs"></param>
- /// <param name="_liteDBFactory"></param>
- /// <returns></returns>
- public async static Task<(List<string> successMsgs, List<string> errorMsgs)> CheckFile(EvaluationClient evaluationLocal, List<string> successMsgs,List<string> errorMsgs, IHubContext<SignalRExamServerHub> _signalRExamServerHub,
- IMemoryCache _memoryCache, ILogger _logger, string deviceId,string evaluationPath)
- {
-
-
- int msg_status = Constant._Message_status_info;
- string content = msg_status.Equals(Constant._Message_status_success) ? "成功" : "失败";
-
- if (!Directory.Exists(evaluationPath))
- {
-
- errorMsgs.Add($"评测目录不存在:{evaluationPath}");
- }
- else
- {
- string evaluationDataPath = Path.Combine(evaluationPath, "data");
- string path_groupList = Path.Combine(evaluationDataPath, "groupList.json");
- msg_status =Constant._Message_status_info;
- if (!System.IO.File.Exists(path_groupList))
- {
- msg_status=Constant._Message_status_error;
- }
- else
- {
- msg_status=Constant._Message_status_success;
-
-
- }
- await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
- new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType= Constant._Message_type_check, status=msg_status, content="评测名单文件(groupList.json)" });
- content = msg_status.Equals(Constant._Message_status_success) ? "成功" : "失败";
- if (msg_status.Equals(Constant._Message_status_success)|| msg_status.Equals(Constant._Message_status_info))
- {
- successMsgs.Add($"评测名单文件(groupList.json),检测结果:{content}");
- }
- else
- {
- errorMsgs.Add($"评测名单文件(groupList.json),检测结果:{content}");
- }
- string path_source = Path.Combine(evaluationDataPath, "source.json");
- msg_status = Constant._Message_status_info;
- if (!System.IO.File.Exists(path_source))
- {
- msg_status=Constant._Message_status_error;
-
-
- }
- else
- {
- msg_status=Constant._Message_status_success;
-
-
- }
- await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
- new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType= Constant._Message_type_check, status=msg_status, content="评测原始数据(source.json)" });
- content = msg_status.Equals(Constant._Message_status_success) ? "成功" : "失败";
-
- if (msg_status.Equals(Constant._Message_status_success)|| msg_status.Equals(Constant._Message_status_info))
- {
- successMsgs.Add($"评测原始数据(source.json),检测结果:{content}");
- }
- else
- {
- errorMsgs.Add($"评测原始数据(source.json),检测结果:{content}");
- }
- msg_status =Constant._Message_status_info;
- try
- {
- //TODO 重整本地文件路径。 文件可能不存在D:\VisualStudioProjects\TEAMModelOS\TEAMModelOS.Extension\IES.Exam\IES.ExamServer\wwwroot\package\exam\6af32bbd-144e-4366-8bc0-61ba4c85677c\evaluation.json
- string path_evaluation = Path.Combine(evaluationDataPath, "evaluation.json");
- if (!System.IO.File.Exists(path_evaluation))
- {
- msg_status=Constant._Message_status_error;
-
-
- }
- else
- {
- msg_status=Constant._Message_status_success;
-
-
- }
- //数据格式: [消息][信息/错误/警告][15:43]=>[开始检查评测信息文件...]
- //数据格式: [检查][成功/失败][15:43]=>[评测数据文件:/wwwroot/package/623a9fe6-5445-0938-ff77-aeb80066ef27/evaluation.json]
- //数据格式: [下载][成功/失败][15:43]=>[评测数据文件:/wwwroot/package/623a9fe6-5445-0938-ff77-aeb80066ef27/evaluation.json][1024kb][15ms]
- await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
- new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType= Constant._Message_type_check, status=msg_status, content="评测数据文件(evaluation.json)" });
- content = msg_status.Equals(Constant._Message_status_success) ? "成功" : "失败";
- if (msg_status.Equals(Constant._Message_status_success)|| msg_status.Equals(Constant._Message_status_info))
- {
- successMsgs.Add($"评测数据文件(evaluation.json),检测结果:{content}");
- }
- else
- {
- errorMsgs.Add($"评测数据文件(evaluation.json),检测结果:{content}");
- }
- if (System.IO.File.Exists(path_evaluation))
- {
- string evaluation_str = await System.IO.File.ReadAllTextAsync(path_evaluation);
- JsonNode? evaluation_data = evaluation_str.ToObject<JsonNode>();
- if (evaluation_data==null)
- {
-
-
- msg_status=Constant._Message_status_error;
- await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
- new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType= Constant._Message_type_check, status=msg_status, content="评测数据文件(evaluation.json),文件读取失败!" });
- errorMsgs.Add("评测数据文件(evaluation.json),文件读取失败!");
- }
- else
- {
- EvaluationClient? evaluationClient = evaluation_data["evaluationClient"]?.ToObject<EvaluationClient>();
- if (evaluationClient!=null)
- {
-
-
- await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
- new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType=Constant._Message_type_message, status=msg_status, content="评测数据文件(evaluation.json),读取评测基本信息..." });
- successMsgs.Add($"评测数据文件(evaluation.json),读取评测基本信息...");
- if (!string.IsNullOrWhiteSpace(evaluationLocal.blobHash) && evaluationLocal.blobHash.Equals(evaluationClient.blobHash)
- &&(evaluationLocal.blobTime==evaluationClient.blobTime)
- &&(evaluationLocal.blobCount== evaluationClient.blobCount)
- &&(evaluationLocal.blobSize== evaluationClient.blobSize)
- && (evaluationLocal.dataTime==evaluationClient.dataTime)
- &&(evaluationLocal.dataSize==evaluationClient.dataSize)
- )
- {
- msg_status=Constant._Message_status_info;
- }
- else
- {
- msg_status=Constant._Message_status_error;
- }
- await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
- new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType=Constant._Message_type_message, status=msg_status, content="评测数据文件(evaluation.json),校验评测基本信息..." });
- content = msg_status.Equals(Constant._Message_status_success)||msg_status.Equals(Constant._Message_status_info) ? "成功" : "失败";
- if (msg_status.Equals(Constant._Message_status_success)|| msg_status.Equals(Constant._Message_status_info))
- {
- successMsgs.Add($"评测数据文件(evaluation.json),校验评测基本信息,检测结果:{content}");
- }
- else
- {
- errorMsgs.Add($"评测数据文件(evaluation.json),校验评测基本信息,检测结果:{content}"); ;
- }
- }
- else
- {
-
-
- msg_status=Constant._Message_status_error;
- await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
- new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType= Constant._Message_type_check, status=msg_status, content="评测数据文件(evaluation.json),读取评测基本信息失败!" });
- errorMsgs.Add("评测数据文件(evaluation.json),读取评测基本信息失败!");
- }
- List<EvaluationExam>? evaluationExams = evaluation_data["evaluationExams"]?.ToObject<List<EvaluationExam>>();
- if (evaluationExams.IsEmpty())
- {
-
-
- msg_status=Constant._Message_status_error;
- content = msg_status.Equals(Constant._Message_status_success)||msg_status.Equals(Constant._Message_status_info) ? "成功" : "失败";
- errorMsgs.Add($"评测数据文件(evaluation.json),读取评测试卷信息失败");
- }
- else
- {
- msg_status=Constant._Message_status_info;
- await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
- new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType=Constant._Message_type_message, status=msg_status, content="评测数据文件(evaluation.json),读取评测试卷信息..." });
- successMsgs.Add($"评测数据文件(evaluation.json),读取评测试卷信息...");
- string pattern = @"paper/[^/]+/([^/]+/[^/]+\.[^/]+)";
- foreach (var evaluationExam in evaluationExams!)
- {
- msg_status=Constant._Message_status_info;
- await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
- new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType=Constant._Message_type_message, status=msg_status, content=$"校验评测科目试卷:{evaluationExam.subjectName}-{evaluationExam.examName}" });
- successMsgs.Add($"校验评测科目试卷:{evaluationExam.subjectName}-{evaluationExam.examName}");
- string path_papers = Path.Combine(evaluationPath, "papers");
- var papers_files = FileHelper.ListAllFiles(path_papers);
- int paperIndex = 0;
- foreach (var paper in evaluationExam.papers)
- {
- paperIndex++;
- List<MessageContent> contents = new List<MessageContent>();
- int blob_error_count = 0;
- foreach (var blobInfo in paper.blobs)
- {
- msg_status=Constant._Message_status_info;
- if (!string.IsNullOrWhiteSpace(blobInfo.path))
- {
- Match match = Regex.Match(blobInfo.path, pattern);
- if (match.Success)
- {
- string result = match.Groups[1].Value.Replace("/", "\\");
-
- string extension = Path.GetExtension(result);
- if (extension.Equals(extension.ToUpper()))
- {
- string fileName = Path.GetFileNameWithoutExtension(result);
- result= $"{fileName!}_1{extension}";
- }
-
- var file = papers_files.Find(x => x.Contains(result));
- if (file!=null)
- {
- msg_status=1;
- msg_status=Constant._Message_status_success;
- }
- else
- {
- msg_status=Constant._Message_status_error;
- blob_error_count++;
- errorMsgs.Add($"试卷名称:[{paperIndex}]{evaluationExam.examName}-{evaluationExam.subjectName}-{paper.paperName},未匹配到本地文件:{blobInfo.path}");
- }
- }
- else
- {
- msg_status=Constant._Message_status_error;
- blob_error_count++;
- errorMsgs.Add($"试卷名称:[{paperIndex}]{evaluationExam.examName}-{evaluationExam.subjectName}-{paper.paperName},未提取到正则匹配的文件:{blobInfo.path}");
- }
- }
- else
- {
- msg_status=Constant._Message_status_error; ;
- blob_error_count++;
- errorMsgs.Add($"试卷名称:[{paperIndex}]{evaluationExam.examName}-{evaluationExam.subjectName}-{paper.paperName},文件路径为空:{blobInfo.ToJsonString()}");
- }
-
- contents.Add(new MessageContent
- {
- dataId=evaluationLocal.id,
- dataName=evaluationLocal.name,
- messageType=Constant._Message_type_check,
- status=msg_status,
- content=$"试卷文件信息:{paper.paperName}"
- });
- }
- int paper_msg_status = Constant._Message_status_info;
- if (blob_error_count>0)
- {
- paper_msg_status=Constant._Message_status_error;
- errorMsgs.Add($"试卷名称:[{paperIndex}]{evaluationExam.examName}-{evaluationExam.subjectName}-{paper.paperName},文件数量:{paper.blobs.Count()},检测成功数量:{contents.Count(x => x.status==Constant._Message_status_success)},检测异常数量{contents.Count(x => x.status==Constant._Message_status_error)}");
- }
- else
- {
- paper_msg_status=Constant._Message_status_success;
- successMsgs.Add($"试卷名称:[{paperIndex}]{evaluationExam.examName}-{evaluationExam.subjectName}-{paper.paperName},文件数量:{paper.blobs.Count()},检测成功数量:{contents.Count(x => x.status==Constant._Message_status_success)},检测异常数量{contents.Count(x => x.status==Constant._Message_status_error)}");
- }
- await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
- new MessageContent
- {
- dataId=evaluationLocal.id,
- dataName=evaluationLocal.name,
- messageType=Constant._Message_type_message,
- status=paper_msg_status,
- content=$"试卷名称:[{paperIndex}]{evaluationExam.examName}-{evaluationExam.subjectName}-{paper.paperName},文件数量:{paper.blobs.Count()},检测成功数量:{contents.Count(x => x.status==Constant._Message_status_success)},检测异常数量{contents.Count(x => x.status==Constant._Message_status_error)}",
- contents=contents
- });
- }
- }
- }
- }
- }
- }
- catch (Exception e)
- {
- errorMsgs.Add($"校验评测试卷文件信息异常:{e.Message}");
- _logger.LogData<object>(new { code = 500, msg = e.Message, data = new { content = e.StackTrace } }, evaluationLocal.id!);
- }
- }
- return (successMsgs , errorMsgs);
- }
- public static (EvaluationCheckDataResult result, EvaluationClient? evaluationLocal) CheckData( EvaluationClient? evaluationLocal, EvaluationClient? evaluationCloud, List<string> successMsgs,List<string> errorMsgs, LiteDBFactory _liteDBFactory )
- {
- //数据,文件,页面 0 没有更新,1 有更新
- int data=0, blob=0, groupList=0, status=0,zip=0;
- long dataSize=0, blobSize=0, studentCount=0;
- if (evaluationLocal== null && evaluationCloud==null)
- {
- //线上线下没有数据
- status=1;
- errorMsgs.Add($"本地和数据中心均没查询到评测!");
- }
- else if (evaluationLocal!=null && evaluationCloud!=null)
- {
- successMsgs.Add($"检测到本地和数据中心均有数据!");
- //线上线下有数据
- status = 2;
- if ((!string.IsNullOrWhiteSpace(evaluationLocal.blobHash) && !evaluationLocal.blobHash.Equals(evaluationCloud.blobHash))
- ||(evaluationLocal.blobTime<evaluationCloud.blobTime)
- ||(evaluationLocal.blobCount!= evaluationCloud.blobCount)
- ||(evaluationLocal.blobSize!= evaluationCloud.blobSize))
- {
- blob=1;
- blobSize=evaluationCloud.blobSize;
- errorMsgs.Add($"文件包校验失败,需要更新文件包!");
- }
- if ((evaluationLocal.dataTime<evaluationCloud.dataTime)
- ||(evaluationLocal.dataSize!=evaluationCloud.dataSize)
- ||(evaluationLocal.paperCount!= evaluationCloud.paperCount)
- )
- {
- data=1;
- errorMsgs.Add($"数据包校验失败,需要更新数据包!");
- dataSize=evaluationCloud.dataSize;
- }
- if ((evaluationLocal.studentCount!= evaluationCloud.studentCount)||(!$"{evaluationLocal.grouplistHash}".Equals(evaluationCloud.grouplistHash)))
- {
- groupList=1;
- studentCount=evaluationCloud.studentCount;
- errorMsgs.Add($"名单信息校验失败,需要更新名单信息!");
- }
- // evaluationLocal=evaluationCloud;
- // _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationClient>().Upsert(evaluationLocal);
- }
- else if (evaluationLocal!=null && evaluationCloud==null)
- {
- //线下有数据,线上没有数据,可能没联网。
- status = 3;
- successMsgs.Add($"数据中心未连接,使用本地数据进行作答!");
- }
- else if (evaluationLocal==null && evaluationCloud!=null)
- {
- //线下没有数据,线上有数据
- evaluationLocal= evaluationCloud;
- blob=1;
- data=1;
- groupList=1;
- blobSize=evaluationCloud.blobSize;
- dataSize=evaluationCloud.dataSize;
- studentCount=evaluationCloud.studentCount;
- status = 4;
- //foreach (var subject in evaluationLocal.subjects)
- //{
- // foreach (var paper in subject.papers)
- // {
- // paper.blob=$"package/{evaluationLocal.id}/papers/{paper.paperId}";
- // }
- //}
- _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationClient>().Upsert(evaluationLocal);
- errorMsgs.Add($"获取到最新的评测数据,需要下载数据包,文件包,名单信息!");
- }
- EvaluationCheckDataResult checkDataResult= new EvaluationCheckDataResult { data = data, blob = blob, groupList = groupList, status = status, dataSize = dataSize, blobSize = blobSize, studentCount = studentCount,zip=zip ,successMsgs=successMsgs,errorMsgs=errorMsgs};
- return (checkDataResult, evaluationLocal);
- }
-
- public class EvaluationCheckDataResult
- {
- public int zip { get; set; }
- public int data { get; set; }
- public int blob { get; set; }
- public int groupList { get; set; }
- public int status { get; set; }
- public long dataSize { get; set; }
- public long blobSize { get; set; }
- public long studentCount { get; set; }
- public List<string> successMsgs { get; set; } = new List<string>();
- public List<string> errorMsgs { get; set; } = new List<string>();
- }
- public class EvaluationCheckFileResult
- {
- public int checkTotal { get; set; }
- public int checkSuccess { get; set; }
- public int checkError { get; set; }
- public List<string> successMsgs { get; set; } = new List<string>();
- public List<string> errorMsgs { get; set; } = new List<string>();
- }
- }
- }
|