Prechádzať zdrojové kódy

word解析代码添加

CrazyIter 5 rokov pred
rodič
commit
9e07dce0a2

+ 12 - 0
TEAMModelOS.Service/Models/Core/CodeValue.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.Service.Models.Core
+{
+    public class CodeValue
+    {
+        public string Code { get; set; }
+        public string Value { get; set; }
+    }
+}

+ 16 - 0
TEAMModelOS.Service/Models/Core/ContentVerify.cs

@@ -0,0 +1,16 @@
+using Microsoft.Azure.Cosmos.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Azure;
+
+namespace TEAMModelOS.Service.Models.Core
+{
+    [TableSpace(Name = "Core")]
+    public class ContentVerify : TableEntity
+    {
+        public string Content { get; set; }
+        public string AlgorithmType { get; set; }
+        public string DigestCode { get; set; }
+    }
+}

+ 25 - 0
TEAMModelOS.Service/Models/Evaluation/Dtos/Own/ExerciseDto.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.Service.Models.Core;
+
+namespace TEAMModelOS.Service.Models.Evaluation.Dtos.Own
+{
+    public class ExerciseDto
+    {
+        public ExerciseDto()
+        {
+            Children = new List<ExerciseDto>();
+            Option = new List<CodeValue>();
+            Answer = new List<string>();
+        }
+        public string ShaCode { get; set; }
+        public string Question { get; set; }
+        public List<CodeValue> Option { get; set; }
+        public List<string> Answer { get; set; }
+        public string Explain { get; set; }
+        public string Type { get; set; }
+        public string PShaCode { get; set; }
+        public List<ExerciseDto> Children { get; set; }
+    }
+}

+ 360 - 0
TEAMModelOS.Service/Services/Evaluation/Implements/HtmlAnalyzeService.cs

