黄贺彬 hai 3 meses
pai
achega
56ecb987fb

+ 5 - 0
TEAMModelOS.Extension/IES.Exam/IES.ExamLibrary/Models/EvaluationCommon.cs

@@ -341,6 +341,11 @@ namespace IES.ExamServer.Models
         /// 题目数量
         /// </summary>
         public int questionCount { get; set; }
+        /// <summary>
+        /// 限时作答0 无限时,大于0 限时时间
+        /// </summary>
+        public long limitTime { get; set; }
+
     }
     public class EvaluationPaper: SubjectExamPaper
     {

+ 28 - 13
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Controllers/StudentController.cs

@@ -100,6 +100,11 @@ namespace IES.ExamServer.Controllers
                             pushed=0//强制重新推送
                         };
                         studentResult.musicAIResult= result;
+                        if (_connectionService!.centerIsConnected)
+                        {
+                            result.pushed=1;
+                            studentResult.musicAIResult.pushed=1;
+                        }
                         _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationMusicAIResult>().Upsert(result);
                         _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>().Upsert(studentResult);
                         return Ok(new { code = 200, studentResult = studentResult, msg = "提交成功!" });
@@ -189,14 +194,6 @@ namespace IES.ExamServer.Controllers
                             string subjectResultId = ShaHashHelper.GetSHA1(evaluationClient.id+examId+subjectId+token.id);
                             var subjectResult = studentResult.subjectResults.Where(x => subjectResultId.Equals(x.id) &&  subjectId.Equals(x.subjectId)
                                     && examId.Equals(x.examId) && paperId.Equals(x.paperId)).FirstOrDefault();
-                            if (subjectResult!=null)
-                            {
-                                subjectResult.answers=answers;
-                                subjectResult.finished=1;
-                                subjectResult.costTime=costTime;
-                                subjectResult.submitTime=now;
-                                subjectResult.pushed=0;//强制重新推送
-                            }
                             EvaluationSubjectResult result = new EvaluationSubjectResult()
                             {
                                 id = subjectResultId,
@@ -212,15 +209,34 @@ namespace IES.ExamServer.Controllers
                                 costTime=costTime,
                                 submitTime=now,
                                 answers=answers,
-                                questionCount=papers.IsNotEmpty()? papers!.First().questionCount : 0,
+                                questionCount=papers.IsNotEmpty() ? papers!.First().questionCount : 0,
                                 pushed=0//强制重新推送
                             };
-                            _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationSubjectResult>().Upsert(result);
-                            _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>().Upsert(studentResult);
+                            if (subjectResult!=null)
+                            {
+                                subjectResult.answers=answers;
+                                subjectResult.finished=1;
+                                subjectResult.costTime=costTime;
+                                subjectResult.submitTime=now;
+                                subjectResult.pushed=0;//强制重新推送
+                            }
+                            else 
+                            {
+                                studentResult.subjectResults.Add(result);
+                            }
+                           
                             if (_connectionService!.centerIsConnected)
                             {
-
+                                result.pushed=1;
+                                if (subjectResult!=null)
+                                {
+                                    subjectResult!.pushed=1;
+                                }
+                                new SubjectPushData(result, studentResult);
                             }
+                            _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationSubjectResult>().Upsert(result);
+                            _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>().Upsert(studentResult);
+                           
                         }
                        
                     }
@@ -317,7 +333,6 @@ namespace IES.ExamServer.Controllers
                             }
                             else
                             {
-
                                 return Ok(new { msg = "当前考试未添加该学生!", code = 7 });
                             }
 

+ 119 - 61
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/DI/SubjectPushService.cs

@@ -48,7 +48,7 @@ namespace IES.ExamServer.DI
             }
         }
         
