CrazyIter_Bin 1 year ago
parent
commit
0ff217db59

+ 37 - 8
TEAMModelOS.SDK/Models/Cosmos/School/ExamImport.cs

@@ -64,6 +64,9 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         /// 科目名称
         /// </summary>
         public string name { get; set; }
+
+        public List<string> point = new List<string>();
+
         /// <summary>
         /// 配分
         /// </summary>
@@ -93,7 +96,7 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
         /// <summary>
         /// 总分
         /// </summary>
-        public double totalScore { get; set; }
+        public double score { get; set; }
         /// <summary>
         /// 小题得分,下标0顺序开始 第一题....N
         /// </summary>
@@ -128,15 +131,15 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
     /// 双向细目表 前端导入结构
     /// </summary>
     public class ImportExam {
-        [Required(ErrorMessage = "评测必填")]
+        [Required(ErrorMessage = "name_Required")]
         public string name { get; set; }
-        [Required(ErrorMessage = "时间必填")]
+        [Required(ErrorMessage = "time_Required")]
         public string time { get; set; }
-        [Required(ErrorMessage = "类型必填")]
+        [Required(ErrorMessage = "type_Required")]
         public string type { get; set; }
-        [Required(ErrorMessage = "学段必填")]
+        [Required(ErrorMessage = "periodId_Required")]
         public string periodId { get; set; }
-        [Required(ErrorMessage = "学校必填")]
+        [Required(ErrorMessage = "school_Required")]
         public string school { get; set; }
         public List<ImportExamSubject> subjects { get; set; } = new List<ImportExamSubject>();
 
@@ -146,8 +149,34 @@ namespace TEAMModelOS.SDK.Models.Cosmos.School
     /// </summary>
     public class ImportExamSubject
     {
-        public string name { get; set; }
-        public List<ExamImportItem> items { get; set; } = new List<ExamImportItem>();
+        public string subject        { get; set; }
+        public List<ImportExamItem> items { get; set; } = new List<ImportExamItem>();
         public List<ExamImportStudent> students { get; set; } = new List<ExamImportStudent>();
     }
+
+    /// <summary>
+    /// 配分
+    /// </summary>
+    public class ImportExamItem
+    {
+        /// <summary>
+        /// 从数组下标0开始
+        /// </summary>
+        public int index { get; set; }
+        /// <summary>
+        /// 认知层次
+        /// </summary>
+        public string filed { get; set; }
+        /// <summary>
+        /// 知识点
+        /// </summary>
+        public string point { get; set; } 
+        //compose--综合题,single--单选题,multiple--多选题,judge--判断题,complete--填空题,subjective--问答题,connector--连线题,correct--改错题
+        public string type { get; set; }
+        /// <summary>
+        /// 配分总分
+        /// </summary>
+        public double score { get; set; }
+    }
+
 }

+ 235 - 9
TEAMModelOS/Controllers/School/ImportExamController.cs

@@ -5,6 +5,12 @@ using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Options;
+using OfficeOpenXml;
+using StackExchange.Redis;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
 using System.Text.Json;
 using System.Threading.Tasks;
 using TEAMModelOS.Filter;
@@ -12,6 +18,7 @@ using TEAMModelOS.Models;
 using TEAMModelOS.SDK;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models.Cosmos.School;
 
 namespace TEAMModelOS.Controllers
@@ -52,27 +59,246 @@ namespace TEAMModelOS.Controllers
             _httpTrigger = httpTrigger;
         }
 