@@ -0,0 +1,360 @@
+using DocumentFormat.OpenXml.Packaging;
+using HtmlAgilityPack;
+using Microsoft.AspNetCore.Http;
+using OpenXmlPowerTools;
+using System;
+using System.Collections.Generic;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
+using TEAMModelOS.SDK.Context.Configuration;
+using TEAMModelOS.SDK.Context.Constant;
+using TEAMModelOS.SDK.Extension.SnowFlake;
+using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
+using TEAMModelOS.SDK.Helper.Common.FileHelper;
+using TEAMModelOS.SDK.Helper.Common.StringHelper;
+using TEAMModelOS.SDK.Helper.Security.ShaHash;
+using TEAMModelOS.SDK.Module.AzureBlob.Container;
+using TEAMModelOS.SDK.Module.AzureBlob.Interfaces;
+using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
+using TEAMModelOS.Service.Models.Core;
+using TEAMModelOS.Service.Models.Evaluation.Dtos.Own;
+using TEAMModelOS.Service.Services.Evaluation.Interfaces;
+namespace TEAMModelOS.Service.Services.Evaluation.Implements
+{
+   public class HtmlAnalyzeService : IHtmlAnalyzeService
+    {
+        private static string SummaryTag = "【题文】";
+        private static string AnswerTag = "【答案】";
+        private static string AnalysisTag = "【解析】";
+        private static string EndedTag = "【结束】";
+        private static string Options = "ABCDEFGHIJ";
+        private static string CompleteStart = "【";
+        private static string CompleteEnd = "】";
+        private static string ComposeStart = "【综合题】";
+        private static string ComposeEnd = "【综合题-题干】";
+        private static string ComposeTag = "【综合题-";
+        private static Dictionary<string, string> TestType = new Dictionary<string, string> {
+            { "Single", "【单选题】|【结束】" }, { "Multiple", "【多选题】|【结束】" },
+            { "Judge", "【判断题】|【结束】" }, { "Complete", "【填空题】|【结束】" },
+            { "Subjective", "【问答题】|【结束】" } , { "Compose", "【综合题】|【完结】" }};
+        public List<ExerciseDto> AnalyzeWordAsync(string html, string Lang)
+        {
+            //去除class 以及span标签"
+            string classpattern = "class=\"([^\"]*)\"";
+            html = Regex.Replace(html, classpattern, "");
+            string pattern = "<span([^>]{0,})>";
+            html = Regex.Replace(html, pattern, "");
+            html = html.Replace("\t", " ").Replace("<span>", "").Replace("</span>", "").Replace("dir=\"ltr\"", "");
+            Dictionary<string, List<string>> TestInType = ConvertTest(html);
+            List<ExerciseDto> tests = new List<ExerciseDto>();
+            foreach (string key in TestInType.Keys)
+            {
+                switch (key)
+                {
+                    case "Single":
+                        List<ExerciseDto> exercisesSingle = SingleConvert(key, TestInType[key]);
+                        exercisesSingle.ForEach(x => { x.PShaCode = x.ShaCode; });
+                        tests.AddRange(exercisesSingle); break;
+                    case "Multiple":
+                        List<ExerciseDto> exercisesMultiple = MultipleConvert(key, TestInType[key]);
+                        exercisesMultiple.ForEach(x => { x.PShaCode = x.ShaCode; });
+                        tests.AddRange(exercisesMultiple); break;
+                    case "Judge":
+                        List<ExerciseDto> exercisesJudge = JudgeConvert(key, TestInType[key]);
+                        exercisesJudge.ForEach(x => { x.PShaCode = x.ShaCode; });
+                        tests.AddRange(exercisesJudge); break;
+                    case "Complete":
+                        List<ExerciseDto> exercisesComplete = CompleteConvert(key, TestInType[key]);
+                        exercisesComplete.ForEach(x => { x.PShaCode = x.ShaCode; });
+                        tests.AddRange(exercisesComplete); break;
+                    case "Subjective":
+                        List<ExerciseDto> exercisesSubjective = SubjectiveConvert(key, TestInType[key]);
+                        exercisesSubjective.ForEach(x => { x.PShaCode = x.ShaCode; });
+                        tests.AddRange(exercisesSubjective); break;
+                    case "Compose":
+                        List<ExerciseDto> exercisesCompose = ComposeConvert(key, TestInType[key], Lang);
+                        exercisesCompose.ForEach(x => { x.PShaCode = x.ShaCode; });
+                        tests.AddRange(exercisesCompose);
+                        break;
+                    default: break;
+                }
+            }
+            return tests;
+        }
+
+        private List<ExerciseDto> SingleConvert(string TypeKey, List<string> list)
+        {
+            List<ExerciseDto> testInfos = OptionProcess(TypeKey, list);
+            return testInfos;
+        }
+
+        private List<ExerciseDto> MultipleConvert(string TypeKey, List<string> list)
+        {
+            List<ExerciseDto> testInfos = OptionProcess(TypeKey, list);
+            return testInfos;
+        }
+
+        private List<ExerciseDto> JudgeConvert(string TypeKey, List<string> list)
+        {
+            List<ExerciseDto> testInfos = OptionProcess(TypeKey, list);
+            return testInfos;
+        }
+
+
+        private List<ExerciseDto> CompleteConvert(string TypeKey, List<string> list)
+        {
+            List<ExerciseDto> testInfos = CompleteProcess(TypeKey, list);
+            return testInfos;
+        }
+        private List<ExerciseDto> CompleteProcess(string TypeKey, List<string> tests)
+        {
+            //List<string> tests = ConvertTest(testHtml);
+            List<ExerciseDto> testInfos = ConvertTestInfo(tests, TypeKey);
+            HtmlDocument doc = new HtmlDocument();
+            foreach (ExerciseDto testInfo in testInfos)
+            {
+                List<string> ans = new List<string>();
+                testInfo.Question = testInfo.Question.Replace(AnalysisTag, "").Replace(SummaryTag, "").Replace(AnswerTag, "");
+                string regRex = CompleteStart + "([\\s\\S]*?)" + CompleteEnd;
+                List<ReplaceDto> replaces = new List<ReplaceDto>();
+                var m = Regex.Match(testInfo.Question, regRex);
+                int index = 1;
+                while (m.Success)
+                {
+                    string an = m.Groups[1].ToString();
+                    doc.LoadHtml(an);
+                    string anstr = doc.DocumentNode.InnerText;
+                    string nbsp = "";
+                    int length = System.Text.Encoding.Default.GetBytes(anstr).Length;
+                    for (int i = 0; i < length * 3; i++)
+                    {
+                        nbsp += "&nbsp;";
+                    }
+                    ReplaceDto replaceDto = new ReplaceDto { oldstr = CompleteStart + an + CompleteEnd, newstr = "<underline data=\"" + index + "\"><u>" + nbsp + "</u></underline>" };
+                    replaces.Add(replaceDto);
+                    ans.Add(an);
+                    m = m.NextMatch();
+                    index++;
+                }
+                string textImg = testInfo.Question;
+                //消除答案
+                foreach (ReplaceDto replace in replaces)
+                {
+                    testInfo.Question = testInfo.Question.Replace(replace.oldstr, replace.newstr);
+                    testInfo.Question = HtmlHelper.DoUselessTag(testInfo.Question);
+                    //只要题干文字和图片 
+                    //不加underline标记
+                    textImg = testInfo.Question.Replace(replace.oldstr, "");
+
+                }
+                textImg = HtmlHelper.DoTextImg(textImg);
+                testInfo.ShaCode = ShaHashHelper.GetSHA1(textImg);
+                //处理解析
+                testInfo.Explain = testInfo.Explain.Replace(AnalysisTag, "").Replace(EndedTag, "");
+                testInfo.Explain = HtmlHelper.DoUselessTag(testInfo.Explain);
+                testInfo.Answer.AddRange(ans);
+            }
+            return testInfos;
+        }
+
+        private List<ExerciseDto> OptionProcess(string typeKey, List<string> list)
+        {
+            string[] optionsKeys = Options.Select(s => s.ToString()).ToArray();
+            List<ExerciseDto> testInfos = ConvertTestInfo(list, typeKey);
+            foreach (ExerciseDto testInfo in testInfos)
+            {
+                string optsRgex = optionsKeys[0] + "(\\.|\\.|\\、|\\:|\\:)([\\s\\S]*?)" + AnswerTag;
+                string optsHtml = Regex.Match(testInfo.Question, optsRgex).Value;
+                //HtmlDocument doc = new HtmlDocument();
+                //doc.LoadHtml(optsHtml);
+                //optsHtml = doc.DocumentNode.InnerText;
+                //处理选项
+                StringBuilder textImg = new StringBuilder();
+                for (int i = 0; i < optionsKeys.Length - 1; i++)
+                {
+                    string optRgex = optionsKeys[i] + "(\\.|\\.|\\、|\\:|\\:)([\\s\\S]*?)" + optionsKeys[i + 1] + "(\\.|\\.|\\、|\\:|\\:)";
+                    string optHtml = Regex.Match(optsHtml, optRgex).Value;
+                    if (!string.IsNullOrEmpty(optHtml))
+                    {
+                        optHtml = optHtml.Substring(2, optHtml.Length - 4);
+                        optHtml = HtmlHelper.DoUselessTag(optHtml);
+                        textImg.Append(HtmlHelper.DoTextImg(optHtml));
+                        testInfo.Option.Add(new CodeValue { Code = optionsKeys[i], Value = optHtml });
+                        //testInfo.Option.Add(new Dictionary<string, string> { { "code", optionsKeys[i] },{ "value", optHtml } });
+                        //testInfo.Option.TryAdd(optionsKeys[i], optHtml);
+                    }
+                    else
+                    {
+                        optRgex = optionsKeys[i] + "(\\.|\\.|\\、|\\:|\\:)([\\s\\S]*?)" + AnswerTag;
+                        optHtml = Regex.Match(optsHtml, optRgex).Value;
+                        if (!string.IsNullOrEmpty(optHtml))
+                        {
+                            optHtml = optHtml.Substring(2, optHtml.Length - 6);
+                            optHtml = HtmlHelper.DoUselessTag(optHtml);
+                            textImg.Append(HtmlHelper.DoTextImg(optHtml));
+                            testInfo.Option.Add(new CodeValue { Code = optionsKeys[i], Value = optHtml });
+                            //testInfo.Option.Add(new Dictionary<string, string> { { "code", optionsKeys[i] }, { "value", optHtml } });
+                            //testInfo.Option.TryAdd(optionsKeys[i], optHtml);
+                        }
+                    }
+                }
+                //处理题干
+                testInfo.Question = testInfo.Question.Replace(optsHtml, "").Replace(SummaryTag, "").Replace(AnswerTag, "");
+                testInfo.Question = HtmlHelper.DoUselessTag(testInfo.Question);
+                textImg.Append(HtmlHelper.DoTextImg(testInfo.Question));
+                testInfo.ShaCode = ShaHashHelper.GetSHA1(textImg.ToString());
+                List<string> answers = testInfo.Answer;
+                HashSet<string> ans = new HashSet<string>();
+                //处理答案
+                for (int i = 0; i < answers.Count; i++)
+                {
+                    string Answer = answers[i].Replace(AnswerTag, "").Replace(AnalysisTag, "").TrimStart().TrimEnd();
+                    Answer.Select(s => s.ToString()).ToList().ForEach(x =>
+                    {
+                        ans.Add(x);
+                    });
+                }
+                testInfo.Answer = ans.ToList();
+                //处理解析
+                testInfo.Explain = testInfo.Explain.Replace(AnalysisTag, "").Replace(EndedTag, "");
+                testInfo.Explain = HtmlHelper.DoUselessTag(testInfo.Explain);
+            }
+            return testInfos;
+        }
+
+
+        private List<ExerciseDto> SubjectiveConvert(string TypeKey, List<string> tests)
+        {
+            // List<string> tests = ConvertTest(testHtml);
+            List<ExerciseDto> testInfos = ConvertTestInfo(tests, TypeKey);
+
+            foreach (ExerciseDto testInfo in testInfos)
+            {
+                testInfo.Question = testInfo.Question.Replace(AnalysisTag, "").Replace(SummaryTag, "").Replace(AnswerTag, "");
+                testInfo.Question = HtmlHelper.DoUselessTag(testInfo.Question);
+                StringBuilder textImg = new StringBuilder(HtmlHelper.DoTextImg(testInfo.Question));
+                testInfo.ShaCode = ShaHashHelper.GetSHA1(textImg.ToString());
+                for (int i = 0; i < testInfo.Answer.Count; i++)
+                {
+                    testInfo.Answer[i] = testInfo.Answer[i].Replace(AnswerTag, "").Replace(AnalysisTag, "");
+                    testInfo.Answer[i] = HtmlHelper.DoUselessTag(testInfo.Answer[i]);
+                }
+                testInfo.Explain = testInfo.Explain.Replace(AnalysisTag, "").Replace(EndedTag, "");
+                testInfo.Explain = HtmlHelper.DoUselessTag(testInfo.Explain);
+            }
+            return testInfos;
+        }
+
+        private List<ExerciseDto> ComposeConvert(string TypeKey, List<string> list, string Lang)
+        {
+            List<ExerciseDto> exerciseDtos = new List<ExerciseDto>();
+            foreach (string html in list)
+            {
+                ExerciseDto exercise = new ExerciseDto() { Type = TypeKey };
+                string RegexStr = ComposeStart + "([\\s\\S]*?)" + ComposeEnd;
+                Match mt = Regex.Match(html, RegexStr);
+                exercise.Question = HtmlHelper.DoUselessTag(mt.Value.Replace(ComposeStart, "").Replace(ComposeEnd, ""));
+                string testinfo = Regex.Replace(html, RegexStr, "").Replace(ComposeTag, CompleteStart);
+                //获取综合题的材料加每个小题的sha1Code
+                string testQs = HtmlHelper.DoTextImg(exercise.Question);
+                List<ExerciseDto> dtos = AnalyzeWordAsync(testinfo, Lang);
+                if (dtos.IsNotEmpty())
+                {
+                    dtos.ForEach(x => { testQs = testQs + x.ShaCode; });
+                    exercise.ShaCode = ShaHashHelper.GetSHA1(testQs);
+                    dtos.ForEach(x => { x.PShaCode = exercise.ShaCode; });
+                    exercise.Children.AddRange(dtos);
+                }
+                exerciseDtos.Add(exercise);
+            }
+            return exerciseDtos;
+        }
+        public static List<ExerciseDto> ConvertTestInfo(List<string> tests, string TypeKey)
+        {
+            List<ExerciseDto> testInfos = new List<ExerciseDto>();
+            foreach (string html in tests)
+            {
+                Dictionary<string, string> regex = new Dictionary<string, string>();
+                Dictionary<string, string> question = new Dictionary<string, string> { { "Summary", TestType[TypeKey].Split("|")[0] + "|" + AnswerTag }, { "Answer", AnswerTag + "|" + AnalysisTag }, { "Analysis", AnalysisTag + "|" + EndedTag } };
+                Dictionary<string, string> compquestion = new Dictionary<string, string> { { "Summary", TestType[TypeKey].Split("|")[0] + "|" + AnalysisTag }, { "Analysis", AnalysisTag + "|" + EndedTag } };
+                ExerciseDto test = new ExerciseDto();
+                test.Type = TypeKey;
+                List<string> keys = new List<string>();
+                if (TypeKey.Equals("Complete"))
+                {
+                    keys = compquestion.Keys.ToList();
+                    regex = compquestion;
+                }
+                else
+                {
+                    keys = question.Keys.ToList();
+                    regex = question;
+                }
+                foreach (string key in keys)
+                {
+                    string[] tags = regex[key].Split("|");
+                    string RegexStr = tags[0] + "([\\s\\S]*?)" + tags[1];
+                    Match mt = Regex.Match(html, RegexStr);
+                    switch (key)
+                    {
+                        case "Summary":
+                            test.Question = mt.Value.Replace(TestType[TypeKey].Split("|")[0], ""); break;
+                        case "Answer":
+                            string Answer = mt.Value;
+                            ///单选或多选,判断答案 脱html标签
+                            if (TypeKey.Equals("Single") || TypeKey.Equals("Multiple") || TypeKey.Equals("Judge"))
+                            {
+                                HtmlDocument doc = new HtmlDocument();
+                                doc.LoadHtml(mt.Value);
+                                Answer = doc.DocumentNode.InnerText;
+                            }
+                            test.Answer = new List<string>() { Answer }; break;
+                        case "Analysis":
+                            test.Explain = mt.Value; break;
+                        default: break;
+                    }
+                }
+                testInfos.Add(test);
+            }
+            return testInfos;
+        }
+        /// <summary>
+        /// 解析题型
+        /// </summary>
+        /// <param name="testHtml"></param>
+        /// <returns></returns>
+        public static Dictionary<string, List<string>> ConvertTest(string testHtml)
+        {
+            string start = SummaryTag;
+            string end = EndedTag;
+            Dictionary<string, List<string>> TestInType = new Dictionary<string, List<string>>();
+            foreach (string key in TestType.Keys)
+            {
+                string[] tags = TestType[key].Split("|");
+                string regRex = tags[0] + "([\\s\\S]*?)" + tags[1];
+                var m = Regex.Match(testHtml, regRex);
+                //int index = 1;
+                List<string> tests = new List<string>();
+                while (m.Success)
+                {
+                    string testInfo = tags[0] + m.Groups[1].ToString() + tags[1];
+                    tests.Add(testInfo);
+                    m = m.NextMatch();
+                }
+                TestInType.Add(key, tests);
+            }
+            return TestInType;
+        }
+    }
+    class ReplaceDto
+    {
+        public string oldstr { get; set; }
+        public string newstr { get; set; }
+    }
+}

