|
@@ -1597,6 +1597,247 @@ namespace TEAMModelOS.Controllers
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 离线版本学生作答接口
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="request"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [ProducesDefaultResponseType]
|
|
|
+ [Authorize(Roles = "IES")]
|
|
|
+ [AuthToken(Roles = "student,teacher")]
|
|
|
+ [HttpPost("upsert-new-record")]
|
|
|
+ public async Task<IActionResult> upsertNewRecord(JsonElement request)
|
|
|
+ {
|
|
|
+
|
|
|
+ //评测活动Id
|
|
|
+ if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
|
|
|
+ //学生作答结果
|
|
|
+ if (!request.TryGetProperty("answer", out JsonElement answer)) return BadRequest();
|
|
|
+ //科目ID
|
|
|
+ if (!request.TryGetProperty("subjectId", out JsonElement subjectId)) return BadRequest();
|
|
|
+ //班级ID
|
|
|
+ if (!request.TryGetProperty("classId", out JsonElement classId)) return BadRequest();
|
|
|
+ //活动code
|
|
|
+ if (!request.TryGetProperty("ownerId", out JsonElement ownerId)) return BadRequest();
|
|
|
+ if (!request.TryGetProperty("paperId", out JsonElement paperId)) return BadRequest();
|
|
|
+ if (!request.TryGetProperty("studentId", out JsonElement studentId)) return BadRequest();
|
|
|
+
|
|
|
+ var (userId, name, picture, school) = HttpContext.GetAuthTokenInfo();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var client = _azureCosmos.GetCosmosClient();
|
|
|
+ ExamInfo info = new();
|
|
|
+ var response = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync(id.ToString(), new PartitionKey($"Exam-{ownerId}"));
|
|
|
+ if (response.StatusCode == System.Net.HttpStatusCode.OK)
|
|
|
+ {
|
|
|
+ using var cJson = await JsonDocument.ParseAsync(response.Content);
|
|
|
+ info = cJson.ToObject<ExamInfo>();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return Ok(new { code = 404, msg = "该活动未被找到" });
|
|
|
+ }
|
|
|
+ string code = string.Empty;
|
|
|
+ if (info.scope.Equals("school"))
|
|
|
+ {
|
|
|
+ code = info.school;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ code = info.creatorId;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<ExamClassResult> examClassResults = new List<ExamClassResult>();
|
|
|
+ await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIteratorSql(
|
|
|
+ queryText: $"select value(c) from c where c.examId = '{id}' and c.subjectId = '{subjectId}' and c.info.id = '{classId}' ",
|
|
|
+ requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{code}") }))
|
|
|
+ {
|
|
|
+ using var json = await JsonDocument.ParseAsync(item.Content);
|
|
|
+ if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
|
|
|
+ {
|
|
|
+ foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
|
|
|
+ {
|
|
|
+ examClassResults.Add(obj.ToObject<ExamClassResult>());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //获取试卷详情
|
|
|
+ PaperSimple paper = info.papers.Where(c => c.id.Equals(paperId.GetString())).FirstOrDefault();
|
|
|
+ examClassResults = examClassResults.Where(c => c.studentIds.Contains(studentId.GetString())).ToList();
|
|
|
+ ExamClassResult classResult = new ExamClassResult();
|
|
|
+
|
|
|
+ List<List<string>> ans = answer.ToObject<List<List<string>>>();
|
|
|
+ List<List<string>> standard = paper.answers;
|
|
|
+ List<double> points = paper.point;
|
|
|
+ int rule = paper.multipleRule;
|
|
|
+ List<Task<string>> tasks = new List<Task<string>>();
|
|
|
+ foreach (ExamClassResult result in examClassResults)
|
|
|
+ {
|
|
|
+
|
|
|
+ int newIndex = result.studentIds.IndexOf(studentId.ToString());
|
|
|
+ StringBuilder builder = new();
|
|
|
+ builder.Append(result.examId).Append('/');
|
|
|
+ builder.Append(result.subjectId).Append('/');
|
|
|
+ builder.Append(studentId.GetString()).Append('/');
|
|
|
+ builder.Append("ans.json");
|
|
|
+ tasks.Add(_azureStorage.GetBlobContainerClient(code.ToString()).UploadFileByContainer(ans.ToJsonString(), "exam", builder.ToString(), false));
|
|
|
+ result.studentAnswers[newIndex].Add(builder.ToString());
|
|
|
+ result.status[newIndex] = 0;
|
|
|
+ for (int i = 0; i < ans.Count; i++)
|
|
|
+ {
|
|
|
+
|
|
|
+ var sc = standard[i].Count;
|
|
|
+ var ac = ans[i].Where(a => a.Trim().Length > 0).ToList().Count;
|
|
|
+ //算分处理
|
|
|
+ if (sc > 0)
|
|
|
+ {
|
|
|
+ /* if (ans[i].Count == 0)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }*/
|
|
|
+ result.ans[newIndex][i] = ans[i];
|
|
|
+ if (ac == sc && sc == 1)
|
|
|
+ {
|
|
|
+ foreach (string right in ans[i])
|
|
|
+ {
|
|
|
+ if (standard[i].Contains(right.Trim()))
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = points[i];
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (rule > 0)
|
|
|
+ {
|
|
|
+ int falseCount = 0;
|
|
|
+ if (ac > 0)
|
|
|
+ {
|
|
|
+ foreach (string obj in ans[i])
|
|
|
+ {
|
|
|
+ if (!standard[i].Contains(obj))
|
|
|
+ {
|
|
|
+ falseCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ switch (rule)
|
|
|
+ {
|
|
|
+ case 1:
|
|
|
+ if (ac == sc)
|
|
|
+ {
|
|
|
+ if (falseCount == 0)
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = points[i];
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = 0;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ if (falseCount > 0)
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (ac == sc)
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = points[i];
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = points[i] / 2;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ if (falseCount > 0)
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (ac == sc)
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = points[i];
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = System.Math.Round((double)ac / sc * points[i], 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ if (ac == sc)
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = points[i];
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ double persent = (double)(sc - 2 * falseCount) / sc;
|
|
|
+ if (persent <= 0)
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = System.Math.Round(persent * points[i], 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ result.studentScores[newIndex][i] = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ bool isAns = result.studentScores[newIndex].Exists(s => s == -1);
|
|
|
+ HttpContext.Items.TryGetValue("Scope", out object type);
|
|
|
+ int userType = $"{type}".Equals(Constant.ScopeStudent) ? 2 : 1;
|
|
|
+ result.sum[newIndex] = result.studentScores[newIndex].Sum();
|
|
|
+ classResult = await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(result, result.id, new PartitionKey($"{result.code}"));
|
|
|
+ var target = info.scope.Equals("school") ? info.school : info.creatorId;
|
|
|
+ string _client = "web";
|
|
|
+ if (info.source.Equals("1"))
|
|
|
+ {
|
|
|
+ _client = "hiteach";
|
|
|
+ }
|
|
|
+ await SystemService.RecordAccumulateData(_azureRedis, _dingDing, new SDK.Models.Dtos.Accumulate { client = _client, count = 1, id = info.id, key = "exam-submit", name = info.name, scope = info.scope, target = target });
|
|
|
+ if (!isAns) {
|
|
|
+ if (request.TryGetProperty("artId", out JsonElement artId) && request.TryGetProperty("quotaId", out JsonElement quotaId))
|
|
|
+ {
|
|
|
+ await getArtInfoAsync(client, artId.GetString(), school, result.sum[newIndex], id.GetString(), subjectId.GetString(), quotaId.GetString(), userId, picture, name, userType, new List<string> { classId.GetString()});
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ await Task.WhenAll(tasks);
|
|
|
+ return Ok(new { classResult });
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ await _dingDing.SendBotMsg($"OS,{_option.Location},exam/upsertNewRecord()\n{e.Message}\n{e.StackTrace}\n\n{id.GetString()}\n{request.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
|
|
|
+ return BadRequest();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
[ProducesDefaultResponseType]
|