-        [ProducesDefaultResponseType]
-        [AuthToken(Roles = "teacher,admin")]
-        [HttpPost("import-check")]
-
+        // [AuthToken(Roles = "teacher,admin")]
+        [HttpPost("read-excel")]
+        //[Authorize(Roles = "IES")]
+        //[AuthToken(Roles = "teacher,admin,business")]
+        [RequestSizeLimit(102_400_000_00)] //最大10000m左右
+        public async Task<IActionResult> ReadExcel([FromForm] IFormFile file) {
+            // var (id, _, _, school) = HttpContext.GetAuthTokenInfo();
+            ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
+            using (ExcelPackage package = new ExcelPackage(file.OpenReadStream()))
+            {
+                ExcelWorksheets sheet = package.Workbook.Worksheets;
+                List<string> baseTitle = new List<string>();
+                List<string> baseData = new List<string>();
+                List<string> itemTitle = new List<string>();
+                List<List<string>> itemDatas = new List<List<string>>();
+                Dictionary<string, string> baseInfo = new Dictionary<string, string>();
+                List<Dictionary<string, string>> itemInfo = new List<Dictionary<string, string>>();
+                HashSet<string> subjects = new HashSet<string>();
+                //读取Exam_
+                var exam_sheet = sheet.Where(z => z.Name.StartsWith("Exam_")).FirstOrDefault();
+                if (exam_sheet!=null  )
+                {
+                  
+                    var rows = exam_sheet.Dimension.Rows;
+                    var columns = exam_sheet.Dimension.Columns;
+                    for (int r = 1; r < rows; r++) {
+                        List<string> itemData = null; 
+                        if (r >= 4) {
+                            itemData= new List<string>();
+                        }
+                        for (int c = 1; c < columns; c++) {
+                            var value = exam_sheet.GetValue(r, c);
+                            if (r == 1)
+                            {
+                                if (!string.IsNullOrWhiteSpace($"{value}"))
+                                {
+                                    baseTitle.Add($"{value}");
+                                }
+                                else
+                                {
+                                    break;
+                                }
+                            }
+                            else if (r == 2)
+                            {
+                                if (c > baseTitle.Count)
+                                {
+                                    break;
+                                }
+                                else
+                                {
+                                    baseData.Add($"{value}");
+                                }
+                            }
+                            else if (r == 3)
+                            {
+                                if (!string.IsNullOrWhiteSpace($"{value}"))
+                                {
+                                    itemTitle.Add($"{value}");
+                                }
+                                else
+                                {
+                                    break;
+                                }
 
+                            }
+                            else {
+                                if (c > itemTitle.Count)
+                                {
+                                    break;
+                                }
+                                else
+                                {
+                                    itemData.Add($"{value}");
+                                }
+                            }
+                        }
+                        if (itemData != null) {
+                            itemDatas.Add(itemData);
+                        }
+                    }
 
+                  
+                    for (int i = 0; i < baseTitle.Count; i++)
+                    {
+                        baseInfo.Add(baseTitle[i], baseData[i]);
+                    }
+                    for (int i = 0; i < itemDatas.Count; i++)
+                    {
+                        Dictionary<string, string> item = new Dictionary<string, string>();
+                        for (int j = 0; j < itemTitle.Count; j++)
+                        {
+                            item.Add(itemTitle[j], itemDatas[i][j]);
+                        }
+                        itemInfo.Add(item);
+                        subjects.Add(itemDatas[i][0]);
+                    }
+                }
+                List<Dictionary<string, object>> students = new List<Dictionary<string, object>>();
+                if (subjects.Count > 0) {
+                    foreach (var subject in subjects) {
+                        List<string> titles = new List<string>();
+                        List<string> datas = new List<string>();
+                        var subject_sheet = sheet.Where(z => z.Name.StartsWith($"Sub_{subject}")).FirstOrDefault();
+                        if (subject_sheet != null)
+                        {
+                            
+                            var rows = subject_sheet.Dimension.Rows;
+                            var columns = subject_sheet.Dimension.Columns;
+                            for (int r = 1; r < rows; r++)
+                            {
+                                for (int c = 1; c < columns; c++)
+                                {
+                                    var value = subject_sheet.GetValue(r, c);
+                                    if (r == 1)
+                                    {
+                                        if (!string.IsNullOrWhiteSpace($"{value}"))
+                                        {
+                                            titles.Add($"{value}");
+                                        }
+                                        else
+                                        {
+                                            break;
+                                        }
+                                    }
+                                    else {
+                                        if (c > titles.Count)
+                                        {
+                                            break;
+                                        }
+                                        else
+                                        {
+                                            datas.Add($"{value}");
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        
+                        for (int i = 0; i < datas.Count; i++)
+                        {
+                            Dictionary<string, object> item = new Dictionary<string, object>();
+                            List<KeyValuePair<int, int>> _index_order = new List<KeyValuePair<int, int>>();
+                            for (int j = 0; j < titles.Count; j++)
+                            {
+                                if (int.TryParse(titles[j], out int index))
+                                {
+                                    _index_order.Add(new KeyValuePair<int, int>(index , j));
+                                }
+                                else {
+                                    item.Add(titles[j], datas[i]);
+                                }
+                              
+                            }
+                            var orders = _index_order.OrderBy(x => x.Key).Select(x => x.Value).ToList();
+                            List<double> scores = new List<double>();
+                            for (int j = 0; j < orders.Count; j++)
+                            {
+                                double score = 0;
+                                double.TryParse(datas[j], out  score);
+                                scores.Add(score);
+                            }
+                            item.Add("scores", scores);
+                            students.Add(item);
+                        }
+                    }
+                }
+                return Ok(new { baseTitle, baseData, itemTitle, itemDatas, subjects, baseInfo, itemInfo, students });
+            } 
+        }
+        [ProducesDefaultResponseType]
+       // [AuthToken(Roles = "teacher,admin")]
+        [HttpPost("import-check")]
         public async Task<IActionResult> ImportCheck(JsonElement json) {
 
             var importExam = json.ToObject<ImportExam>();
-
             var validData= importExam.Valid();
-
-
+            if (!validData.isVaild) {
+                return Ok(new { code = 400, error = validData.errors.SelectMany(z => z.Value).ToList() });
+            }
+            List<string> error = new List<string>();
+            List<string> warn = new List<string>();
             string sql = $"select value c from c where c.name ='{importExam.name}'";
             var result =  await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<ExamImport>(sql,$"ExamImport-{importExam.school}",pageSize:1);
             ExamImport examImport = null;
-            if (string.IsNullOrEmpty(result.continuationToken)) { 
-                
+            if (string.IsNullOrEmpty(result.continuationToken)) {
+                warn.Add("name_duplicate");//评测名称重复
             }
             if (result.list.IsNotEmpty()) {
                 examImport = result.list[0];
+                warn.Add("name_update");//同名评测数据更新
+            }
+            if (examImport == null) { 
+                examImport= new ExamImport { name=importExam.name,type=importExam.type,school=importExam.school};
+                if (DateTimeOffset.TryParse(importExam.time, out DateTimeOffset dateTime))
+                {
+                    examImport.time = dateTime.ToUnixTimeMilliseconds();
+                }
+                else {
+                    error.Add("time_format");// 时间格式错误
+                    return Ok(new { code = 400, error  });
+                }
+            }
+
+            School schoolBase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(importExam.school, new Azure.Cosmos.PartitionKey("Base"));
+            Period period = schoolBase.period.Find(x => x.id.Equals(importExam.periodId));
+            if (period != null) {
+                foreach (var item in importExam.subjects)
+                {
+                   var subject = period.subjects.Find(z => z.name.Equals(item.subject ));
+                    if (subject != null)
+                    {
+                        // 学号确定的学生
+                        var ids =  item.students.Where(z => !string.IsNullOrWhiteSpace(z.id)).Select(x=>x.id);
+                        //没有学号 ,且姓名和班级信息不全的
+                        var studentInvalid = item.students.Where(z => string.IsNullOrWhiteSpace(z.id) && (string.IsNullOrWhiteSpace(z.name)||string.IsNullOrWhiteSpace(z.classId)));
+                        if(studentInvalid.Any())
+                        {
+                            error.Add("student_invalid ");// 学生信息不全
+                            return Ok(new { code = 400, error, studentInvalid });
+                        }
+                        var classesStu = item.students.Where(z => !string.IsNullOrWhiteSpace(z.classId) && string.IsNullOrWhiteSpace(z.id) ).Select(x => x.id);
+                        List<string>classNames = new List<string>();
+                        foreach(var clazz in classesStu)
+                        {
+                            var cls = clazz.Split("-");
+                            if (cls.Length == 2 && int.TryParse(cls[0], out int year) && year>2000 && int.TryParse(cls[1], out int no) && no>0)
+                            {
+                                string sqlClazz = $"select value c from c where c.year={year} and c.no ='{cls[1]}' and  ";
+                            }
+                            else {
+                                classNames.Add(clazz);
+                            }
+                        }
+                    }
+                    else {
+                        error.Add("subject_invalid");// 科目不存在
+                        return Ok(new { code = 400, error });
+                    }
+                }
             }
             return Ok();
         }

+ 21 - 0
TEAMModelOS/Controllers/XTest/TestController.cs

@@ -41,6 +41,7 @@ using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using TEAMModelOS.Controllers.Analysis;
 using TEAMModelOS.Controllers.Core;
+using TEAMModelOS.Controllers.Third.LePei;
 using TEAMModelOS.Filter;
 using TEAMModelOS.Models;
 using TEAMModelOS.SDK;
@@ -91,6 +92,26 @@ namespace TEAMModelOS.Controllers
             _searcher = searcher;
             _httpTrigger = httpTrigger;
         }
+
+
+
+        /// <summary>
+        /// 测试五育画像数据推送
+        /// </summary>
+        /// <param name="json"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("import-table")]
+        public async Task<IActionResult> ImportTable(JsonElement json)
+        {
+            List<LPSchool> schools = json.ToObject<List<LPSchool>>();
+            var table = _azureStorage.GetCloudTableClient().GetTableReference("ScYxpt");
+            await table.BatchInsertAsync (schools);
+            return Ok(schools);
+        }
+
+
+
         /// <summary>
         /// 测试五育画像数据推送
         /// </summary>

+ 1 - 0
TEAMModelOS/TEAMModelOS.csproj

@@ -6,6 +6,7 @@
   <ItemGroup>
     <PackageReference Include="DotNetZip" Version="1.16.0" />
 	  <PackageReference Include="DinkToPdf" Version="1.0.8" />
+	  <PackageReference Include="EPPlus" Version="6.2.6" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
   </ItemGroup>
   <ItemGroup>

+ 32 - 27
TEAMModelOS/appsettings.Development.json

@@ -22,43 +22,48 @@
   },
   "Azure": {
      //测试站数据库
-    "Storage": {
-      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodeltest;AccountKey=O2W2vadCqexDxWO+px+QK7y1sHwsYj8f/WwKLdOdG5RwHgW/Dupz9dDUb4c1gi6ojzQaRpFUeAAmOu4N9E+37A==;EndpointSuffix=core.chinacloudapi.cn"
-    },
-    "Cosmos": {
-      "ConnectionString": "AccountEndpoint=https://cdhabookdep-free.documents.azure.cn:443/;AccountKey=JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A==;"
-    },
-    "Redis": {
-      "ConnectionString": "52.130.252.100:6379,password=habook,ssl=false,abortConnect=False,writeBuffer=10240"
-    },
-    "ServiceBus": {
-      "ConnectionString": "Endpoint=sb://teammodelos.servicebus.chinacloudapi.cn/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=Sy4h4EQ8zP+7w/lOLi1X3tGord/7ShFHimHs1vC50Dc=",
-      "ActiveTask": "dep-active-task",
-      "ItemCondQueue": "dep-itemcond",
-      "GenPdfQueue": "dep-genpdf"
-    },
-    "SignalR": {
-      "ConnectionString": "Endpoint=https://channel.service.signalr.net;AccessKey=KrblW06tuA4a/GyqRPDU0ynFFmAWxbAvyJihHclSXbQ=;Version=1.0;"
-    }
-    // 正式站数据库
     //"Storage": {
-    //  "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelos;AccountKey=Dl04mfZ9hE9cdPVO1UtqTUQYN/kz/dD/p1nGvSq4tUu/4WhiKcNRVdY9tbe8620nPXo/RaXxs+1F9sVrWRo0bg==;EndpointSuffix=core.chinacloudapi.cn"
+    //  "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodeltest;AccountKey=O2W2vadCqexDxWO+px+QK7y1sHwsYj8f/WwKLdOdG5RwHgW/Dupz9dDUb4c1gi6ojzQaRpFUeAAmOu4N9E+37A==;EndpointSuffix=core.chinacloudapi.cn"
     //},
     //"Cosmos": {
-    //  "ConnectionString": "AccountEndpoint=https://teammodelos.documents.azure.cn:443/;AccountKey=clF73GwPECfP1lKZTCvs8gLMMyCZig1HODFbhDUsarsAURO7TcOjVz6ZFfPqr1HzYrfjCXpMuVD5TlEG5bFGGg==;"
+    //  "ConnectionString": "AccountEndpoint=https://cdhabookdep-free.documents.azure.cn:443/;AccountKey=JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A==;"
     //},
     //"Redis": {
-    //  "ConnectionString": "CoreRedisCN.redis.cache.chinacloudapi.cn:6380,password=LyJWP1ORJdv+poXWofAF97lhCEQPg1wXWqvtzXGXQuE=,ssl=True,abortConnect=False"
+    //  "ConnectionString": "52.130.252.100:6379,password=habook,ssl=false,abortConnect=False,writeBuffer=10240"
     //},
     //"ServiceBus": {
-    //  "ConnectionString": "Endpoint=sb://coreiotservicebuscnpro.servicebus.chinacloudapi.cn/;SharedAccessKeyName=TEAMModelOS;SharedAccessKey=llRPBMDJG9w1Nnifj+pGhV0g4H2REcq0PjvX2qqpcOg=",
-    //  "ActiveTask": "active-task",
-    //  "ItemCondQueue": "itemcond",
-    //  "GenPdfQueue": "genpdf"
+    //  "ConnectionString": "Endpoint=sb://teammodelos.servicebus.chinacloudapi.cn/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=Sy4h4EQ8zP+7w/lOLi1X3tGord/7ShFHimHs1vC50Dc=",
+    //  "ActiveTask": "dep-active-task",
+    //  "ItemCondQueue": "dep-itemcond",
+    //  "GenPdfQueue": "dep-genpdf"
     //},
     //"SignalR": {
-    //  "ConnectionString": "Endpoint=https://channel.signalr.azure.cn;AccessKey=AtcB7JYFNUbUXb1rGxa3PVksQ2X5YSv3JOHZR9J88tw=;Version=1.0;"
+    //  "ConnectionString": "Endpoint=https://channel.service.signalr.net;AccessKey=KrblW06tuA4a/GyqRPDU0ynFFmAWxbAvyJihHclSXbQ=;Version=1.0;"
     //}
+    // 正式站数据库
+    "Storage": {
+      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelos;AccountKey=Dl04mfZ9hE9cdPVO1UtqTUQYN/kz/dD/p1nGvSq4tUu/4WhiKcNRVdY9tbe8620nPXo/RaXxs+1F9sVrWRo0bg==;EndpointSuffix=core.chinacloudapi.cn"
+    },
+    "Cosmos": {
+      "ConnectionString": "AccountEndpoint=https://teammodelos.documents.azure.cn:443/;AccountKey=clF73GwPECfP1lKZTCvs8gLMMyCZig1HODFbhDUsarsAURO7TcOjVz6ZFfPqr1HzYrfjCXpMuVD5TlEG5bFGGg==;"
+    },
+    "Redis": {
+      "ConnectionString": "CoreRedisCN.redis.cache.chinacloudapi.cn:6380,password=LyJWP1ORJdv+poXWofAF97lhCEQPg1wXWqvtzXGXQuE=,ssl=True,abortConnect=False"
+    },
+    "ServiceBus": {
+      "ConnectionString": "Endpoint=sb://coreiotservicebuscnpro.servicebus.chinacloudapi.cn/;SharedAccessKeyName=TEAMModelOS;SharedAccessKey=llRPBMDJG9w1Nnifj+pGhV0g4H2REcq0PjvX2qqpcOg=",
+      "ActiveTask": "active-task",
+      "ItemCondQueue": "itemcond",
+      "GenPdfQueue": "genpdf"
+    },
+    "SignalR": {
+      "ConnectionString": "Endpoint=https://channel.signalr.azure.cn;AccessKey=AtcB7JYFNUbUXb1rGxa3PVksQ2X5YSv3JOHZR9J88tw=;Version=1.0;"
+    },
+    "Speech": {
+      "SubscriptionKey": "a4f5f4e2e2e54c6e8b0a4a0b4a0a4a0b",
+      "Region": "chinanorth3",
+      "Endpoint": "https://chinanorth3.api.cognitive.azure.cn/sts/v1.0/issuetoken"
+    }
   },
   "HaBookAuth": {
     "CoreId": {