+ 200 - 0
TEAMModelOS.Service/Services/Evaluation/Implements/ImportExerciseService.cs

@@ -0,0 +1,200 @@
+using DocumentFormat.OpenXml.Packaging;
+using HtmlAgilityPack;
+using Microsoft.AspNetCore.Http;
+using OpenXmlPowerTools;
+using System;
+using System.Collections.Generic;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
+using TEAMModelOS.SDK.Context.Configuration;
+using TEAMModelOS.SDK.Context.Constant;
+using TEAMModelOS.SDK.Extension.SnowFlake;
+using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
+using TEAMModelOS.SDK.Helper.Common.FileHelper;
+using TEAMModelOS.SDK.Helper.Common.StringHelper;
+using TEAMModelOS.SDK.Helper.Security.ShaHash;
+using TEAMModelOS.SDK.Module.AzureBlob.Container;
+using TEAMModelOS.SDK.Module.AzureBlob.Interfaces;
+using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
+using TEAMModelOS.Service.Models.Core;
+using TEAMModelOS.Service.Models.Evaluation.Dtos.Own;
+using TEAMModelOS.Service.Services.Evaluation.Interfaces;
+
+namespace TEAMModelOS.Service.Services.Evaluation.Implements
+{
+    public class ImportExerciseService : IImportExerciseService
+    {
+        private static string SummaryTag = "【题文】";
+        private static string AnswerTag = "【答案】";
+        private static string AnalysisTag = "【解析】";
+        private static string EndedTag = "【结束】";
+        private static string Options = "ABCDEFGHIJ";
+        private static string CompleteStart = "【";
+        private static string CompleteEnd = "】";
+        Dictionary<string, string> TestType = new Dictionary<string, string> {
+            { "Single", "单选题|多选题" }, { "Multiple", "多选题|判断题" },
+            { "Judge", "判断题|填空题" }, { "Complete", "填空题|主观题" },
+            { "Subjective", "主观题|【完结】" } };
+        private readonly IAzureBlobDBRepository azureBlobDBRepository;
+        private readonly IAzureTableDBRepository azureTableDBRepository;
+        public ImportExerciseService(IAzureBlobDBRepository _azureBlobDBRepository, IAzureTableDBRepository _azureTableDBRepository)
+        {
+            azureBlobDBRepository = _azureBlobDBRepository;
+            azureTableDBRepository = _azureTableDBRepository;
+        }
+        public async Task<Dictionary<string, object>> UploadWord(IFormFile file)
+        {
+
+            Dictionary<string, object> resdict = new Dictionary<string, object>();
+            string shaCode = ShaHashHelper.GetSHA1(file.OpenReadStream());
+            long length = file.Length;
+            Dictionary<string, object> dict = new Dictionary<string, object> { { "Sha1Code", shaCode } };
+            List<AzureBlobModel> models = await azureTableDBRepository.FindListByDict<AzureBlobModel>(dict);
+
+            //if (models.IsNotEmpty())
+            //{
+            //    resdict.Add("HtmlString", HttpHelper.HttpGet(models[0].BlobUrl));
+            //    resdict.Add("Sha1Code", models[0].Sha1Code);
+            //    return resdict;
+            //}
+
+            string folder = BaseConfigModel.ContentRootPath + "/Upload/" + IdWorker.getInstance().NextId();
+            System.IO.Directory.CreateDirectory(folder);
+            var filePath = folder + "\\" + file.FileName;
+            using (var stream = new FileStream(filePath, FileMode.Create))
+            {
+                await file.CopyToAsync(stream);
+            }
+            var htmlInfo = ConvertDocxToHtml(filePath, folder);
+            AzureBlobModel model = await azureBlobDBRepository.UploadPath(htmlInfo.blobPath);
+            model.Sha1Code = shaCode;
+            await azureTableDBRepository.Save<AzureBlobModel>(model);
+            FileHelper.DeleteDirAndFiles(BaseConfigModel.ContentRootPath + "/Upload");
+            resdict.Add("HtmlString", htmlInfo.htmlString);
+            resdict.Add("Sha1Code", shaCode);
+            return resdict;
+        }
+        public dynamic ConvertDocxToHtml(string filePath, string folder)
+        {
+            string FolderName = DateTime.Now.ToString("yyyyMMdd");
+            byte[] byteArray = File.ReadAllBytes(filePath);
+
+            //byte[] bytes = new byte[stream.Length];
+            using (MemoryStream memoryStream = new MemoryStream())
+            {
+                memoryStream.Write(byteArray, 0, byteArray.Length);
+                using (WordprocessingDocument doc = WordprocessingDocument.Open(memoryStream, true))
+                {
+                    int imageCounter = 0;
+                    WmlToHtmlConverterSettings settings = new WmlToHtmlConverterSettings()
+                    {
+                        PageTitle = "",
+                        AdditionalCss = "body { margin: 1cm auto; max-width: 20cm; padding: 0; }",
+
+                        FabricateCssClasses = true,
+                        CssClassPrefix = "pt-",
+                        RestrictToSupportedLanguages = false,
+                        RestrictToSupportedNumberingFormats = false,
+                        ImageHandler = imageInfo =>
+                        {
+                            ++imageCounter;
+                            string extension = imageInfo.ContentType.Split('/')[1].ToLower();
+                            ImageFormat imageFormat = null;
+                            if (extension.Equals("png")) imageFormat = ImageFormat.Png;
+                            else if (extension.Equals("gif")) imageFormat = ImageFormat.Gif;
+                            else if (extension.Equals("bmp")) imageFormat = ImageFormat.Bmp;
+                            else if (extension.Equals("jpeg")) imageFormat = ImageFormat.Jpeg;
+                            else if (extension.Equals("tiff"))
+                            {
+                                extension = "gif";
+                                imageFormat = ImageFormat.Gif;
+                            }
+                            else if (extension.Equals("x-wmf"))
+                            {
+                                extension = "wmf";
+                                imageFormat = ImageFormat.Wmf;
+                            }
+
+                            if (imageFormat == null) return null;
+                            string base64 = null;
+                            string mimeType = null;
+                            string shaCode = null;
+                            try
+                            {
+                                if (extension.Equals("wmf"))
+                                {
+                                    var buffer = Encoding.Default.GetBytes(imageInfo.Mathxml);
+                                    base64 = System.Convert.ToBase64String(buffer);
+                                    mimeType = "image/svg+xml";
+                                    shaCode = ShaHashHelper.GetSHA1(new MemoryStream(buffer));
+                                }
+                                else
+                                {
+                                    ImageFormat format = imageInfo.Bitmap.RawFormat;
+                                    ImageCodecInfo codec = ImageCodecInfo.GetImageDecoders()
+                                                                .First(c => c.FormatID == format.Guid);
+                                    mimeType = codec.MimeType;
+                                    using (MemoryStream ms = new MemoryStream())
+                                    {
+
+                                        imageInfo.Bitmap.Save(ms, imageFormat);
+                                        var ba = ms.ToArray();
+                                        base64 = System.Convert.ToBase64String(ba);
+                                        shaCode = ShaHashHelper.GetSHA1(ms);
+                                    }
+                                }
+                            }
+                            catch (System.Runtime.InteropServices.ExternalException)
+                            { return null; }
+
+                            string imageSource =
+                                    string.Format("data:{0};base64,{1}", mimeType, base64);
+                            #region 处理图片存到Bolb
+                            string[] strs = imageSource.Split(',');
+                            string fileExt = StringHelper.SubMidString(strs[0], ":", ";");
+                            if (ContentTypeDict.extdict.TryGetValue(fileExt, out string ext))
+                            {
+                                fileExt = ext;
+                            }
+                            else
+                            {
+                                //解决多种扩展名不能获取的
+                                string[] sp = StringHelper.SubMidString(strs[0], "/", ";").Split("-");
+                                fileExt = sp[sp.Length - 1];
+                                sp = fileExt.Split("+");
+                                fileExt = "." + sp[sp.Length - 1];
+                            }
+                            Stream stream = new MemoryStream(Convert.FromBase64String(strs[1]));
+                            // long bizno = IdWorker.getInstance().NextId();
+                            string filename = shaCode + fileExt;
+                            AzureBlobModel model = azureBlobDBRepository.UploadFileByFolderNAsyn(stream, FolderName, filename, "exercise", false);
+                            #endregion
+                            XElement img = new XElement(Xhtml.img,
+                                    new XAttribute(NoNamespace.src, model.BlobUrl),
+                                    imageInfo.ImgStyleAttribute,
+                                    imageInfo.AltText != null ?
+                                        new XAttribute(NoNamespace.alt, imageInfo.AltText) : null);
+                            stream.Close();
+                            return img;
+                        }
+                    };
+                    // XElement html = HtmlConverter.ConvertToHtml(doc, settings);
+                    // File.WriteAllText(@"E:\document\kk.html", html.ToStringNewLineOnAttributes());
+                    XElement htmlElement = WmlToHtmlConverter.ConvertToHtml(doc, settings);
+                    var htmls = new XDocument(new XDocumentType("html", null, null, null), htmlElement);
+                    var htmlString = htmls.ToString(SaveOptions.DisableFormatting);
+                    //引入MathJax插件
+                    htmlString = htmlString + "<script type=\"text/javascript\" src=\"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"></script>";
+                    File.WriteAllText(folder + "/" + "index.html", htmlString);
+                    return new { htmlString, blobPath = folder + "/" + "index.html" };
+                };
+            }
+        }
+    }
+}