-        private async Task PushSubjectResultDataToCloudAsync((EvaluationStudentResult studentResult, EvaluationSubjectResult subjectResult, string resultId)data, CancellationToken cancellationToken)
+        private async Task PushSubjectResultDataToCloudAsync(SubjectPushData data, CancellationToken cancellationToken)
         {
             if (_connectionService.centerIsConnected) 
             {
@@ -64,102 +64,101 @@ namespace IES.ExamServer.DI
                     }
                     httpClient.DefaultRequestHeaders.Add("X-Auth-AuthToken", _connectionService.loginToken);
                     var response = await httpClient.PostAsJsonAsync(url, new { 
-                        id =data.subjectResult.examId,
-                        answer=data.subjectResult.answers,
-                        subjectId=data.subjectResult.subjectId,
-                        classId=data.studentResult.classId,
-                        ownerId=data.studentResult.ownerId,
-                        paperId=data.subjectResult.paperId,
-                        studentId=data.studentResult.studentId,
-                        studentName=data.studentResult.studentName,
+                        id =data.examId,
+                        answer=data.answers,
+                        subjectId = data.subjectId,
+                        classId = data.classId,
+                        ownerId = data.ownerId,
+                        paperId = data.paperId,
+                        studentId = data.studentId,
+                        studentName = data.studentName,
                     }, cancellationToken);
 
                     if (response.IsSuccessStatusCode)
                     {
                         MarkDataAsPushed(data);
-                        Console.WriteLine($"Data {data.resultId} pushed successfully.");
+                        Console.WriteLine($"Data {data.studentResultId}{data.subjectResultId} pushed successfully.");
                     }
                     else
                     {
-                        Console.WriteLine($"Failed to push data {data.resultId}. Retrying...");
+                        Console.WriteLine($"Failed to push data {data.studentResultId}{data.subjectResultId}  Retrying...");
                         // 推送失败,重新加入队列
                         await _dataQueue.Writer.WriteAsync(data, cancellationToken);
                     }
                 }
                 catch (Exception ex)
                 {
-                    Console.WriteLine($"Error pushing data {data.resultId}: {ex.Message}");
+                    Console.WriteLine($"Error pushing data {data.studentResultId}{data.subjectResultId} : {ex.Message}");
                     // 推送失败,重新加入队列
                     await _dataQueue.Writer.WriteAsync(data, cancellationToken);
                 }
             }
         }
-        private void MarkDataAsPushed((EvaluationStudentResult studentResult, EvaluationSubjectResult subjectResult, string resultId) data)
+        private void MarkDataAsPushed(SubjectPushData data )
         {
-            var collection = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>();
-            EvaluationSubjectResult? subjectResult = data.studentResult.subjectResults.Where(x => x.id!.Equals(data.resultId)).FirstOrDefault();
+            EvaluationStudentResult  studentResult = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>().FindOne(x=>x.id!.Equals(data.studentResultId));
+            EvaluationSubjectResult  subjectResult = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationSubjectResult>().FindOne(x => x.id!.Equals(data.subjectResultId));
+            EvaluationSubjectResult? subjectResultInStundent = studentResult.subjectResults.Where(x => x.id!.Equals(data.subjectResultId)).FirstOrDefault();
+            if (subjectResultInStundent!=null) 
+            {
+                subjectResultInStundent.pushed=1;
+                _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>().Upsert(studentResult);
+            }
             if (subjectResult!=null) 
             {
                 subjectResult.pushed=1;
-                collection.Upsert(data.studentResult);
-                var collectionSub = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationSubjectResult>();
-                var unpushedData = collectionSub.FindOne(x => data.resultId.Equals(x.id));
-                if (unpushedData!=null) 
-                {
-                    unpushedData.pushed=1;
-                    _dataQueue.MarkAsProcessed((unpushedData.id!, unpushedData.examId!, unpushedData.evaluationId!, unpushedData.subjectId!,unpushedData, data.studentResult));
-                }
+                _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationSubjectResult>().Upsert(subjectResult);
             }
             
         }
