zhouj1203@hotmail.com 1 년 전
부모
커밋
c18d61d9bb

+ 56 - 0
TEAMModelOS.SDK/Models/Cosmos/School/MoofenExam.cs

@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TEAMModelOS.SDK.Models.Cosmos.School
+{
+    public class MoofenExam :CosmosEntity
+    {
+        public MoofenExam() {
+            pk = "MfExam";
+        }
+        public long examDate { get; set; }
+        public string examName { get; set;}
+        //学期
+        public string semester { get; set;}
+        public int grade { get;set;}
+        //学段类型 primary junior senior
+        public string periodType { get; set;}
+        public List<SubjectData> datas { get; set; } = new();
+
+    }
+    public class SubjectData
+    { 
+    
+        public string subjectName { get; set; }
+        public double totalScore { get; set; }
+        public List<PaperInfo> paperInfos { get; set; } = new();
+    }
+    public class PaperInfo
+    {
+        public string questionNo { get; set; }
+        public string type { get; set; }
+        public double score { get; set; }
+
+        public int difficulty { get; set; }
+        public string choices { get; set; }
+        public string answer { get; set; }
+    }
+    public class StuAnswer : CosmosEntity
+    {
+        public StuAnswer() {
+            pk = "Answer";
+        }
+        public string subject { get; set; }
+        public string stuNo { get; set; }
+        public string examId { get; set; }
+        public List<Ans> ans { get; set; } = new();
+    }
+    public class Ans { 
+        public string questionNo { get; set; }
+        public double score { get; set; }
+        public string answer { get; set; }
+    }
+}

+ 283 - 26
TEAMModelOS.SDK/Models/Service/Third/ThirdService.cs

@@ -1,8 +1,16 @@
 using Azure.Cosmos;
 using Azure.Cosmos;
+using Azure.Storage.Blobs.Models;
+using DocumentFormat.OpenXml.Drawing.Charts;
+using DocumentFormat.OpenXml.Office2010.Excel;
 using HTEXLib.COMM.Helpers;
 using HTEXLib.COMM.Helpers;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
+using Microsoft.OData.Edm;
+using Newtonsoft.Json;
+using OpenXmlPowerTools;
+using OpenXmlPowerTools.HtmlToWml.CSS;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Net.Http;
 using System.Net.Http;
 using System.Text;
 using System.Text;
@@ -11,6 +19,8 @@ using System.Threading.Tasks;
 using TEAMModelOS.Models;
 using TEAMModelOS.Models;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models.Cosmos;
+using TEAMModelOS.SDK.Models.Cosmos.Student;
 using static TEAMModelOS.SDK.Models.Teacher;
 using static TEAMModelOS.SDK.Models.Teacher;
 
 
 namespace TEAMModelOS.SDK.Models
 namespace TEAMModelOS.SDK.Models
@@ -56,14 +66,15 @@ namespace TEAMModelOS.SDK.Models
                                         SchoolTeacher schoolTeacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<SchoolTeacher>(teacher.id, new PartitionKey($"Teacher-{school.id}"));
                                         SchoolTeacher schoolTeacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<SchoolTeacher>(teacher.id, new PartitionKey($"Teacher-{school.id}"));
                                         if (schoolTeacher != null)
                                         if (schoolTeacher != null)
                                         {
                                         {
-                                            if (!schoolTeacher.roles.IsEmpty() )
+                                            if (!schoolTeacher.roles.IsEmpty())
                                             {
                                             {
                                                 if (!schoolTeacher.roles.Contains("teacher"))
                                                 if (!schoolTeacher.roles.Contains("teacher"))
                                                 {
                                                 {
                                                     schoolTeacher.roles.Add("teacher");
                                                     schoolTeacher.roles.Add("teacher");
                                                 }
                                                 }
                                             }
                                             }
-                                            else {
+                                            else
+                                            {
                                                 schoolTeacher.roles = new List<string> { "teacher" };
                                                 schoolTeacher.roles = new List<string> { "teacher" };
                                             }
                                             }
                                             schoolTeacher.status = "join";
                                             schoolTeacher.status = "join";
@@ -91,7 +102,7 @@ namespace TEAMModelOS.SDK.Models
                                             createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                                             createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                                             ttl = -1
                                             ttl = -1
                                         };
                                         };
-                                        await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(schoolTeacher,new PartitionKey(schoolTeacher.code));
+                                        await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(schoolTeacher, new PartitionKey(schoolTeacher.code));
                                     }
                                     }
                                 }
                                 }
                             }
                             }