+ 13 - 0
TEAMModelOS.Service/Services/Evaluation/Interfaces/IHtmlAnalyzeService.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Configuration;
+using TEAMModelOS.Service.Models.Evaluation.Dtos.Own;
+
+namespace TEAMModelOS.Service.Services.Evaluation.Interfaces
+{
+    public interface IHtmlAnalyzeService: IBusinessService
+    {
+        List<ExerciseDto> AnalyzeWordAsync(string htmlString, string Lang);
+    }
+}

+ 19 - 0
TEAMModelOS.Service/Services/Evaluation/Interfaces/IImportExerciseService.cs

@@ -0,0 +1,19 @@
+using Microsoft.AspNetCore.Http;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
+using TEAMModelOS.SDK.Context.Configuration;
+using TEAMModelOS.Service.Models.Evaluation.Dtos.Own;
+
+namespace TEAMModelOS.Service.Services.Evaluation.Interfaces
+{
+    public interface IImportExerciseService: IBusinessService
+    {
+      
+
+        Task<Dictionary<string, object>> UploadWord(IFormFile file);
+
+    }
+}

+ 0 - 16
TEAMModelOS.sln

@@ -13,10 +13,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TEAMModelOS.Grpc", "TEAMMod
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{53913D96-CC85-4698-9241-84761C58EAC3}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TEAMModelOS.JsonRPC", "TEAMModelOS.JsonRPC\TEAMModelOS.JsonRPC.csproj", "{62889C98-D423-4F80-AB07-0BB3F842CF8D}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TEAMModelOS.JsonRPC3", "TEAMModelOS.JsonRPC3\TEAMModelOS.JsonRPC3.csproj", "{100F1A4F-84AE-4282-8E52-D009AAE914EB}"
-EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -39,22 +35,10 @@ Global
 		{75C46F80-6FDB-4589-A045-1C10F3FCD225}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{75C46F80-6FDB-4589-A045-1C10F3FCD225}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{75C46F80-6FDB-4589-A045-1C10F3FCD225}.Release|Any CPU.Build.0 = Release|Any CPU