-        private async Task LoadUnpushedDataAsync(CancellationToken cancellationToken)
-        {
-            var collection = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationSubjectResult>();
-            var unpushedData = collection.Find(x => x.pushed!=1);
-            foreach (var data in unpushedData)
-            {
-                var studentResults  = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>().Find(x => x.subjectResults.Where(x => x.id!.Equals(data.id)).IsNotEmpty()).Distinct();
-                // 将未推送的数据写入 Channel
-                foreach (var studentResult in studentResults)
-                {
-                    await _dataQueue.WriteAsync((studentResult!,data, data.id!), cancellationToken); 
-                }
-            }
-        }
+        //private async Task LoadUnpushedDataAsync(CancellationToken cancellationToken)
+        //{
+        //    var collection = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationSubjectResult>();
+        //    var unpushedData = collection.Find(x => x.pushed!=1);
+        //    foreach (var data in unpushedData)
+        //    {
+        //        var studentResults  = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>().Find(x => x.subjectResults.Where(x => x.id!.Equals(data.id)).IsNotEmpty()).Distinct();
+        //        // 将未推送的数据写入 Channel
+        //        foreach (var studentResult in studentResults)
+        //        {
+        //            await _dataQueue.WriteAsync((studentResult!,data, data.id!), cancellationToken); 
+        //        }
+        //    }
+        //}
     }
 
     public class DataQueue
     {
-        private readonly Channel<(EvaluationStudentResult studentResult, EvaluationSubjectResult subjectResult, string resultId)> _channel;
-        private readonly HashSet<(string resultId,string examId,string evaluationId,string subjectId, EvaluationSubjectResult subjectResult, EvaluationStudentResult studentResult)> _uniqueIds; // 用于维护唯一性
+        private readonly Channel<SubjectPushData> _channel;
+       // private readonly HashSet<(string resultId, SubjectPushData pushData)> _uniqueIds; // 用于维护唯一性
 
-        public async Task<bool> TryAddAsync((string resultId, string examId, string evaluationId, string subjectId, EvaluationSubjectResult subjectResult, EvaluationStudentResult studentResult) data, CancellationToken cancellationToken = default)
+        public async Task<bool> TryAddAsync(SubjectPushData pushData, CancellationToken cancellationToken = default)
         {
-            var key = (data.resultId, data.examId,data.evaluationId,data.subjectId,data.subjectResult,data.studentResult); // 复合键
-            lock (_uniqueIds)
-            {
-                if (_uniqueIds.Contains(key))
-                {
-                    return false;
-                }
-                _uniqueIds.Add(key);
-            }
+            //var key = (data.resultId,data.pushData); // 复合键
+            //lock (_uniqueIds)
+            //{
+            //    if (_uniqueIds.Contains(key))
+            //    {
+            //        return false;
+            //    }
+            //    _uniqueIds.Add(key);
+            //}
 
-            await _channel.Writer.WriteAsync((data.studentResult,data.subjectResult, data.resultId), cancellationToken);
+            await _channel.Writer.WriteAsync(pushData , cancellationToken);
             return true;
         }
         public DataQueue() {
             // 创建一个无界 Channel
-            _channel = Channel.CreateUnbounded<(EvaluationStudentResult studentResult, EvaluationSubjectResult subjectResult, string resultId)>();
-            _uniqueIds = new HashSet<(string resultId, string examId, string evaluationId, string subjectId, EvaluationSubjectResult subjectResult, EvaluationStudentResult studentResult)>();
+            _channel = Channel.CreateUnbounded<SubjectPushData>();
+           //_uniqueIds = new HashSet<(string resultId, SubjectPushData pushData)>();
         }
-        public ChannelWriter<(EvaluationStudentResult studentResult, EvaluationSubjectResult subjectResult, string resultId)> Writer => _channel.Writer;
-        public ChannelReader<(EvaluationStudentResult studentResult, EvaluationSubjectResult subjectResult, string resultId)> Reader => _channel.Reader;
+        public ChannelWriter<SubjectPushData> Writer => _channel.Writer;
+        public ChannelReader<SubjectPushData> Reader => _channel.Reader;
 
         // 批量写入数据
-        public async Task WriteAsync(( EvaluationStudentResult studentResult, EvaluationSubjectResult subjectResult, string resultId) data, CancellationToken cancellationToken = default)
+        public async Task WriteAsync(SubjectPushData data, CancellationToken cancellationToken = default)
         {
-            await _channel.Writer.WriteAsync((data.studentResult,data.subjectResult, data.resultId), cancellationToken);
+            await _channel.Writer.WriteAsync(data, cancellationToken);
         }
         // 获取当前队列中的未上传数据数量
         public int GetPendingCount()
@@ -167,12 +166,71 @@ namespace IES.ExamServer.DI
             return _channel.Reader.Count;
         }
         // 从队列中移除数据时,同时从 HashSet 中移除 ID
