using Microsoft.Azure.Cosmos; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.Json; using System.Threading.Tasks; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK.Extension; namespace TEAMModelOS.SDK.Models.Service { public static class ExamService { public static List getClasses(List cla, List stus) { List classes = new List(); try { if (cla.Count > 0) { foreach (string cl in cla) { classes.Add(cl); } } if (stus.Count > 0) { foreach (string stu in stus) { classes.Add(stu); } } return classes; } catch (Exception) { return classes; } } public static async Task deleteAsync(CosmosClient client, string id, string tId) { List correctIds = new List(); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryStreamIteratorSql(queryText: $"select c.id from c where c.cid = '{id}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"CorrectTask-{tId}") })) { using var jsonTask = await JsonDocument.ParseAsync(item.Content); if (jsonTask.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0) { var accounts = jsonTask.RootElement.GetProperty("Documents").EnumerateArray(); while (accounts.MoveNext()) { JsonElement account = accounts.Current; correctIds.Add(account.GetProperty("id").GetString()); } } } if (correctIds.Count > 0) { await client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemsStreamAsync(correctIds, $"CorrectTask-{tId}"); } } public static async Task classMore, double total,List<(string studentId, double scores, string classId)>students,long time )>> getGradeScore(CoreAPIHttpService _coreAPIHttpService, DingDing _dingDing, CosmosClient client, List classIds, string periodId, string schooCode,List examType, long stime, long etime) { List<(string name, List<(string classId,double average)> classMore, double total, List<(string studentId, double scores, string classId)> stus,long time)> grades = new(); //List<(string grade, double score)> grades = new(); try { //获取该年级所有班级ID /*List classIds = new(); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIteratorSql(queryText: $"select c.id from c where c.year = {gradeId} and c.pk = 'Class' and c.periodId = '{periodId}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{schooCode}") })) { using var jsonTask = await JsonDocument.ParseAsync(item.Content); if (jsonTask.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0) { var accounts = jsonTask.RootElement.GetProperty("Documents").EnumerateArray(); while (accounts.MoveNext()) { JsonElement account = accounts.Current; classIds.Add(account.GetProperty("id").GetString()); } } }*/ if (classIds.Count == 0) { return grades; } else { //获取该学期内学校发生的所有评测活动(不包含个人评测活动) List exams = new(); /* School sc = new(); var response = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(schooCode.ToString(), new PartitionKey($"Base")); if (response.StatusCode == System.Net.HttpStatusCode.OK) { using var json = await JsonDocument.ParseAsync(response.Content); sc = json.ToObject(); }*/ StringBuilder stringBuilder = new($"select value(c) from c where c.startTime >= {stime} and c.startTime < {etime} and c.progress = 'finish' and c.period.id = '{periodId}'"); if (examType.Any()) { stringBuilder.Append($" and c.examType.name in ({string.Join(",", examType.Select(o => $"'{o}'"))}) "); } stringBuilder.Append(" order by c.createTime desc"); //var gradeNames = sc.period.Where(x => x.id.Equals(periodId.ToString()))?.FirstOrDefault().grades; //var index = gradeNames.IndexOf(gradeName.ToString()); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIteratorSql( queryText: stringBuilder.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{schooCode}") })) { exams.Add(item); } List newExams = new(); //exams = exams.Where(x => x.period.id.Equals(periodId)).ToList(); foreach (ExamInfo info in exams) { bool flag = true; foreach (string id in classIds) { if (!info.classes.Contains(id)) { flag = false; } } if (flag) { newExams.Add(info); } } if (newExams.Count > 3) { newExams = newExams.Take(3).ToList(); } List examIds = newExams.Select(x => x.id).ToList(); if (examIds.Count > 0) { List classResults = new(); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIteratorSql( queryText: $"select value(c) from c where c.examId in ({string.Join(",", examIds.Select(x => $"'{x}'"))})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{schooCode}") })) { classResults.Add(item); } (List rmembers, List groups) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, classIds, schooCode); foreach (ExamInfo info in newExams) { double totalScore = info.papers[0].point.Sum(); var classResult = classResults.Where(x => x.examId.Equals(info.id)).ToList(); var classScores = classResult.GroupBy(x => x.info.id).Select(c => new { classId = c.Key, average = Math.Round(c.ToList().Sum(z => z.average) / info.subjects.Count / totalScore,4) }).ToList(); List<(string className, double average)> classMore = new(); foreach (var cs in classScores) { classMore.Add((cs.classId, cs.average)); } var gradeScores = Math.Round(info.average / totalScore,4); List<(string sname, double scores, string classId)> stus = new(); foreach (RMember member in rmembers) { double scroe = 0; foreach (ExamClassResult result in classResult) { if (result.studentIds.Contains(member.id)) { int index = result.studentIds.IndexOf(member.id); scroe += result.sum[index]; } } var persent = Math.Round(scroe * 1.0 / totalScore, 4); stus.Add((member.id, persent, member.classId)); } grades.Add((info.name, classMore, gradeScores, stus,info.startTime)); } } } } catch (Exception e) { await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ExamService-getGradeScore()\n{e.Message}\n{e.StackTrace}", GroupNames.成都开发測試群組); } return grades; } public static async Task saveMoreAsync(CosmosClient client, DingDing _dingDing, ExamLite trExam) { try { trExam.ttl = -1; trExam.code = "ExamLite-" + trExam.school; trExam.scope = "school"; long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); trExam.createTime = now; if (trExam.publish == 1) { trExam.progress = "pending"; } else { if (trExam.startTime > now) { trExam.progress = "pending"; } else { trExam.progress = "going"; } } if (string.IsNullOrEmpty(trExam.id)) { trExam.id = Guid.NewGuid().ToString(); await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(trExam, new PartitionKey($"{trExam.code}")); } else { await client.GetContainer("TEAMModelOS", "Common").UpsertItemAsync(trExam, new PartitionKey($"{trExam.code}")); } return trExam.id; } catch (Exception e) { await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ExamService-saveMore\n{e.Message}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組); return ""; } } public static async Task<(List datas, string continuationToken)> FindExam(JsonElement request, string id, string school, AzureCosmosFactory _azureCosmos) { List examInfo = new(); try { var client = _azureCosmos.GetCosmosClient(); string sub = string.Empty; string subject = string.Empty; if (request.TryGetProperty("subjectId", out JsonElement subjectId) && !string.IsNullOrWhiteSpace($"{subjectId}")) { sub = $" join A0 in c.subjects "; subject = $" and A0.id = '{subjectId}'"; } StringBuilder stringBuilder = new($"select c.id,c.name,c.code,c.period,c.startTime,c.endTime,c.stuCount,c.type,c.progress,c.examType,c.createTime,c.source, c.subjects, c.grades,c.owner, c.scope,c.classes, c.stuLists, c.sRate,c.lostStu,c.sStatus,c.qamode,c.school,c.cloudas from c {sub} where (c.status<>404 or IS_DEFINED(c.status) = false) and c.pk = 'Exam' {subject}"); //开始时间, if (request.TryGetProperty("stime", out JsonElement stime)) { if (long.TryParse($"{stime}", out long data)) { stringBuilder.Append($" and c.startTime >= {data} "); }; }; //默认当前时间 var etimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); stringBuilder.Append($" and c.startTime <= {etimestamp} "); /*if (request.TryGetProperty("etime", out JsonElement etime)) { if (long.TryParse($"{etime}", out long data)) { stringBuilder.Append($" and c.createTime <= {data} "); }; };*/ // string periodId = string.Empty; if (request.TryGetProperty("name", out JsonElement name) && !string.IsNullOrWhiteSpace($"{name}")) { stringBuilder.Append($" and Contains( c.name , '{name}') = true "); } if (request.TryGetProperty("classId", out JsonElement classId) && !string.IsNullOrWhiteSpace($"{classId}")) { if (request.TryGetProperty("classType", out JsonElement classType) && !string.IsNullOrWhiteSpace($"{classType}")) { if (classType.ToString().Equals("class")) { stringBuilder.Append($" and array_contains(c.classes, '{classId}')"); } else { stringBuilder.Append($" and array_contains(c.stuLists, '{classId}')"); } } } if (request.TryGetProperty("owner", out JsonElement owner) && !string.IsNullOrWhiteSpace($"{owner}")) { stringBuilder.Append($" and c.owner = '{owner}' "); } if (request.TryGetProperty("source", out JsonElement source) && !string.IsNullOrWhiteSpace($"{source}")) { stringBuilder.Append($" and c.source = '{source}' "); } if (request.TryGetProperty("type", out JsonElement type)) { if (!type.ValueKind.Equals(JsonValueKind.Undefined) && !type.ValueKind.Equals(JsonValueKind.Null) && type.ValueKind.Equals(JsonValueKind.String)) { stringBuilder.Append($" and c.pk = '{type}' "); } } stringBuilder.Append("order by c.createTime desc"); //string token = null; string token = default; //默认不指定返回大小 int? topcout = null; if (request.TryGetProperty("count", out JsonElement jcount)) { if (!jcount.ValueKind.Equals(JsonValueKind.Undefined) && !jcount.ValueKind.Equals(JsonValueKind.Null) && jcount.TryGetInt32(out int data)) { topcout = data; } } //是否需要进行分页查询,默认不分页 bool iscontinuation = false; if (topcout != null && topcout.Value > 0) { iscontinuation = true; } //如果指定了返回大小 if (request.TryGetProperty("continuationToken", out JsonElement token_1)) { if (!token_1.ValueKind.Equals(JsonValueKind.Null) && token_1.ValueKind.Equals(JsonValueKind.String)) { token = token_1.GetString(); } } await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIteratorSql(queryText: stringBuilder.ToString(), continuationToken: token, requestOptions: new QueryRequestOptions() { MaxItemCount = topcout })) { 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()) { examInfo.Add(obj.ToObject()); } } if (iscontinuation) { token = item.ContinuationToken; break; } } return (examInfo, token); } catch (Exception e) { return (examInfo,"500"); } } /* public static async Task getKnowledges(List knowledges,List answers ,string sub,List> kones,List point) { foreach (string k in knowledges) { double score = 0; double allScore = 0; int n = 0; int count = 0; foreach (ExamClassResult result in answers) { if (result.subjectId.Equals(sub)) { foreach (List str in kones) { if (str.Contains(k)) { var itemPersent = str.Count > 0 ? 1 / Convert.ToDouble(str.Count) : 0; allScore += point.Count > 0 ? point[n] * itemPersent : 0; if (result.studentScores.Count > 0) { score += result.studentScores.Sum(r => r.Sum()) * itemPersent; } } n++; } count += result.studentIds.Count; } } double per = count > 0 ? Math.Round(score / count, 2) : 0; } }*/ } }