@@ -131,7 +142,7 @@ namespace TEAMModelOS.SDK.Models
                                 {
                                 {
                                     if (scBind.pid.Equals("1249"))
                                     if (scBind.pid.Equals("1249"))
                                     {
                                     {
-                                        groupName =$"第三批教师培训组";
+                                        groupName = $"第三批教师培训组";
                                     }
                                     }
                                     nickname = scTeachers[0].TeacherName;
                                     nickname = scTeachers[0].TeacherName;
                                     if (!string.IsNullOrEmpty(groupName))
                                     if (!string.IsNullOrEmpty(groupName))
@@ -150,14 +161,14 @@ namespace TEAMModelOS.SDK.Models
                                 //不在研修名单
                                 //不在研修名单
                                 if (meber == null || !meber.Any())
                                 if (meber == null || !meber.Any())
                                 {
                                 {
-                                    yxtrain[0].members.Add(new Member { id = teacher.id, type = 1, groupId = groupId, groupName = groupName,nickname= nickname });
-                                    await GroupListService.UpsertList(yxtrain[0], _azureCosmos, _configuration, _serviceBus,"web");
+                                    yxtrain[0].members.Add(new Member { id = teacher.id, type = 1, groupId = groupId, groupName = groupName, nickname = nickname });
+                                    await GroupListService.UpsertList(yxtrain[0], _azureCosmos, _configuration, _serviceBus, "web");
                                 }
                                 }
                                 else
                                 else
                                 {
                                 {
                                     if (string.IsNullOrEmpty(meber.First().groupId) || string.IsNullOrEmpty(meber.First().groupName))
                                     if (string.IsNullOrEmpty(meber.First().groupId) || string.IsNullOrEmpty(meber.First().groupName))
                                     {
                                     {
-                                        meber.ToList().ForEach(x => { x.groupId = groupId; x.groupName = groupName;x.nickname = string.IsNullOrWhiteSpace(x.nickname)? nickname:x.nickname; });
+                                        meber.ToList().ForEach(x => { x.groupId = groupId; x.groupName = groupName; x.nickname = string.IsNullOrWhiteSpace(x.nickname) ? nickname : x.nickname; });
                                         await GroupListService.UpsertList(yxtrain[0], _azureCosmos, _configuration, _serviceBus, "web");
                                         await GroupListService.UpsertList(yxtrain[0], _azureCosmos, _configuration, _serviceBus, "web");
                                     }
                                     }
                                 }
                                 }
@@ -233,7 +244,7 @@ namespace TEAMModelOS.SDK.Models
                 return (setting.accessConfig, area, setting);
                 return (setting.accessConfig, area, setting);
             }
             }
         }
         }
-        public static async Task<List<Ability>> GetDiagnosisList(CosmosClient client, string standard, DingDing _dingDing, AreaSetting setting, HttpClient  _httpClient , Teacher teacher, TEAMModelOS.Models.Option _option, AzureStorageFactory _azureStorage)
+        public static async Task<List<Ability>> GetDiagnosisList(CosmosClient client, string standard, DingDing _dingDing, AreaSetting setting, HttpClient _httpClient, Teacher teacher, TEAMModelOS.Models.Option _option, AzureStorageFactory _azureStorage)
         {
         {
             List<string> abilityNos = new();
             List<string> abilityNos = new();
             var table = _azureStorage.GetCloudTableClient().GetTableReference("ScYxpt");
             var table = _azureStorage.GetCloudTableClient().GetTableReference("ScYxpt");
@@ -269,7 +280,7 @@ namespace TEAMModelOS.SDK.Models
                         dict = new Dictionary<string, object>() { { "accessConfig", setting.accessConfig }, { "pxid", pxid }, { "areaId", setting.id } };
                         dict = new Dictionary<string, object>() { { "accessConfig", setting.accessConfig }, { "pxid", pxid }, { "areaId", setting.id } };
                     }
                     }
 
 
-                    (int status, string json) = await ScsStudyApisService.GetDiagnosisListByProject_V2(_httpClient, _dingDing, _azureStorage, setting.id ,setting.accessConfig,pxid, teachers[0].schoolCode);
+                    (int status, string json) = await ScsStudyApisService.GetDiagnosisListByProject_V2(_httpClient, _dingDing, _azureStorage, setting.id, setting.accessConfig, pxid, teachers[0].schoolCode);
                     //(int status, string json) = await httpTrigger.RequestHttpTrigger(dict, _option.Location, "GetDiagnosisListByProject_V2");
                     //(int status, string json) = await httpTrigger.RequestHttpTrigger(dict, _option.Location, "GetDiagnosisListByProject_V2");
                     if (status == 200)
                     if (status == 200)
                     {
                     {
@@ -296,13 +307,13 @@ namespace TEAMModelOS.SDK.Models
             return abilities;
             return abilities;
         }
         }
 
 
-        
+
 
 
 
 
 
 
         //5.3.1.22学员校本教研PDF(每人可以返回多条)批量回写-UploadSBTARPDFListV2
         //5.3.1.22学员校本教研PDF(每人可以返回多条)批量回写-UploadSBTARPDFListV2
-        public  async static  Task<(int t53122OK, List<CodeValue> msgs, List<OfflineRecord> allRightOfflineRecords)> check53122(TeacherTrain teacherTrain, List<CodeValue> msgs,string school,
-            string schoolPrefix,string sas, AzureStorageFactory _azureStorage)
+        public async static Task<(int t53122OK, List<CodeValue> msgs, List<OfflineRecord> allRightOfflineRecords)> check53122(TeacherTrain teacherTrain, List<CodeValue> msgs, string school,
+            string schoolPrefix, string sas, AzureStorageFactory _azureStorage)
         {
         {
             int t53122OK = 1;
             int t53122OK = 1;
             if (teacherTrain.offlineRecords.Count <= 0)
             if (teacherTrain.offlineRecords.Count <= 0)
@@ -317,27 +328,30 @@ namespace TEAMModelOS.SDK.Models
                 t53122OK = 0;
                 t53122OK = 0;
                 msgs.Add(new CodeValue("offlineRecord-url", $"需要上传的校本研修作业至少有一个。"));
                 msgs.Add(new CodeValue("offlineRecord-url", $"需要上传的校本研修作业至少有一个。"));
             }
             }