-        public void MarkAsProcessed((string resultId, string examId, string evaluationId, string subjectId, EvaluationSubjectResult subjectResult, EvaluationStudentResult studentResult) key)
+        //public void MarkAsProcessed((string resultId, SubjectPushData pushData) key)
+        //{
+        //    lock (_uniqueIds) // 加锁确保线程安全
+        //    {
+        //        _uniqueIds.Remove(key);
+        //    }
+        //}
+    }
+    /// <summary>
+    /// 用于推送数据的类
+    /// </summary>
+    public class SubjectPushData: EvaluationSubjectResult
+    {
+        public SubjectPushData() 
+        { }
+        public SubjectPushData(EvaluationSubjectResult subjectResult, EvaluationStudentResult studentResult) 
         {
-            lock (_uniqueIds) // 加锁确保线程安全
-            {
-                _uniqueIds.Remove(key);
-            }
+            
+            this.id = subjectResult.id;
+            this.subjectResultId = subjectResult.id;
+            this.examId = subjectResult.examId;
+            this.examName = subjectResult.examName;
+            this.subjectName = subjectResult.subjectName;
+            this.paperName = subjectResult.paperName;
+            this.evaluationId = subjectResult.evaluationId;
+            this.subjectId = subjectResult.subjectId;
+            this.paperId = subjectResult.paperId;
+            this.answers = subjectResult.answers;
+            this.pushed = subjectResult.pushed;
+            this.answers = subjectResult.answers;
+            this.questionCount = subjectResult.questionCount;
+            this.costTime= subjectResult.costTime;
+            this.evaluationId= subjectResult.evaluationId;
+            this.submitTime = subjectResult.submitTime;
+            this.finished = subjectResult.finished;
+            this.studentName = studentResult.studentName;
+            this.studentResultId = studentResult.id;
+            this.studentId = studentResult.studentId;
+            this.schoolId = studentResult.schoolId;
+            this.pid = studentResult.pid;
+            this.classId = studentResult.classId;
+            this.ownerId = studentResult.ownerId;
+            this.scope = studentResult.scope;
+            this.type = studentResult.type;
         }
+
+        public string? studentResultId { get; set; }
+        public string? subjectResultId { get; set; }
+        public string? studentId { get; set; }
+        public string? studentName { get; set; }
+        public string? schoolId { get; set; }
+        public string? pid { get; set; }
+        public string? classId { get; set; }
+        public string? ownerId { get; set; }
+        /// <summary>
+        /// 数据范围
+        /// </summary>
+        public string? scope { get; set; }
+        /// <summary>
+        /// 类型: Exam 普通评测, Art艺术评测
+        /// </summary>
+        public string? type { get; set; }
+        /// <summary>
+        /// 推送次数
+        /// </summary>
+        public int pushedCount { get; set; }
     }
 }

+ 2 - 2
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Models/EvaluationStudent.cs

@@ -144,7 +144,7 @@
         /// </summary>
         public long startTime { get; set; }
         /// <summary>
-        /// 是否推送0 未推送,1推
+        /// 是否推送-1 推送失败 0 未推送 ,1推送中  2 已推
         /// </summary>
         public int pushed { get; set; }
         //public HashSet<string> subjectResultIds= new HashSet<string>();