-		{62889C98-D423-4F80-AB07-0BB3F842CF8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{62889C98-D423-4F80-AB07-0BB3F842CF8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{62889C98-D423-4F80-AB07-0BB3F842CF8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{62889C98-D423-4F80-AB07-0BB3F842CF8D}.Release|Any CPU.Build.0 = Release|Any CPU
-		{100F1A4F-84AE-4282-8E52-D009AAE914EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{100F1A4F-84AE-4282-8E52-D009AAE914EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{100F1A4F-84AE-4282-8E52-D009AAE914EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{100F1A4F-84AE-4282-8E52-D009AAE914EB}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
-	GlobalSection(NestedProjects) = preSolution
-		{62889C98-D423-4F80-AB07-0BB3F842CF8D} = {53913D96-CC85-4698-9241-84761C58EAC3}
-		{100F1A4F-84AE-4282-8E52-D009AAE914EB} = {53913D96-CC85-4698-9241-84761C58EAC3}
-	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {76440725-5E50-4288-851F-BA5C0BC8E8C6}
 	EndGlobalSection

+ 70 - 0
TEAMModelOS/Controllers/Evaluation/ImportExerciseController.cs

@@ -0,0 +1,70 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.Context.Constant.Common;
+using TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest;
+using TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse;
+using TEAMModelOS.Service.Models.Evaluation.Dtos.Own;
+using TEAMModelOS.Service.Services.Evaluation.Implements;
+using TEAMModelOS.Service.Services.Evaluation.Interfaces;
+
+namespace TEAMModelOS.Controllers.Evaluation
+{
+    [Route("api/[controller]")]
+    [ApiController]
+    public class ImportExerciseController: BaseController
+    {
+        private readonly IImportExerciseService importExerciseService;
+        private readonly IHtmlAnalyzeService htmlAnalyzeService;
+        public ImportExerciseController(IImportExerciseService _importExerciseService, IHtmlAnalyzeService _htmlAnalyzeService )
+        {
+            importExerciseService = _importExerciseService;
+            htmlAnalyzeService = _htmlAnalyzeService;
+        }
+
+        /// <summary>
+        /// docUrl
+        /// folder
+        /// shaCode
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("uploadWord")]
+        [RequestSizeLimit(102_400_000_00)] //最大10000m左右
+        public async Task<BaseJosnRPCResponse> UploadWord([FromForm] IFormFile file)
+        {
+            JsonRPCResponseBuilder responseBuilder = new JsonRPCResponseBuilder();
+            if (!FileType.GetExtention(file.FileName).ToLower().Equals("docx"))
+            {
+                return responseBuilder.Error("type is not docx").build();
+            }
+           Dictionary<string, object> model = await importExerciseService.UploadWord(file);
+
+            return responseBuilder.Data(model).build();
+        }
+
+        /// <summary>
+        /// htmlString 
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("AnalyzeHtml")]
+        public BaseJosnRPCResponse AnalyzeHtml(JosnRPCRequest<Dictionary<string, object>> request)
+        {
+            JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
+            bool flag = request.@params.TryGetValue("htmlString", out object htmlString);
+            if (flag && htmlString != null && !string.IsNullOrEmpty(htmlString.ToString()))
+            {
+                List<ExerciseDto> exercises = htmlAnalyzeService.AnalyzeWordAsync(htmlString.ToString(), request.lang);
+                return builder.Data(exercises).build();
+            }
+            else
+            {
+                return builder.Data(null).build();
+            }
+        }
+    }
+}

+ 0 - 1
TEAMModelOS/TEAMModelOS.csproj

@@ -24,7 +24,6 @@
   </ItemGroup>
 
   <ItemGroup>
-    <Folder Include="Controllers\Evaluation\" />
     <Folder Include="JsonFile\Subject\" />
     <Folder Include="wwwroot\" />
   </ItemGroup>