-            if (teacherTrain.offlineReport==null) {
+            if (teacherTrain.offlineReport == null)
+            {
                 t53122OK = 0;
                 t53122OK = 0;
                 msgs.Add(new CodeValue("offlineReport", $"校本研修汇总报告未生成。"));
                 msgs.Add(new CodeValue("offlineReport", $"校本研修汇总报告未生成。"));
 
 
             }
             }
             List<string> unexistUrl = new List<string>();
             List<string> unexistUrl = new List<string>();
-            foreach (var url in hasUrl) {
+            foreach (var url in hasUrl)
+            {
                 string blobItem = url.url.Replace($"{schoolPrefix}/", "");
                 string blobItem = url.url.Replace($"{schoolPrefix}/", "");
                 bool Exist = await _azureStorage.GetBlobContainerClient(school).GetBlobClient(blobItem).ExistsAsync();
                 bool Exist = await _azureStorage.GetBlobContainerClient(school).GetBlobClient(blobItem).ExistsAsync();
                 if (!Exist)
                 if (!Exist)
                 {
                 {
                     unexistUrl.Add($"{url.url}?{sas}");
                     unexistUrl.Add($"{url.url}?{sas}");
                 }
                 }
-                else {
+                else
+                {
                     allRightOfflineRecords.Add(url);
                     allRightOfflineRecords.Add(url);
                 }
                 }
             }
             }
             if (unexistUrl.Any() && hasUrl.Count() > 0 && hasUrl.Count() == unexistUrl.Count)
             if (unexistUrl.Any() && hasUrl.Count() > 0 && hasUrl.Count() == unexistUrl.Count)
             {
             {
                 t53122OK = 0;
                 t53122OK = 0;
-                msgs.Add(new CodeValue("offlineRecord-url-unexist", $"校本研修文件不存在,{string.Join("  ,   " ,unexistUrl)}"));
+                msgs.Add(new CodeValue("offlineRecord-url-unexist", $"校本研修文件不存在,{string.Join("  ,   ", unexistUrl)}"));
             }
             }
 
 
             //不需要检查每一个校本研修的文件记录。
             //不需要检查每一个校本研修的文件记录。
@@ -354,7 +368,7 @@ namespace TEAMModelOS.SDK.Models
         }
         }
 
 
         //5.3.1.17学员课堂实录批量回写-UploadKTSLList
         //5.3.1.17学员课堂实录批量回写-UploadKTSLList
-        public async  static Task<(int t53117OK, List<CodeValue> msgs)> check53117(TeacherTrain teacherTrain, List<CodeValue> msgs, string school,
+        public async static Task<(int t53117OK, List<CodeValue> msgs)> check53117(TeacherTrain teacherTrain, List<CodeValue> msgs, string school,
             string schoolPrefix, string sas, AzureStorageFactory _azureStorage)
             string schoolPrefix, string sas, AzureStorageFactory _azureStorage)
         {
         {
             //校验 基本情况是否满足
             //校验 基本情况是否满足
@@ -370,7 +384,8 @@ namespace TEAMModelOS.SDK.Models
                 t53117OK = 0;
                 t53117OK = 0;
             }
             }
 
 