@@ -224,7 +224,7 @@
 
         public long createTime { get; set; }
         /// <summary>
-        /// 是否推送 0 未推送 1 已推送
+        /// 是否推送-1 推送失败 0 未推送 ,1推送中  2 已推送
         /// </summary>
         public int pushed { get; set; }
     }

+ 0 - 174
TEAMModelOS.Function/Properties/ServiceDependencies/TEAMModelOSFunction - Zip Deploy/profile.arm.json

@@ -1,174 +0,0 @@
-{
-  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
-  "contentVersion": "1.0.0.0",
-  "metadata": {
-    "_dependencyType": "compute.function.windows.appService"
-  },
-  "parameters": {
-    "resourceGroupName": {
-      "type": "string",
-      "defaultValue": "TEAMModelChengdu",
-      "metadata": {
-        "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking."
-      }
-    },
-    "resourceGroupLocation": {
-      "type": "string",
-      "defaultValue": "",
-      "metadata": {
-        "description": "Location of the resource group. Resource groups could have different location than resources, however by default we use API versions from latest hybrid profile which support all locations for resource types we support."
-      }
-    },
-    "resourceName": {
-      "type": "string",
-      "defaultValue": "TEAMModelOSFunction",
-      "metadata": {
-        "description": "Name of the main resource to be created by this template."
-      }
-    },
-    "resourceLocation": {
-      "type": "string",
-      "defaultValue": "[parameters('resourceGroupLocation')]",
-      "metadata": {
-        "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there."
-      }
-    }
-  },
-  "resources": [
-    {
-      "type": "Microsoft.Resources/resourceGroups",
-      "name": "[parameters('resourceGroupName')]",
-      "location": "[parameters('resourceGroupLocation')]",
-      "apiVersion": "2019-10-01"
-    },
-    {
-      "type": "Microsoft.Resources/deployments",
-      "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]",
-      "resourceGroup": "[parameters('resourceGroupName')]",
-      "apiVersion": "2019-10-01",
-      "dependsOn": [
-        "[parameters('resourceGroupName')]"
-      ],
-      "properties": {
-        "mode": "Incremental",
-        "expressionEvaluationOptions": {
-          "scope": "inner"
-        },
-        "parameters": {
-          "resourceGroupName": {
-            "value": "[parameters('resourceGroupName')]"
-          },
-          "resourceGroupLocation": {
-            "value": "[parameters('resourceGroupLocation')]"
-          },
-          "resourceName": {
-            "value": "[parameters('resourceName')]"
-          },
-          "resourceLocation": {
-            "value": "[parameters('resourceLocation')]"
-          }
-        },
-        "template": {
-          "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
-          "contentVersion": "1.0.0.0",
-          "parameters": {
-            "resourceGroupName": {
-              "type": "string"
-            },
-            "resourceGroupLocation": {
-              "type": "string"
-            },
-            "resourceName": {
-              "type": "string"
-            },
-            "resourceLocation": {
-              "type": "string"
-            }
-          },
-          "variables": {
-            "storage_name": "[toLower(concat('storage', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId))))]",
-            "appServicePlan_name": "[concat('Plan', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]",
-            "storage_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Storage/storageAccounts/', variables('storage_name'))]",
-            "appServicePlan_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/serverFarms/', variables('appServicePlan_name'))]",
-            "function_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/sites/', parameters('resourceName'))]"
-          },
-          "resources": [
-            {
-              "location": "[parameters('resourceLocation')]",
-              "name": "[parameters('resourceName')]",
-              "type": "Microsoft.Web/sites",
-              "apiVersion": "2015-08-01",
-              "tags": {
-                "[concat('hidden-related:', variables('appServicePlan_ResourceId'))]": "empty"
-              },
-              "dependsOn": [
-                "[variables('appServicePlan_ResourceId')]",
-                "[variables('storage_ResourceId')]"
-              ],
-              "kind": "functionapp",
-              "properties": {
-                "name": "[parameters('resourceName')]",
-                "kind": "functionapp",
-                "httpsOnly": true,
-                "reserved": false,
-                "serverFarmId": "[variables('appServicePlan_ResourceId')]",
-                "siteConfig": {
-                  "alwaysOn": true
-                }
-              },
-              "identity": {
-                "type": "SystemAssigned"
-              },
-              "resources": [
-                {
-                  "name": "appsettings",
-                  "type": "config",
-                  "apiVersion": "2015-08-01",
-                  "dependsOn": [
-                    "[variables('function_ResourceId')]"
-                  ],
-                  "properties": {
-                    "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storage_name'), ';AccountKey=', listKeys(variables('storage_ResourceId'), '2017-10-01').keys[0].value, ';EndpointSuffix=', 'core.windows.net')]",
-                    "FUNCTIONS_EXTENSION_VERSION": "~3",
-                    "FUNCTIONS_WORKER_RUNTIME": "dotnet"
-                  }
-                }
-              ]
-            },
-            {
-              "location": "[parameters('resourceGroupLocation')]",
-              "name": "[variables('storage_name')]",
-              "type": "Microsoft.Storage/storageAccounts",
-              "apiVersion": "2017-10-01",
-              "tags": {
-                "[concat('hidden-related:', concat('/providers/Microsoft.Web/sites/', parameters('resourceName')))]": "empty"
-              },
-              "properties": {
-                "supportsHttpsTrafficOnly": true
-              },
-              "sku": {
-                "name": "Standard_LRS"
-              },
-              "kind": "Storage"
-            },
-            {
-              "location": "[parameters('resourceGroupLocation')]",
-              "name": "[variables('appServicePlan_name')]",
-              "type": "Microsoft.Web/serverFarms",
-              "apiVersion": "2015-08-01",
-              "sku": {
-                "name": "S1",
-                "tier": "Standard",
-                "family": "S",
-                "size": "S1"
-              },
-              "properties": {
-                "name": "[variables('appServicePlan_name')]"
-              }
-            }
-          ]
-        }
-      }
-    }
-  ]
-}

