ImportExerciseService.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. using DocumentFormat.OpenXml.Packaging;
  2. using HtmlAgilityPack;
  3. using Microsoft.AspNetCore.Http;
  4. using OpenXmlPowerTools;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Drawing.Imaging;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Text.RegularExpressions;
  12. using System.Threading.Tasks;
  13. using System.Xml.Linq;
  14. using TEAMModelOS.Model.Core.Dtos;
  15. using TEAMModelOS.Model.Core.Models;
  16. using TEAMModelOS.Model.Evaluation.Dtos.Own;
  17. using TEAMModelOS.Model.Evaluation.Models;
  18. using TEAMModelOS.SDK.Context.Configuration;
  19. using TEAMModelOS.SDK.Context.Constant;
  20. using TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest;
  21. using TEAMModelOS.SDK.Extension.SnowFlake;
  22. using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
  23. using TEAMModelOS.SDK.Helper.Common.FileHelper;
  24. using TEAMModelOS.SDK.Helper.Common.JsonHelper;
  25. using TEAMModelOS.SDK.Helper.Common.StringHelper;
  26. using TEAMModelOS.SDK.Helper.Network.HttpHelper;
  27. using TEAMModelOS.SDK.Helper.Security.ShaHash;
  28. using TEAMModelOS.SDK.Module.AzureBlob.Container;
  29. using TEAMModelOS.SDK.Module.AzureBlob.Implements;
  30. using TEAMModelOS.SDK.Module.AzureBlob.Interfaces;
  31. using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
  32. using TEAMModelOS.SDK.Module.PowerPointX;
  33. using TEAMModelOS.SDK.Module.PowerPointX.Model;
  34. using TEAMModelOS.Service.Core.Implements;
  35. using TEAMModelOS.Service.Evaluation.Interfaces;
  36. namespace TEAMModelOS.Service.Evaluation.Implements
  37. {
  38. public class ImportExerciseService : BaseService, IImportExerciseService
  39. {
  40. private static string SummaryTag = "【题文】";
  41. private static string AnswerTag = "【答案】";
  42. private static string AnalysisTag = "【解析】";
  43. private static string EndedTag = "【结束】";
  44. private static string Options = "ABCDEFGHIJ";
  45. private static string CompleteStart = "【";
  46. private static string CompleteEnd = "】";
  47. Dictionary<string, string> TestType = new Dictionary<string, string> {
  48. { "Single", "单选题|多选题" }, { "Multiple", "多选题|判断题" },
  49. { "Judge", "判断题|填空题" }, { "Complete", "填空题|主观题" },
  50. { "Subjective", "主观题|【完结】" } };
  51. private readonly IHttpContextAccessor httpContextAccessor;
  52. private readonly IAzureBlobDBRepository azureBlobDBRepository;
  53. public ImportExerciseService(IHttpContextAccessor _httpContextAccessor, IAzureBlobDBRepository _azureBlobDBRepository)
  54. {
  55. azureBlobDBRepository = _azureBlobDBRepository;
  56. httpContextAccessor = _httpContextAccessor;
  57. }
  58. public async Task<Dictionary<string, object>> UploadPPTX(IFormFile file) {
  59. Dictionary<string, object> resdict = new Dictionary<string, object>();
  60. PresentationConvert convert = new PresentationConvert();
  61. PPTXInfo info= convert.LoadPresentation(file.OpenReadStream());
  62. resdict.Add("pptx", info);
  63. return resdict;
  64. }
  65. public async Task<Dictionary<string, object>> UploadWord(IFormFile file)
  66. {
  67. Dictionary<string, object> resdict = new Dictionary<string, object>();
  68. string shaCode = ShaHashHelper.GetSHA1(file.OpenReadStream());
  69. long length = file.Length;
  70. Dictionary<string, object> dict = new Dictionary<string, object> { { "Sha1Code", shaCode } };
  71. List<AzureBlobModel> models = await FindListByDict<AzureBlobModel>(dict);
  72. //if (models.IsNotEmpty())
  73. //{
  74. // resdict.Add("HtmlString", HttpHelper.HttpGet(models[0].BlobUrl));
  75. // resdict.Add("Sha1Code", models[0].Sha1Code);
  76. // return resdict;
  77. //}
  78. string folder = BaseConfigModel.ContentRootPath + "/Upload/" + IdWorker.getInstance().NextId();
  79. System.IO.Directory.CreateDirectory(folder);
  80. var filePath = folder +"\\"+ file.FileName;
  81. using (var stream = new FileStream(filePath, FileMode.Create))
  82. {
  83. await file.CopyToAsync(stream);
  84. }
  85. var htmlInfo = ConvertDocxToHtml(filePath, folder);
  86. AzureBlobModel model = await azureBlobDBRepository.UploadPath(htmlInfo.blobPath);
  87. model.Sha1Code = shaCode;
  88. await Save<AzureBlobModel>(model);
  89. FileHelper.DeleteDirAndFiles(BaseConfigModel.ContentRootPath + "/Upload");
  90. resdict.Add("HtmlString", htmlInfo.htmlString);
  91. resdict.Add("Sha1Code", shaCode);
  92. return resdict;
  93. }
  94. public dynamic ConvertDocxToHtml(string filePath, string folder)
  95. {
  96. string FolderName = DateTime.Now.ToString("yyyyMMdd");
  97. byte[] byteArray = File.ReadAllBytes(filePath);
  98. //byte[] bytes = new byte[stream.Length];
  99. using (MemoryStream memoryStream = new MemoryStream())
  100. {
  101. memoryStream.Write(byteArray, 0, byteArray.Length);
  102. using (WordprocessingDocument doc = WordprocessingDocument.Open(memoryStream, true))
  103. {
  104. int imageCounter = 0;
  105. WmlToHtmlConverterSettings settings = new WmlToHtmlConverterSettings()
  106. {
  107. PageTitle = "",
  108. AdditionalCss = "body { margin: 1cm auto; max-width: 20cm; padding: 0; }",
  109. FabricateCssClasses = true,
  110. CssClassPrefix = "pt-",
  111. RestrictToSupportedLanguages = false,
  112. RestrictToSupportedNumberingFormats = false,
  113. ImageHandler = imageInfo =>
  114. {
  115. ++imageCounter;
  116. string extension = imageInfo.ContentType.Split('/')[1].ToLower();
  117. ImageFormat imageFormat = null;
  118. if (extension.Equals("png")) imageFormat = ImageFormat.Png;
  119. else if (extension.Equals("gif")) imageFormat = ImageFormat.Gif;
  120. else if (extension.Equals("bmp")) imageFormat = ImageFormat.Bmp;
  121. else if (extension.Equals("jpeg")) imageFormat = ImageFormat.Jpeg;
  122. else if (extension.Equals("tiff"))
  123. {
  124. extension = "gif";
  125. imageFormat = ImageFormat.Gif;
  126. }
  127. else if (extension.Equals( "x-wmf"))
  128. {
  129. extension = "wmf";
  130. imageFormat = ImageFormat.Wmf;
  131. }
  132. if (imageFormat == null) return null;
  133. string base64 = null;
  134. string mimeType = null;
  135. string shaCode = null;
  136. try
  137. {
  138. if (extension.Equals("wmf"))
  139. {
  140. var buffer = Encoding.Default.GetBytes(imageInfo.Mathxml);
  141. base64 = System.Convert.ToBase64String(buffer);
  142. mimeType = "image/svg+xml";
  143. shaCode = ShaHashHelper.GetSHA1( new MemoryStream(buffer));
  144. }
  145. else {
  146. ImageFormat format = imageInfo.Bitmap.RawFormat;
  147. ImageCodecInfo codec = ImageCodecInfo.GetImageDecoders()
  148. .First(c => c.FormatID == format.Guid);
  149. mimeType = codec.MimeType;
  150. using (MemoryStream ms = new MemoryStream())
  151. {
  152. imageInfo.Bitmap.Save(ms, imageFormat);
  153. var ba = ms.ToArray();
  154. base64 = System.Convert.ToBase64String(ba);
  155. shaCode = ShaHashHelper.GetSHA1(ms);
  156. }
  157. }
  158. }
  159. catch (System.Runtime.InteropServices.ExternalException)
  160. { return null; }
  161. string imageSource =
  162. string.Format("data:{0};base64,{1}", mimeType, base64);
  163. #region 处理图片存到Bolb
  164. string[] strs = imageSource.Split(',');
  165. string fileExt = StringHelper.SubMidString(strs[0], ":", ";");
  166. if (ContentTypeDict.extdict.TryGetValue(fileExt, out string ext))
  167. {
  168. fileExt = ext;
  169. }
  170. else
  171. {
  172. //解决多种扩展名不能获取的
  173. string[] sp = StringHelper.SubMidString(strs[0], "/", ";").Split("-");
  174. fileExt = sp[sp.Length - 1];
  175. sp = fileExt.Split("+");
  176. fileExt = "." + sp[sp.Length - 1];
  177. }
  178. Stream stream = new MemoryStream(Convert.FromBase64String(strs[1]));
  179. // long bizno = IdWorker.getInstance().NextId();
  180. string filename = shaCode + fileExt;
  181. AzureBlobModel model = azureBlobDBRepository.UploadFileByFolderNAsyn(stream, FolderName, filename, "exercise", false);
  182. #endregion
  183. XElement img = new XElement(Xhtml.img,
  184. new XAttribute(NoNamespace.src, model.BlobUrl),
  185. imageInfo.ImgStyleAttribute,
  186. imageInfo.AltText != null ?
  187. new XAttribute(NoNamespace.alt, imageInfo.AltText) : null);
  188. stream.Close();
  189. return img;
  190. }
  191. };
  192. // XElement html = HtmlConverter.ConvertToHtml(doc, settings);
  193. // File.WriteAllText(@"E:\document\kk.html", html.ToStringNewLineOnAttributes());
  194. XElement htmlElement = WmlToHtmlConverter.ConvertToHtml(doc, settings);
  195. var htmls = new XDocument(new XDocumentType("html", null, null, null), htmlElement);
  196. var htmlString = htmls.ToString(SaveOptions.DisableFormatting);
  197. //引入MathJax插件
  198. htmlString = htmlString + "<script type=\"text/javascript\" src=\"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>";
  199. File.WriteAllText(folder + "/" + "index.html", htmlString);
  200. return new { htmlString, blobPath = folder + "/" + "index.html" };
  201. };
  202. }
  203. }
  204. public async Task<List<ExerciseDto>> AnalyzeWordAsync(DocInfoDto dict, string Lang)
  205. {
  206. List<ContentVerify> contents = await this.FindListByKey<ContentVerify>("DigestCode", dict.ShaCode);
  207. string html="";
  208. if (contents.IsNotEmpty())
  209. {
  210. html = contents[0].Content;
  211. }
  212. else
  213. {
  214. }
  215. //String url = "https://teammodelstorage.blob.core.chinacloudapi.cn/teammodelcontest/20190517/%E6%A8%A1%E6%9D%BF%E6%A0%B7%E4%BE%8B.doc";
  216. Dictionary<string, string> TestInType = new Dictionary<string, string>();
  217. html = html.Replace("\t", " ").Replace("<span>", "").Replace("</span>", "");
  218. //去除class
  219. string classpattern = "class=\"([^\"]*)\"";
  220. html = Regex.Replace(html, classpattern, "");
  221. string pattern = "<span([^>]{0,})>";
  222. html = Regex.Replace(html, pattern, "");
  223. foreach (string key in TestType.Keys)
  224. {
  225. string[] tags = TestType[key].Split("|");
  226. string RegexStr = tags[0] + "([\\s\\S]*?)" + tags[1];
  227. Match mt = Regex.Match(html, RegexStr);
  228. TestInType.Add(key, mt.Value);
  229. }
  230. List<ExerciseDto> tests = new List<ExerciseDto>();
  231. ///解析几种题型的题目
  232. foreach (string key in TestInType.Keys)
  233. {
  234. switch (key)
  235. {
  236. case "Single":
  237. List<ExerciseDto> exercisesSingle = SingleConvert(key, TestInType[key]);
  238. tests.AddRange(exercisesSingle); break;
  239. case "Multiple":
  240. List<ExerciseDto> exercisesMultiple = MultipleConvert(key, TestInType[key]);
  241. tests.AddRange(exercisesMultiple); break;
  242. case "Judge":
  243. List<ExerciseDto> exercisesJudge = JudgeConvert(key, TestInType[key]);
  244. tests.AddRange(exercisesJudge); break;
  245. case "Complete":
  246. List<ExerciseDto> exercisesComplete = CompleteConvert(key, TestInType[key]);
  247. tests.AddRange(exercisesComplete); break;
  248. case "Subjective":
  249. List<ExerciseDto> exercisesSubjective = SubjectiveConvert(key, TestInType[key]);
  250. tests.AddRange(exercisesSubjective); break;
  251. default: break;
  252. }
  253. }
  254. ///SaveExercise(tests, Lang);
  255. return tests;
  256. }
  257. //public async void SaveExercise(List<ExerciseDto> exercises, string Lang)
  258. //{
  259. // string tmdid = "";
  260. // List<string> ids = HttpContextHelper.GetLoginUser(httpContextAccessor, "id");
  261. // if (ids.IsNotEmpty())
  262. // {
  263. // tmdid = ids[0];
  264. // }
  265. // List<ExerciseVerify> exerciseVerifies = new List<ExerciseVerify>();
  266. // exercises.ForEach(x =>
  267. // {
  268. // ExerciseVerify exercise0 = new ExerciseVerify { TeamModelId = tmdid, RowKey = x.ShaCode, Type = 0, PartitionKey = Lang, Content = x.Question, SummaryCode = x.ShaCode, Status = 1 };
  269. // exerciseVerifies.Add(exercise0);
  270. // if (x.Option.IsNotEmpty())
  271. // {
  272. // string opt = MessagePackHelper.ObjectToJson(x.Option);
  273. // ExerciseVerify exercise1 = new ExerciseVerify { TeamModelId = tmdid, RowKey = x.ShaCode + "-" + ShaHashHelper.GetSHA1(opt), Type = 1, PartitionKey = Lang, Content = opt, SummaryCode = x.ShaCode, Status = 1 };
  274. // exerciseVerifies.Add(exercise1);
  275. // }
  276. // if (x.Answer.IsNotEmpty())
  277. // {
  278. // string ans = MessagePackHelper.ObjectToJson(x.Answer);
  279. // ExerciseVerify exercise2 = new ExerciseVerify { TeamModelId = tmdid, RowKey = x.ShaCode + "-" + ShaHashHelper.GetSHA1(ans), Type = 2, PartitionKey = Lang, Content = ans, SummaryCode = x.ShaCode, Status = 1 };
  280. // exerciseVerifies.Add(exercise2);
  281. // }
  282. // ExerciseVerify exercise3 = new ExerciseVerify { TeamModelId = tmdid, RowKey = x.ShaCode + "-" + ShaHashHelper.GetSHA1(x.Explain), Type = 3, PartitionKey = Lang, Content = x.Explain, SummaryCode = x.ShaCode, Status = 1 };
  283. // exerciseVerifies.Add(exercise3);
  284. // });
  285. // await this.SaveOrUpdateAll(exerciseVerifies);
  286. //}
  287. public static List<ExerciseDto> SingleConvert(string TypeKey, string testHtml)
  288. {
  289. List<ExerciseDto> testInfos = OptionProcess(TypeKey, testHtml);
  290. return testInfos;
  291. }
  292. public static List<ExerciseDto> MultipleConvert(string TypeKey, string testHtml)
  293. {
  294. List<ExerciseDto> testInfos = OptionProcess(TypeKey, testHtml);
  295. return testInfos;
  296. }
  297. public static List<ExerciseDto> JudgeConvert(string TypeKey, string testHtml)
  298. {
  299. List<ExerciseDto> testInfos = OptionProcess(TypeKey, testHtml);
  300. return testInfos;
  301. }
  302. public static List<ExerciseDto> CompleteConvert(string TypeKey, string testHtml)
  303. {
  304. List<ExerciseDto> testInfos = CompleteProcess(TypeKey, testHtml);
  305. return testInfos;
  306. }
  307. public static List<ExerciseDto> SubjectiveConvert(string TypeKey, string testHtml)
  308. {
  309. List<string> tests = ConvertTest(testHtml);
  310. List<ExerciseDto> testInfos = ConvertTestInfo(tests, TypeKey);
  311. foreach (ExerciseDto testInfo in testInfos)
  312. {
  313. testInfo.Question = testInfo.Question.Replace(AnalysisTag, "").Replace(SummaryTag, "").Replace(AnswerTag, "");
  314. testInfo.Question = HtmlHelper.DoUselessTag(testInfo.Question);
  315. StringBuilder textImg = new StringBuilder(HtmlHelper.DoTextImg(testInfo.Question));
  316. testInfo.ShaCode = ShaHashHelper.GetSHA1(textImg.ToString());
  317. for (int i = 0; i < testInfo.Answer.Count; i++)
  318. {
  319. testInfo.Answer[i] = testInfo.Answer[i].Replace(AnswerTag, "").Replace(AnalysisTag, "");
  320. testInfo.Answer[i] = HtmlHelper.DoUselessTag(testInfo.Answer[i]);
  321. }
  322. testInfo.Explain = testInfo.Explain.Replace(AnalysisTag, "").Replace(EndedTag, "");
  323. testInfo.Explain = HtmlHelper.DoUselessTag(testInfo.Explain);
  324. }
  325. return testInfos;
  326. }
  327. public static List<ExerciseDto> CompleteProcess(string TypeKey, string testHtml)
  328. {
  329. List<string> tests = ConvertTest(testHtml);
  330. List<ExerciseDto> testInfos = ConvertTestInfo(tests, TypeKey);
  331. HtmlDocument doc = new HtmlDocument();
  332. foreach (ExerciseDto testInfo in testInfos)
  333. {
  334. List<string> ans = new List<string>();
  335. testInfo.Question = testInfo.Question.Replace(AnalysisTag, "").Replace(SummaryTag, "").Replace(AnswerTag, "");
  336. string regRex = CompleteStart + "([\\s\\S]*?)" + CompleteEnd;
  337. List<ReplaceDto> replaces = new List<ReplaceDto>();
  338. var m = Regex.Match(testInfo.Question, regRex);
  339. int index = 1;
  340. while (m.Success)
  341. {
  342. string an = m.Groups[1].ToString();
  343. doc.LoadHtml(an);
  344. string anstr = doc.DocumentNode.InnerText;
  345. string nbsp = "";
  346. int length = System.Text.Encoding.Default.GetBytes(anstr).Length;
  347. for (int i = 0; i < length * 3; i++)
  348. {
  349. nbsp += "&nbsp;";
  350. }
  351. ReplaceDto replaceDto = new ReplaceDto { oldstr = "【" + an + "】", newstr = "<underline data=\"" + index + "\"><u>" + nbsp + "</u></underline>" };
  352. replaces.Add(replaceDto);
  353. ans.Add(an);
  354. m = m.NextMatch();
  355. index++;
  356. }
  357. string textImg = testInfo.Question;
  358. //消除答案
  359. foreach (ReplaceDto replace in replaces)
  360. {
  361. testInfo.Question = testInfo.Question.Replace(replace.oldstr, replace.newstr);
  362. testInfo.Question = HtmlHelper.DoUselessTag(testInfo.Question);
  363. //只要题干文字和图片
  364. //不加underline标记
  365. textImg = testInfo.Question.Replace(replace.oldstr, "");
  366. }
  367. textImg = HtmlHelper.DoTextImg(textImg);
  368. testInfo.ShaCode = ShaHashHelper.GetSHA1(textImg);
  369. //处理解析
  370. testInfo.Explain = testInfo.Explain.Replace(AnalysisTag, "").Replace(EndedTag, "");
  371. testInfo.Explain = HtmlHelper.DoUselessTag(testInfo.Explain);
  372. testInfo.Answer.AddRange(ans);
  373. }
  374. return testInfos;
  375. }
  376. /// <summary>
  377. /// 选择题处理
  378. /// </summary>
  379. /// <param name="TypeKey"></param>
  380. /// <param name="testHtml"></param>
  381. /// <returns></returns>
  382. public static List<ExerciseDto> OptionProcess(string TypeKey, string testHtml)
  383. {
  384. //处理 \t
  385. List<string> tests = ConvertTest(testHtml);
  386. string[] optionsKeys = Options.Select(s => s.ToString()).ToArray();
  387. List<ExerciseDto> testInfos = ConvertTestInfo(tests, TypeKey);
  388. foreach (ExerciseDto testInfo in testInfos)
  389. {
  390. string optsRgex = optionsKeys[0] + "(\\.|\\.|\\、|\\:|\\:)([\\s\\S]*?)" + AnswerTag;
  391. string optsHtml = Regex.Match(testInfo.Question, optsRgex).Value;
  392. //HtmlDocument doc = new HtmlDocument();
  393. //doc.LoadHtml(optsHtml);
  394. //optsHtml = doc.DocumentNode.InnerText;
  395. //处理选项
  396. StringBuilder textImg = new StringBuilder();
  397. for (int i = 0; i < optionsKeys.Length - 1; i++)
  398. {
  399. string optRgex = optionsKeys[i] + "(\\.|\\.|\\、|\\:|\\:)([\\s\\S]*?)" + optionsKeys[i + 1] + "(\\.|\\.|\\、|\\:|\\:)";
  400. string optHtml = Regex.Match(optsHtml, optRgex).Value;
  401. if (!string.IsNullOrEmpty(optHtml))
  402. {
  403. optHtml = optHtml.Substring(2, optHtml.Length - 4);
  404. optHtml = HtmlHelper.DoUselessTag(optHtml);
  405. textImg.Append(HtmlHelper.DoTextImg(optHtml));
  406. testInfo.Option.Add(new CodeValue { Code = optionsKeys[i], Value = optHtml });
  407. //testInfo.Option.Add(new Dictionary<string, string> { { "code", optionsKeys[i] },{ "value", optHtml } });
  408. //testInfo.Option.TryAdd(optionsKeys[i], optHtml);
  409. }
  410. else
  411. {
  412. optRgex = optionsKeys[i] + "(\\.|\\.|\\、|\\:|\\:)([\\s\\S]*?)" + AnswerTag;
  413. optHtml = Regex.Match(optsHtml, optRgex).Value;
  414. if (!string.IsNullOrEmpty(optHtml))
  415. {
  416. optHtml = optHtml.Substring(2, optHtml.Length - 6);
  417. optHtml = HtmlHelper.DoUselessTag(optHtml);
  418. textImg.Append(HtmlHelper.DoTextImg(optHtml));
  419. testInfo.Option.Add(new CodeValue { Code = optionsKeys[i], Value = optHtml });
  420. //testInfo.Option.Add(new Dictionary<string, string> { { "code", optionsKeys[i] }, { "value", optHtml } });
  421. //testInfo.Option.TryAdd(optionsKeys[i], optHtml);
  422. }
  423. }
  424. }
  425. //处理题干
  426. testInfo.Question = testInfo.Question.Replace(optsHtml, "").Replace(SummaryTag, "").Replace(AnswerTag, "");
  427. testInfo.Question = HtmlHelper.DoUselessTag(testInfo.Question);
  428. textImg.Append(HtmlHelper.DoTextImg(testInfo.Question));
  429. testInfo.ShaCode = ShaHashHelper.GetSHA1(textImg.ToString());
  430. List<string> answers = testInfo.Answer;
  431. HashSet<string> ans = new HashSet<string>();
  432. //处理答案
  433. for (int i = 0; i < answers.Count; i++)
  434. {
  435. string Answer = answers[i].Replace(AnswerTag, "").Replace(AnalysisTag, "").TrimStart().TrimEnd();
  436. Answer.Select(s => s.ToString()).ToList().ForEach(x =>
  437. {
  438. ans.Add(x);
  439. });
  440. }
  441. testInfo.Answer = ans.ToList();
  442. //处理解析
  443. testInfo.Explain = testInfo.Explain.Replace(AnalysisTag, "").Replace(EndedTag, "");
  444. testInfo.Explain = HtmlHelper.DoUselessTag(testInfo.Explain);
  445. }
  446. return testInfos;
  447. }
  448. public static List<ExerciseDto> ConvertTestInfo(List<string> tests, string TypeKey)
  449. {
  450. List<ExerciseDto> testInfos = new List<ExerciseDto>();
  451. foreach (string html in tests)
  452. {
  453. Dictionary<string, string> regex = new Dictionary<string, string>();
  454. Dictionary<string, string> question = new Dictionary<string, string> { { "Summary", SummaryTag + "|" + AnswerTag }, { "Answer", AnswerTag + "|" + AnalysisTag }, { "Analysis", AnalysisTag + "|" + EndedTag } };
  455. Dictionary<string, string> compquestion = new Dictionary<string, string> { { "Summary", SummaryTag + "|" + AnalysisTag }, { "Analysis", AnalysisTag + "|" + EndedTag } };
  456. ExerciseDto test = new ExerciseDto();
  457. test.Type = TypeKey;
  458. List<string> keys = new List<string>();
  459. if (TypeKey.Equals("Complete"))
  460. {
  461. keys = compquestion.Keys.ToList();
  462. regex = compquestion;
  463. }
  464. else
  465. {
  466. keys = question.Keys.ToList();
  467. regex = question;
  468. }
  469. foreach (string key in keys)
  470. {
  471. string[] tags = regex[key].Split("|");
  472. string RegexStr = tags[0] + "([\\s\\S]*?)" + tags[1];
  473. Match mt = Regex.Match(html, RegexStr);
  474. switch (key)
  475. {
  476. case "Summary":
  477. test.Question = mt.Value; break;
  478. case "Answer":
  479. string Answer = mt.Value;
  480. ///单选或多选,判断答案 脱html标签
  481. if (TypeKey.Equals("Single") || TypeKey.Equals("Multiple") || TypeKey.Equals("Judge"))
  482. {
  483. HtmlDocument doc = new HtmlDocument();
  484. doc.LoadHtml(mt.Value);
  485. Answer = doc.DocumentNode.InnerText;
  486. }
  487. test.Answer = new List<string>() { Answer }; break;
  488. case "Analysis":
  489. test.Explain = mt.Value; break;
  490. default: break;
  491. }
  492. }
  493. testInfos.Add(test);
  494. }
  495. return testInfos;
  496. }
  497. public static List<string> ConvertTest(string testHtml)
  498. {
  499. string start = SummaryTag;
  500. string end = EndedTag;
  501. List<string> tests = new List<string>();
  502. while (testHtml.IndexOf(start) > 0)
  503. {
  504. int indexStart = testHtml.IndexOf(start);
  505. int indexEnd = testHtml.IndexOf(end);
  506. string test = testHtml.Substring(indexStart, indexEnd - indexStart + start.Length);
  507. tests.Add(test);
  508. testHtml = testHtml.Substring(indexEnd + end.Length);
  509. }
  510. return tests;
  511. }
  512. }
  513. class ReplaceDto
  514. {
  515. public string oldstr { get; set; }
  516. public string newstr { get; set; }
  517. }
  518. }