-            teacherTrain.teacherClasses.ForEach(x => {
+            teacherTrain.teacherClasses.ForEach(x =>
+            {
                 if (string.IsNullOrWhiteSpace(x.url))
                 if (string.IsNullOrWhiteSpace(x.url))
                 {
                 {
                     t53117OK = 0;
                     t53117OK = 0;
@@ -395,7 +410,7 @@ namespace TEAMModelOS.SDK.Models
             return (t53117OK, msgs);
             return (t53117OK, msgs);
         }
         }
         //5.3.1.12学员培训基本情况批量回写-UpdateTeacherListSituation
         //5.3.1.12学员培训基本情况批量回写-UpdateTeacherListSituation
-        public   static (int t53112OK, List<CodeValue> msgs) check53112(TeacherTrain teacherTrain, List<CodeValue> msgs)
+        public static (int t53112OK, List<CodeValue> msgs) check53112(TeacherTrain teacherTrain, List<CodeValue> msgs)
         {
         {
             //校验 基本情况是否满足
             //校验 基本情况是否满足
             int t53112OK = 1;
             int t53112OK = 1;
@@ -426,7 +441,7 @@ namespace TEAMModelOS.SDK.Models
             return (t53112OK, msgs);
             return (t53112OK, msgs);
         }
         }
         //5.3.1.13学员能力点测评结果批量回写-UpdateTeacherListDiagnosis
         //5.3.1.13学员能力点测评结果批量回写-UpdateTeacherListDiagnosis
-        public  async static Task<(int t53113OK, List<CodeValue> msgs, List<AbilitySub> abilitySubs, List<AbilitySub>  allRightAbility)> check53113(AzureCosmosFactory _azureCosmos,TeacherTrain teacherTrain, ScTeacherDiagnosis diagnosis, 
+        public async static Task<(int t53113OK, List<CodeValue> msgs, List<AbilitySub> abilitySubs, List<AbilitySub> allRightAbility)> check53113(AzureCosmosFactory _azureCosmos, TeacherTrain teacherTrain, ScTeacherDiagnosis diagnosis,
             List<CodeValue> msgs, string school,
             List<CodeValue> msgs, string school,
             string schoolPrefix, string sas, AzureStorageFactory _azureStorage)
             string schoolPrefix, string sas, AzureStorageFactory _azureStorage)
         {
         {
@@ -450,7 +465,8 @@ namespace TEAMModelOS.SDK.Models
                 msgs.Add(new CodeValue("teacherAilities", $"已学习能力点:0"));
                 msgs.Add(new CodeValue("teacherAilities", $"已学习能力点:0"));
                 t53113OK = 0;
                 t53113OK = 0;
             }
             }
-            try {
+            try
+            {
                 if (diagnosis != null)
                 if (diagnosis != null)
                 {
                 {
                     if (!string.IsNullOrWhiteSpace(diagnosis.abilityNos))
                     if (!string.IsNullOrWhiteSpace(diagnosis.abilityNos))
@@ -459,7 +475,7 @@ namespace TEAMModelOS.SDK.Models
                         if (nos.Count > 0 && teacherTrain.currency.teacherAilities.Count > 0)
                         if (nos.Count > 0 && teacherTrain.currency.teacherAilities.Count > 0)
                         {
                         {
                             var notin = nos.Except(teacherTrain.currency.teacherAilities.Select(x => x.no).Where(z => !string.IsNullOrWhiteSpace(z)));
                             var notin = nos.Except(teacherTrain.currency.teacherAilities.Select(x => x.no).Where(z => !string.IsNullOrWhiteSpace(z)));
-                            if (notin.Any()  )
+                            if (notin.Any())
                             {
                             {
                                 msgs.Add(new CodeValue("diagnosisNos", $"省平台勾选的能力点编号为学习完成:省平台:{string.Join(",", nos.OrderBy(x => x))}" + $" ,已学习:{string.Join(",", teacherTrain.currency.teacherAilities.Select(x => x.no).OrderBy(x => x))} "));
                                 msgs.Add(new CodeValue("diagnosisNos", $"省平台勾选的能力点编号为学习完成:省平台:{string.Join(",", nos.OrderBy(x => x))}" + $" ,已学习:{string.Join(",", teacherTrain.currency.teacherAilities.Select(x => x.no).OrderBy(x => x))} "));
                                 t53113OK = 0;
                                 t53113OK = 0;
@@ -481,7 +497,8 @@ namespace TEAMModelOS.SDK.Models
 
 
                                 if (abilitySubs.Count() <= 3)
                                 if (abilitySubs.Count() <= 3)
                                 {
                                 {
-                                    abilitySubs.ForEach(ab => {
+                                    abilitySubs.ForEach(ab =>
+                                    {
                                         var x = teacherTrain.currency.teacherAilities.Find(x => x.id.Equals(ab.id));
                                         var x = teacherTrain.currency.teacherAilities.Find(x => x.id.Equals(ab.id));
                                         if (x == null || !ab.uploads.Any())
                                         if (x == null || !ab.uploads.Any())
                                         {
                                         {
@@ -550,7 +567,8 @@ namespace TEAMModelOS.SDK.Models
                                             t53113OK = 0;
                                             t53113OK = 0;
                                             ///少于三个的,需要判断另外的不满足情况的
                                             ///少于三个的,需要判断另外的不满足情况的
                                             abilitySubs.RemoveAll(x => x.uploads.Count > 0);
                                             abilitySubs.RemoveAll(x => x.uploads.Count > 0);
-                                            abilitySubs.ForEach(ab => {
+                                            abilitySubs.ForEach(ab =>
+                                            {
                                                 var x = teacherTrain.currency.teacherAilities.Find(x => x.id.Equals(ab.id));
                                                 var x = teacherTrain.currency.teacherAilities.Find(x => x.id.Equals(ab.id));
                                                 if (x == null || !ab.uploads.Any())
                                                 if (x == null || !ab.uploads.Any())
                                                 {
                                                 {
@@ -607,7 +625,8 @@ namespace TEAMModelOS.SDK.Models
                                                 un_msg.Add(new CodeValue("uploads-url", $"{x.no},{x.name}上传的认证材料文件失效:{string.Join("   ,   ", urlUn)}"));
                                                 un_msg.Add(new CodeValue("uploads-url", $"{x.no},{x.name}上传的认证材料文件失效:{string.Join("   ,   ", urlUn)}"));
                                             }
                                             }
                                         }
                                         }
-                                        if (allRightAbility.Count<3) {
+                                        if (allRightAbility.Count < 3)
+                                        {
                                             t53113OK = 0;
                                             t53113OK = 0;
                                             msgs.AddRange(un_msg);
                                             msgs.AddRange(un_msg);
                                         }
                                         }
@@ -632,7 +651,9 @@ namespace TEAMModelOS.SDK.Models
                     msgs.Add(new CodeValue("teacherAilities", $"未同步省平台挑选的能力点"));
                     msgs.Add(new CodeValue("teacherAilities", $"未同步省平台挑选的能力点"));
                     t53113OK = 0;
                     t53113OK = 0;
                 }
                 }
-            } catch (Exception ex) {
+            }
+            catch (Exception ex)
+            {
                 throw new Exception($"{ex.StackTrace},{ex.Message}");
                 throw new Exception($"{ex.StackTrace},{ex.Message}");
             }
             }
             if (allRightAbility.Count < 3)
             if (allRightAbility.Count < 3)
@@ -643,5 +664,241 @@ namespace TEAMModelOS.SDK.Models
 
 
             return (t53113OK, msgs, abilitySubs, allRightAbility);
             return (t53113OK, msgs, abilitySubs, allRightAbility);
         }
         }
+
+        //推送作答数据
+        public static async Task<(string id, int code)> pushAnswers(CosmosClient client, AzureStorageFactory _azureStorage, IHttpClientFactory _httpClient, string activityId, string code)
+        {
+            if (string.IsNullOrEmpty(activityId))
+            {
+                try
+                {
+                    ExamInfo info = null;
+                    var response = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync(activityId.ToString(), new PartitionKey($"Exam-{code}"));
+                    if (response.Status == 200)
+                    {
+                        using var json = await JsonDocument.ParseAsync(response.ContentStream);
+                        info = json.ToObject<ExamInfo>();
+                    }
+                    List<ExamClassResult> classResults = new();
+                    if (info.scope.Equals("school", StringComparison.OrdinalIgnoreCase))
+                    {
+                        var queryResult = $"select value(c) where c.examId ='{activityId}' and c.pk = 'ExamClassResult' ";
+                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamClassResult>(queryText: queryResult,
+                            requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{info.school}") }))
+                        {
+                            classResults.Add(item);
+                        }
+                    }
+                    else
+                    {
+                        var queryResult = $"select value(c) where c.examId ='{activityId}' and c.pk = 'ExamClassResult' ";
+                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamClassResult>(queryText: queryResult,
+                            requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{code}") }))
+                        {
+                            classResults.Add(item);
+                        }
+                    }
+                    //如果单个活动包含多个科目
+                    var (grade, per) = await GetGradeAsync(client, info);
+                    var (currSemester, studyYear, currSemesterDate, date, nextSemester) = SchoolService.GetSemester(per, info.startTime);
+                    int no = 0;
+                    foreach (var subject in info.subjects)
+                    {
+                        //获取试题详细信息
+                        BlobDownloadResult index_json;
+                        if (info.scope.Equals("school"))
+                        {
+                            index_json = await _azureStorage.GetBlobContainerClient($"{info.school}").GetBlobClient($"{info.papers[no].blob}/index.json").DownloadContentAsync();
+                        }
+                        else
+                        {
+                            index_json = await _azureStorage.GetBlobContainerClient($"{info.creatorId}").GetBlobClient($"{info.papers[no].blob}/index.json").DownloadContentAsync();
+                        }
+                        JsonElement RecordingJson = JsonDocument.Parse(new MemoryStream(Encoding.UTF8.GetBytes(index_json.Content.ToString()))).RootElement;
+                        RecordingJson.TryGetProperty("slides", out JsonElement slides);
+                        var sdes = slides.ToObject<List<Slides>>();
+                        List<string> urls = new();
+                        foreach (var ne in sdes)
+                        {
+                            if (!ne.type.Equals("compose"))
+                            {
+                                urls.Add(ne.url);
+                            }
+                        }
+                        // 获取整体的题目ID集合
+                        List<string> ids = new();
+                        List<(string id, string type, double score, int difficulty, string choices, string answer)> itemInfos = new();
+                        int index = 1;
+                        foreach (string url in urls)
+                        {
+                            string id = url.Replace(".json", "");
+                            BlobDownloadResult index_item_json;
+                            if (info.scope.Equals("school"))
+                            {
+                                index_item_json = await _azureStorage.GetBlobContainerClient($"{info.school}").GetBlobClient($"{info.papers[no].blob}/{url}").DownloadContentAsync();
+                            }
+                            else
+                            {
+                                index_item_json = await _azureStorage.GetBlobContainerClient($"{info.creatorId}").GetBlobClient($"{info.papers[no].blob}/{url}").DownloadContentAsync();
+                            }
+                            JsonElement itemJson = JsonDocument.Parse(new MemoryStream(Encoding.UTF8.GetBytes(index_item_json.Content.ToString()))).RootElement;
+                            itemJson.TryGetProperty("exercise", out JsonElement exercise);
+                            var item_json = exercise.ToObject<Exercise>();
+                            string type = item_json.type;
+                            int level = item_json.level;
+                            double score = item_json.score;
+                            var ans = item_json.answer;
+                            if (itemJson.TryGetProperty("item", out JsonElement item))
+                            {
+                                var itemInfo_json = item.ToObject<List<itemInfo>>();
+                                StringBuilder sb = new();
+                                StringBuilder an = new();
+                                itemInfo_json.FirstOrDefault().option.Select(c => c.code).ToList().ForEach(z =>
+                                {
+                                    sb.Append(z);
+                                });
+                                ans.ForEach(z =>
+                                {
+                                    an.Append(z);
+                                });
+                                itemInfos.Add((index.ToString(), type, score, level, sb.ToString(), an.ToString()));
+                            }
+
+                            index++;
+                        }
+                        //学生作答信息
+                        List<(string stuId, List<(string questionNo, double score, string answer)> ansDt)> stuAns = new();
+                        foreach (ExamClassResult classResult in classResults)
+                        {
+                            if (classResult.subjectId.Equals(subject.id)) {
+                                int stuCount = 0;
+                                foreach (var stu in classResult.studentIds)
+                                {
+                                    int itemCount = 0;
+                                    List<(string questionNo, double score, string answer)> ansDt = new();
+                                    foreach (var itemNo in classResult.studentAnswers[stuCount])
+                                    {
+
+                                        ansDt.Add(((itemCount + 1).ToString(), classResult.studentScores[stuCount][itemCount], itemNo));
+                                        itemCount++;
+                                    }
+                                    stuAns.Add((stu, ansDt));
+                                    stuCount++;
+                                }
+                            }                            
+                        }                      
+                        var jsonString = new
+                        {
+
+                            examDate = info.startTime,
+                            //todo  不同学段年级数量不一致
+                            grade,
+                            subName = subject.name,
+                            totalScore = info.papers[no].point.Sum(),
+                            termCode = currSemester.start == 1 ? 1 : 2,
+                            data = new
+                            {
+                                items = itemInfos.Select(c => new
+                                {
+                                    questionNo = c.id,
+                                    c.type,
+                                    c.score,
+                                    c.difficulty,
+                                    c.choices,
+                                    c.answer
+                                }),
+                                stuDate = stuAns.Select(c => new
+                                {
+
+                                    stuNo = c.stuId,
+                                    scoreData = c.ansDt.Select(z => new
+                                    {
+                                        z.questionNo,
+                                        z.score,
+                                        z.answer
+                                    })
+                                })
+                            }
+                        };
+
+                        var key = Md5Hash.GetMd5String("TMD" + info.school);
+                        string connect = $"http://www.moofen.net/esi/tmd/exam/{info.school}/{key}";
+                        var htc = _httpClient.CreateClient();
+                        string paramJson = JsonConvert.SerializeObject(jsonString);
+                        var content = new StringContent(paramJson, Encoding.UTF8, "application/json");
+                        var ansResponse = await htc.PostAsync(connect, content);
+                        if ((int)ansResponse.StatusCode == 200)
+                        {
+                            return (activityId, 200);
+                        }
+                        no++;
+                    }
+                }
+                catch (CosmosException)
+                {
+                    return (activityId, 500);
+                }
+            }
+            return (activityId, 404);
+        }
+
+        public static async Task<(string gId, Period per)> GetGradeAsync(CosmosClient client, ExamInfo info)
+        {
+            if (info.grades.Count > 0)
+            {
+                var schresponse = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(info.school, new PartitionKey("Base"));
+                string grade = "";
+                School sc = new();
+                if (schresponse.Status == 200)
+                {
+                    using var schjson = await JsonDocument.ParseAsync(schresponse.ContentStream);
+                    sc = schjson.ToObject<School>();
+                }
+                var period = sc.period.Where(x => x.id.Equals(info.period.id)).FirstOrDefault();
+                var pType = sc.period.FirstOrDefault(c => c.id.Equals(info.period.id)).periodType;
+                int pcount = (int)(sc.period.Where(c => c.periodType.Equals("primary")).FirstOrDefault()?.grades.Count);
+                int jcount = (int)(sc.period.Where(c => c.periodType.Equals("junior")).FirstOrDefault()?.grades.Count);
+                if (pType.Equals("primary"))
+                {
+                    grade = (int.Parse(info.grades.FirstOrDefault().id) + 1).ToString();
+                }
+                else if (pType.Equals("junior"))
+                {
+                    grade = (int.Parse(info.grades.FirstOrDefault().id) + 1 + pcount).ToString();
+                }
+                else
+                {
+                    grade = (int.Parse(info.grades.FirstOrDefault().id) + 1 + pcount + jcount).ToString();
+                }
+                return (grade, period);
+            }
+            else
+            {
+                return ("", new Period());
+            }
+
+
+        }
+
+        private class item
+        {
+            public string questionNo { get; set; }
+            public string type { get; set; }
+            public double score { get; set; }
+            public int difficulty { get; set; }
+            public string choices { get; set; }
+            public string answer { get; set; }
+        }
+
+        private class itemInfo
+        {
+            public List<opt> option { get; set; } = new();
+
+        }
+        private class opt
+        {
+            public string code { get; set; }
+            public double value { get; set; }
+        }
     }
     }
 }
 }

+ 3 - 3
TEAMModelOS/Controllers/Analysis/ArtAnalysisController.cs

@@ -364,17 +364,17 @@ namespace TEAMModelOS.Controllers.Analysis
                         persent = Math.Round(z.point > 0 ? z.score / x.ToList().Count / z.point : 0, 2),
                         persent = Math.Round(z.point > 0 ? z.score / x.ToList().Count / z.point : 0, 2),
                         block = knos.Where(v => null != v.kno && v.kno.Contains(z.name)).Select(x => x.name)
                         block = knos.Where(v => null != v.kno && v.kno.Contains(z.name)).Select(x => x.name)
                     }),
                     }),
-                    block = claBlock.Where(c => c.Key.Equals(x.Key.classId)).FirstOrDefault().block.Select(z => new
+                    block = claBlock.Count() > 0 ? claBlock.Where(c => c.Key.Equals(x.Key.classId))?.FirstOrDefault().block.Select(z => new
                     {
                     {
                         name = z.Key,
                         name = z.Key,
                         persent = Math.Round(z.point > 0 ? z.score / x.ToList().Count / z.point : 0, 2)
                         persent = Math.Round(z.point > 0 ? z.score / x.ToList().Count / z.point : 0, 2)
-                    }),
+                    }) : null,
                     dim = claDims.Where(c => c.claId.Equals(x.Key.classId)).Select(z => new
                     dim = claDims.Where(c => c.claId.Equals(x.Key.classId)).Select(z => new
                     {
                     {
                         name = z.dim,
                         name = z.dim,
                         persent = Math.Round(z.point > 0 ? z.score / x.ToList().Count / z.point : 0, 2)
                         persent = Math.Round(z.point > 0 ? z.score / x.ToList().Count / z.point : 0, 2)
                     }),
                     }),
-                    examResults[0].classes.Where(c => c.id.Equals(x.Key.classId)).FirstOrDefault().gradeId
+                    examResults[0].classes.Where(c => c.id.Equals(x.Key.classId))?.FirstOrDefault().gradeId
                 });
                 });
                 //年级信息
                 //年级信息
                 var grades = students.GroupBy(c => c.gradeId).Select(x => new { gradeId = x.Key, list = x.ToList().Select(v => v.score).Where(c => c > 0) });
                 var grades = students.GroupBy(c => c.gradeId).Select(x => new { gradeId = x.Key, list = x.ToList().Select(v => v.score).Where(c => c > 0) });

+ 4 - 4
TEAMModelOS/Controllers/Common/ExamController.cs

@@ -1432,8 +1432,8 @@ namespace TEAMModelOS.Controllers
                             result.studentScores[index][i] = ans[index_sc][i];
                             result.studentScores[index][i] = ans[index_sc][i];
                         }
                         }
                         result.sum[index] = result.studentScores[index].Sum();
                         result.sum[index] = result.studentScores[index].Sum();
-                        bool flag = result.studentScores[index].Exists(r => r == -1);
-                        if (!flag)
+                        //bool flag = result.studentScores[index].Exists(r => r == -1);
+                        /*if (!flag)
                         {
                         {
                             if (s.type == 1)
                             if (s.type == 1)
                             {
                             {
@@ -1473,7 +1473,7 @@ namespace TEAMModelOS.Controllers
                                                 while (accounts.MoveNext())
                                                 while (accounts.MoveNext())
                                                 {
                                                 {
                                                     JsonElement account = accounts.Current;
                                                     JsonElement account = accounts.Current;
-                                                    scode.Add(account.GetProperty("shoolId").GetString());
+                                                    scode.Add(account.GetProperty("schoolId").GetString());
                                                 }
                                                 }
                                             }
                                             }
                                         }
                                         }
@@ -1491,7 +1491,7 @@ namespace TEAMModelOS.Controllers
                                     await _dingDing.SendBotMsg($"{_option.Location}\n{ex.Message}\n{ex.StackTrace}\n\n,id:{id},code:{s.id},school:{result?.school}", GroupNames.醍摩豆服務運維群組);
                                     await _dingDing.SendBotMsg($"{_option.Location}\n{ex.Message}\n{ex.StackTrace}\n\n,id:{id},code:{s.id},school:{result?.school}", GroupNames.醍摩豆服務運維群組);
                                 }
                                 }
                             }
                             }
-                        }
+                        }*/
 
 
                         index_sc++;
                         index_sc++;
                     }
                     }

+ 176 - 0
TEAMModelOS/Controllers/OpenApi/Business/BizExamController.cs

@@ -0,0 +1,176 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK;
+using TEAMModelOS.Models;
+using Microsoft.Extensions.Options;
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.Filter;
+using TEAMModelOS.SDK.Context.Constant;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+using TEAMModelOS.SDK.Models.Dtos;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Cosmos.School;
+using Azure.Cosmos;
+using System;
+using System.Linq;
+using DocumentFormat.OpenXml.VariantTypes;
+using static SKIT.FlurlHttpClient.Wechat.TenpayV3.Models.CreateApplyForSubjectApplymentRequest.Types;
+using TEAMModelOS.SDK.Models.Cosmos.OpenEntity;
+using DocumentFormat.OpenXml.Office2021.DocumentTasks;
+
+namespace TEAMModelOS.Controllers.OpenApi.Business
+{
+    [Route("exam")]
+    [ApiController]
+    public class BizExamController : ControllerBase
+    {
+        private readonly AzureCosmosFactory _azureCosmos;
+        private readonly AzureStorageFactory _azureStorage;
+        private readonly AzureRedisFactory _azureRedis;
+        private readonly DingDing _dingDing;
+        private readonly Option _option;
+        private readonly IConfiguration _configuration;
+        private readonly CoreAPIHttpService _coreAPIHttpService;
+        private readonly AzureServiceBusFactory _serviceBus;
+
+        public BizExamController(CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, DingDing dingDing, IOptionsSnapshot<Option> option, IConfiguration configuration, AzureServiceBusFactory serviceBus)
+        {
+            _azureCosmos = azureCosmos;
+            _azureStorage = azureStorage;
+            _azureRedis = azureRedis;
+            _dingDing = dingDing;
+            _option = option?.Value;
+            _configuration = configuration;
+            _coreAPIHttpService = coreAPIHttpService;
+            _serviceBus = serviceBus;
+        }
+
+        /// <summary>
+        /// 批量汇入评测考试结果数据
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("upsert-examInfo")]
+        [ApiToken(Auth = "2300", Name = "批量汇入评测考试结果数据", TName = "批次匯入評測考試結果數據", EName = "Batch import of evaluation exam result data", RWN = "W", Limit = false)]
+        public async Task<IActionResult> upsertExamInfo(JsonElement jsonElement)
+        {
+            var (id, school) = HttpContext.GetApiTokenInfo();
+            if (!jsonElement.TryGetProperty("id", out JsonElement examId)) return Ok(new { responseData = new ResponseData<dynamic>() { code = RespondCode.ParamsError, msg = "缺少唯一标识" } });
+            var cosmosClient = _azureCosmos.GetCosmosClient();
+            try
+            {
+
+                MfExam moofen = jsonElement.ToObject<MfExam>();
+                var ans = moofen.datas.Select(c => new { c.subjectName, c.answers }).ToList();
+                MoofenExam exam = new()
+                {
+                    id = examId.GetString(),
+                    code = $"moofen-{school}",
+                    examDate = moofen.examDate,
+                    examName = moofen.examName,
+                    semester = moofen.semester,
+                    grade = moofen.grade,
+                    periodType = moofen.periodType,
+                    ttl = -1
+                };
+                foreach (var data in moofen.datas)
+                {
+                    SubjectData subject = new()
+                    {
+                        subjectName = data.subjectName,
+                        totalScore = data.totalScore,
+                    };
+                    foreach (var paper in data.paperInfos)
+                    {
+                        PaperInfo paperInfo = new()
+                        {
+                            questionNo = paper.questionNo,
+                            type = paper.type,
+                            score = paper.score,
+                            difficulty = paper.difficulty,
+                            choices = paper.choices,
+                            answer = paper.answer,
+                        };
+                        subject.paperInfos.Add(paperInfo);
+                    }
+                    exam.datas.Add(subject);
+                }
+                List<StuAnswer> stuAnswers = new();
+                await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<StuAnswer>(
+                   queryText: $"select value(c) from c where c.examId = '{id}'",
+                   requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{school}") }))
+                {
+                    stuAnswers.Add(item);
+                }
+                List<Task<ItemResponse<StuAnswer>>> tasks = new();
+                if (stuAnswers.Count > 0)
+                {
+                    stuAnswers.ForEach(item => {
+                        item.ans = ans.Where(c => c.subjectName.Equals(item.subject)).FirstOrDefault().answers.Where(z => z.stuNo.Equals(item.stuNo)).FirstOrDefault().ans;
+                        tasks.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync(item, item.id,new PartitionKey($"{item.code}")));
+                    });
+                    await tasks.TaskPage(10);
+                }
+                else {
+                    foreach (var answer in ans)
+                    {
+                        foreach (var stu in answer.answers)
+                        {
+                            StuAnswer san = new()
+                            {
+                                id = Guid.NewGuid().ToString(),
+                                code = $"Answer-{school}",
+                                subject = answer.subjectName,
+                                stuNo = stu.stuNo,
+                                examId = examId.GetString(),
+                                ans = stu.ans,
+                                ttl = -1
+                            };
+                            tasks.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Student").CreateItemAsync(san, new PartitionKey($"{san.code}")));
+                        }
+                    }
+                    await tasks.TaskPage(10);
+                }                
+                await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").UpsertItemAsync(exam, new PartitionKey($"{exam.code}"));
+                return Ok(new { responseData = new ResponseData<dynamic>() { code = RespondCode.Ok, msg = "成功", data = examId } });
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"OS,{_option.Location},exam/upsert-examInfo()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                return Ok(new { responseData = new ResponseData<dynamic>() { code = RespondCode.ParamsError, msg = "推送失败" } });
+            }
+
+        }
+
+
+        public class MfExam
+        {
+            public long examDate { get; set; }
+            public string examName { get; set; }
+            //学期
+            public string semester { get; set; }
+            public int grade { get; set; }
+            //学段类型 primary junior senior
+            public string periodType { get; set; }
+            public List<Data> datas { get; set; }
+
+        }
+        public class Data
+        {
+            public string subjectName { get; set; }
+            public double totalScore { get; set; }
+            public List<PaperInfo> paperInfos { get; set; } = new();
+            public List<StuAnswerMore> answers { get; set; } = new();
+        }
+        public class StuAnswerMore
+        {
+            public string stuNo { get; set; }
+            public List<Ans> ans { get; set; } = new();
+        }
+    }
+}