+ 7 - 7
TEAMModelOS.SDK/Models/Service/EvaluationSyncInfoService.cs

@@ -186,7 +186,7 @@ namespace TEAMModelOS.SDK.Models.Service
                                         subjectName=subject.name,
                                         examId=id,
                                         examName=exam.name,
-                                        papers= group.list.Select(x=>new SubjectExamPaper {paperId= x.id,paperName=x.name, questionCount=x.answers.IsNotEmpty()?x.answers.Count():0, blob=x.blob, local=$"package/{evaluationSyncInfo.id}/papers/{x.id}" }).ToList(),
+                                        papers= group.list.Select(x=>new SubjectExamPaper {paperId= x.id,paperName=x.name,limitTime=x.time, questionCount=x.answers.IsNotEmpty()?x.answers.Count():0, blob=x.blob, local=$"package/{evaluationSyncInfo.id}/papers/{x.id}" }).ToList(),
                                     } );
 
                                     EvaluationExam evaluationExam = new EvaluationExam()
@@ -201,7 +201,7 @@ namespace TEAMModelOS.SDK.Models.Service
                                         scope=scope,
                                         stime=stime,
                                         etime=etime,
-                                        papers= group.list.Select(x => new EvaluationPaper { paperId= x.id, paperName=x.name, questionCount=x.answers.IsNotEmpty() ? x.answers.Count() : 0, blob=x.blob, local=$"package/{evaluationSyncInfo.id}/papers/{x.id}", point=x.point,knowledge=x.knowledge,type=x.type,field=x.field }).ToList(),
+                                        papers= group.list.Select(x => new EvaluationPaper { paperId= x.id, paperName=x.name, limitTime=x.time, questionCount=x.answers.IsNotEmpty() ? x.answers.Count() : 0, blob=x.blob, local=$"package/{evaluationSyncInfo.id}/papers/{x.id}", point=x.point,knowledge=x.knowledge,type=x.type,field=x.field }).ToList(),
                                     };
                                     evaluationExams.Add(evaluationExam);
                                 }
@@ -256,7 +256,7 @@ namespace TEAMModelOS.SDK.Models.Service
                                         var subjectSync = evaluationSyncInfo.subjects.Find(x => x.examId.Equals(item.acId) && x.subjectId.Equals(item.subject));
                                         if (subjectSync!=null)
                                         {
-                                            subjectSync.papers= papers?.Select(x => new SubjectExamPaper { paperId=x.id, paperName=x.name, questionCount=x.answers.IsNotEmpty() ? x.answers.Count() : 0, blob=x.blob, local=$"package/{evaluationSyncInfo.id}/papers/{x.id}" }).ToList();
+                                            subjectSync.papers= papers?.Select(x => new SubjectExamPaper { paperId=x.id, limitTime=x.time, paperName=x.name, questionCount=x.answers.IsNotEmpty() ? x.answers.Count() : 0, blob=x.blob, local=$"package/{evaluationSyncInfo.id}/papers/{x.id}" }).ToList();
                                             subjectSync.subjectName=subject.name;
                                         }
                                         else {
@@ -267,7 +267,7 @@ namespace TEAMModelOS.SDK.Models.Service
                                                 examId=item.acId,
                                                 examName=exam.name,
                                                 disorder=item.isOrder.HasValue ? item.isOrder.Value : 0,
-                                                papers = papers?.Select(x => new SubjectExamPaper { paperId=x.id, paperName=x.name, questionCount=x.answers.IsNotEmpty() ? x.answers.Count() : 0, blob=x.blob, local=$"package/{evaluationSyncInfo.id}/papers/{x.id}" }).ToList()
+                                                papers = papers?.Select(x => new SubjectExamPaper { paperId=x.id, paperName=x.name, limitTime=x.time, questionCount=x.answers.IsNotEmpty() ? x.answers.Count() : 0, blob=x.blob, local=$"package/{evaluationSyncInfo.id}/papers/{x.id}" }).ToList()
                                             });
                                         }
                                         dataTime= dataTime<exam._ts*1000 ? exam._ts*1000 : dataTime;
@@ -285,7 +285,7 @@ namespace TEAMModelOS.SDK.Models.Service
                                             stime=stime,
                                             etime=etime,
                                             disorder=item.isOrder.HasValue?item.isOrder.Value:0,
-                                            papers= papers.Select(x => new EvaluationPaper { paperId= x.id, paperName=x.name, blob=x.blob, questionCount=x.answers.IsNotEmpty() ? x.answers.Count() : 0, local=$"package/{evaluationSyncInfo.id}/papers/{x.id}", point=x.point, knowledge=x.knowledge, type=x.type, field=x.field }).ToList(),
+                                            papers= papers.Select(x => new EvaluationPaper { paperId= x.id, paperName=x.name, blob=x.blob, limitTime=x.time, questionCount=x.answers.IsNotEmpty() ? x.answers.Count() : 0, local=$"package/{evaluationSyncInfo.id}/papers/{x.id}", point=x.point, knowledge=x.knowledge, type=x.type, field=x.field }).ToList(),
                                         };
                                         evaluationExams.Add(evaluationExam);
                                     }
@@ -402,9 +402,9 @@ namespace TEAMModelOS.SDK.Models.Service
                             evaluationPaper =  evaluationExam.papers.Find(x => x.paperId.Equals(paper.paperId));
                             evaluationPaper.blobs=blobs;
                         }
-                        catch
+                        catch(Exception ex )
                         {
-
+                           await _dingDing.SendBotMsg($"数据打包异常,试卷检测异常,{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
                         }
                         long lastTime = blobs.Max(x => x.last);
                         blobTime= lastTime>blobTime?lastTime:blobTime;