123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- using IES.ExamLibrary.Models;
- using IES.ExamServer.DI;
- using IES.ExamServer.Filters;
- using IES.ExamServer.Helper;
- using IES.ExamServer.Helpers;
- using IES.ExamServer.Models;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Caching.Memory;
- using Microsoft.Extensions.Hosting;
- using Microsoft.VisualBasic;
- using System;
- using System.Text.Json.Nodes;
- using System.Threading.Tasks;
- namespace IES.ExamServer.Controllers
- {
- [ApiController]
- [Route("student")]
- public class StudentController : BaseController
- {
- private readonly IConfiguration _configuration;
- private readonly IHttpClientFactory _httpClientFactory;
- private readonly IMemoryCache _memoryCache;
- private readonly ILogger<IndexController> _logger;
- private readonly CenterServiceConnectionService _connectionService;
- private readonly LiteDBFactory _liteDBFactory;
- private readonly DataQueue _dataQueue;
- public StudentController(ILogger<IndexController> logger, IConfiguration configuration, IHttpClientFactory httpClientFactory,
- IMemoryCache memoryCache, CenterServiceConnectionService connectionService, LiteDBFactory liteDBFactory, DataQueue dataQueue)
- {
- _logger = logger;
- _configuration=configuration;
- _httpClientFactory=httpClientFactory;
- _memoryCache=memoryCache;
- _connectionService=connectionService;
- _liteDBFactory=liteDBFactory;
- _dataQueue=dataQueue;
- }
- /// <summary>
- /// 学生提交音乐作答
- /// </summary>
- /// <param name="json"></param>
- /// <returns></returns>
- [HttpPost("submit-music-ai-result")]
- [AuthToken("student")]
- public IActionResult SubmitMusicAIResult(JsonNode json)
- {
- int finished = int.Parse($"{json["finished"]}");
- string evaluationId = $"{json["evaluationId"]}";
- string taskId = $"{json["taskId"]}";
- string questionId = $"{json["questionId"]}";
- long costTime = int.Parse($"{json["costTime"]}");
- string settingId = $"{json["settingId"]}";
- var token = GetAuthTokenInfo();
- EvaluationRoundSetting? setting = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationRoundSetting>().FindOne(x => x.id!.Equals(settingId) && evaluationId.Equals(x.evaluationId) && x.activate==1);
- EvaluationClient? evaluationClient = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationClient>().FindOne(x => evaluationId.Equals(x.id));
- if (evaluationClient!=null && setting!=null && setting.activate==1)
- {
- string resultId = ShaHashHelper.GetSHA1(evaluationId+_connectionService?.serverDevice?.school?.id+token.id);
- EvaluationStudentResult studentResult = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>()
- .FindOne(x => resultId.Equals(x.id) && token.id.Equals(x.studentId) && evaluationId.Equals(x.evaluationId));
- if (studentResult!=null)
- {
- long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
- //判断开始时间
- if ((setting.startline>0 && setting.startline>now)|| evaluationClient.stime>now)
- {
- //未到开始时间
- return Ok(new { msg = "未到开始时间。", code = 1 });
- }
- //判断截止时间
- long deadline;
- if (setting.countdownType==2)
- {
- deadline= studentResult.startTime+setting.countdown;
- }
- else
- {
- deadline= setting.startline+setting.countdown;
- }
- deadline+= 10*60*1000;//漂移10分钟,允许学生延迟提交,但是前端页面显示的截止时间是准的,时间一到,可自动提交。
- //已过截止时间
- //if ((deadline>0&&deadline<now)|| evaluationClient.etime<now)
- //{
- // return Ok(new { msg = "已过截止时间。", code = 2 });
- //}
- if (!string.IsNullOrWhiteSpace(questionId) && !string.IsNullOrWhiteSpace(taskId) && costTime>0)
- {
- var result = new EvaluationMusicAIResult()
- {
- id= ShaHashHelper.GetSHA1($"{evaluationId}{questionId}{taskId}{token.id}"),
- taskId = taskId,
- questionId = questionId,
- costTime = costTime,
- finished = finished,
- submitTime = now,
- questionName=!string.IsNullOrWhiteSpace(evaluationClient?.music?.questionName) ? evaluationClient.music.questionName : null,
- evaluationId=evaluationId,
- createTime=now,
- 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 = "提交成功!" });
- }
- else
- {
- return Ok(new { msg = "提交失败,请检查参数。", code = 3 });
- }
- }
- else
- {
- return Ok(new { msg = "未找到该学生的作答信息。", code = 4 });
- }
- }
- else {
- return Ok(new { msg = "未匹配到正则开考的评测。", code = 5 });
- }
-
- }
- /// <summary>
- /// 学生提交科目作答
- /// </summary>
- /// <param name="json"></param>
- /// <returns></returns>
- [HttpPost("submit-subject-result")]
- [AuthToken("student")]
- public async Task<IActionResult> SubmitSubjectResult(JsonNode json)
- {
- List<List<string>>? answers = json["answer"]?.ToObject<List<List<string>>>();
- string evaluationId = $"{json["evaluationId"]}";
- string examId = $"{json["examId"]}";
- string subjectId = $"{json["subjectId"]}";
- string paperId = $"{json["paperId"]}";
- long costTime = int.Parse($"{json["costTime"]}");
- string settingId = $"{json["settingId"]}";
- var token = GetAuthTokenInfo();
- EvaluationRoundSetting? setting = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationRoundSetting>().FindOne(x => x.id!.Equals(settingId) && evaluationId.Equals(x.evaluationId) && x.activate==1);
- EvaluationClient? evaluationClient = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationClient>().FindOne(x=>evaluationId.Equals(x.id));
- if (evaluationClient!=null && setting!=null && setting.activate==1)
- {
- string resultId = ShaHashHelper.GetSHA1(evaluationId+_connectionService?.serverDevice?.school?.id+token.id);
- EvaluationStudentResult studentResult = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>()
- .FindOne(x => resultId.Equals(x.id) && token.id.Equals(x.studentId) && evaluationId.Equals(x.evaluationId));
- if (studentResult!=null)
- {
- long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
- //判断开始时间
- if ((setting.startline>0 && setting.startline>now)|| evaluationClient.stime>now)
- {
- //未到开始时间
- return Ok(new { msg = "未到开始时间。", code = 1 });
- }
- //判断截止时间
- long deadline;
- if (setting.countdownType==2)
- {
- deadline= studentResult.startTime+setting.countdown;
- }
- else
- {
- deadline= setting.startline+setting.countdown;
- }
- deadline+= 10*60*1000;//漂移10分钟,允许学生延迟提交,但是前端页面显示的截止时间是准的,时间一到,可自动提交。
- //已过截止时间
- //if ((deadline>0&&deadline<now)|| evaluationClient.etime<now)
- //{
-
- // return Ok(new { msg = "已过截止时间。", code = 2 });
- //}
- if (!string.IsNullOrWhiteSpace(subjectId) && !string.IsNullOrWhiteSpace(examId) && !string.IsNullOrWhiteSpace(paperId))
- {
-
- if (answers!.IsNotEmpty())
- {
- var subjectExams= evaluationClient.subjects.FindAll(x => examId.Equals(x.examId)&& subjectId.Equals(x.subjectId));
- var papers= subjectExams.FirstOrDefault()?.papers.FindAll(x => paperId.Equals(x.paperId));
- if (papers.IsNotEmpty())
- {
- if (answers!.Count()!=papers!.First()?.questionCount)
- {
- return Ok(new { msg = "提交的答案数量与试卷题目数量不匹配。", code = 5 });
- }
- }
- 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();
- EvaluationSubjectResult result = new EvaluationSubjectResult()
- {
- id = subjectResultId,
- evaluationId = evaluationId,
- examId = examId,
- examName = subjectResult?.examName,
- subjectId = subjectId,
- subjectName = subjectResult?.subjectName,
- paperId =paperId,
- paperName = subjectResult?.paperName,
- createTime=now,
- finished=1,
- costTime=costTime,
- submitTime=now,
- answers=answers,
- questionCount=papers.IsNotEmpty() ? papers!.First().questionCount : 0,
- pushed=0//强制重新推送
- };
- 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;
- }
- await _dataQueue.TryAddAsync(new SubjectPushData(result, studentResult));
- }
- _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationSubjectResult>().Upsert(result);
- _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>().Upsert(studentResult);
-
- }
-
- }
- return Ok(new { code = 200, studentResult = studentResult, msg = "提交成功!" });
- }
- else {
- return Ok(new { msg = "未找到该学生的作答信息。", code = 4});
- }
- }
- else
- {
- return Ok(new { msg = "未匹配到正则开考的评测。", code = 3 });
- }
-
-
- }
- /// <summary>
- /// 获取学生当前考试的作答信息。
- /// </summary>
- /// <param name="json"></param>
- /// <returns></returns>
- [HttpPost("load-evaluation-result")]
- [AuthToken("student")]
- public IActionResult LoadEvaluationResult(JsonNode json)
- {
- string evaluationId = $"{json["evaluationId"]}";
- var token = GetAuthTokenInfo();//6af32bbd-144e-4366-8bc0-61ba4c85677c
- string resultId = ShaHashHelper.GetSHA1(evaluationId+_connectionService?.serverDevice?.school?.id+token.id);
- string? scoolId = _connectionService?.serverDevice?.school?.id;
- EvaluationStudentResult studentResult = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>()
- .FindOne(x=> resultId.Equals(x.id) && !string.IsNullOrWhiteSpace(x.schoolId) && x.schoolId.Equals(scoolId)&& token.id.Equals(x.studentId) && evaluationId.Equals(x.evaluationId));
- if (studentResult!=null)
- {
- //标记开始作答
- if (studentResult.finished<1)
- {
- studentResult.finished=1;
- }
- if (studentResult.startTime<=0)
- {
- studentResult.startTime=DateTimeOffset.Now.ToUnixTimeMilliseconds();
- }
- _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationStudentResult>().Update(studentResult);
- return Ok(new { code = 200, studentResult = studentResult });
- }
- else {
- return Ok(new { msg = "未找到该学生的作答信息。", code = 404});
- }
- }
- /// <summary>
- /// 登录
- /// </summary>
- /// <param name="json"></param>
- /// <returns></returns>
- [HttpPost("login")]
- public IActionResult Login(JsonNode json)
- {
- string studentId = $"{json["studentId"]}";
- string studentName = $"{json["studentName"]}";
- string evaluationId = $"{json["evaluationId"]}";
- string settingId = $"{json["settingId"]}";
- EvaluationRoundSetting? setting = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationRoundSetting>().FindOne(x => x.id!.Equals(settingId) && evaluationId.Equals(x.evaluationId) && x.activate==1);
- EvaluationClient? evaluationClient = null;
- if (setting!=null)
- {
- evaluationClient = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationClient>().FindOne(x => x.id!.Equals(setting.evaluationId));
- if (evaluationClient!=null)
- {
- //检查是否在作答时间内
- (code, msg)= CheckActivate(evaluationClient, setting);
- if (code==200)
- {
- long time = DateTimeOffset.Now.ToUnixTimeMilliseconds();
- _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server);
- School? school = null;
- ///获取名单文件,解析信息,应该在设置开考轮次的时候进行解析,并放在数据库中,并且在此时看是否是需要 分配试卷,还是在登录的时候获取试卷。
- if (server!=null)
- {
- school = server.school;
- }
- EvaluationMember? member = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationMember>().FindOne(x => studentId.Equals(x.id)&& studentName.Equals(x.name));
- if (member!=null)
- {
- if (evaluationId.Equals(member.evaluationId))
- {
- string x_auth_token = JwtAuthExtension.CreateAuthToken("www.teammodel.cn", studentId, studentName, picture: string.Empty, ExamConstant.JwtSecretKey, ExamConstant.ScopeStudent, 8, schoolID: school?.id, new string[] { "student" },expire: 1, year: member.year);
- return Ok(new { code = 200, x_auth_token = x_auth_token });
- }
- else
- {
- return Ok(new { msg = "当前考试未添加该学生!", code = 7 });
- }
- }
- else
- {
- return Ok(new { msg = "学者账号和姓名不匹配!", code = 1 });
- }
- }
- else {
- return Ok(new { msg = msg, code = code });
- }
- }
- else {
- return Ok(new { msg = "未找到考试设置。", code = 6 });
- }
- }
- else {
- return Ok(new { msg = "未找到考试设置。", code = 2 });
- }
- }
- /// <summary>
- /// 学生端获取激活的考试
- /// </summary>
- /// <param name="json"></param>
- /// <returns></returns>
- [HttpPost("get-activate-evaluation")]
- public IActionResult GetActivateEvaluation(JsonNode json)
- {
- // _connectionService.serverDevice.school.id?
- try
- {
- IEnumerable<EvaluationRoundSetting>? settings = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationRoundSetting>().Find(x =>x.activate==1 );
- if (settings != null && settings.Count() > 0)
- {
- if (settings.Count()>1)
- {
- msg="有多个正在开考的评测,请监考教师重新设置开考评测。";
- code=2;
- }
- else
- {
- EvaluationRoundSetting? setting = settings.First(); ;
- EvaluationClient evaluationClient = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationClient>().FindOne(x => x.id ==setting.evaluationId);
- if (evaluationClient!=null)
- {
- (code ,msg)= CheckActivate(evaluationClient, setting);
- var anonymousObject = new Dictionary<string, object?>();
- var properties = evaluationClient.GetType().GetProperties();
- foreach (var property in properties)
- {
- if (!property.Name.Equals("shortCode") && !property.Name.Equals("openCode"))
- {
- anonymousObject[property.Name] = property.GetValue(evaluationClient);
- }
- }
- return Ok(new { evaluationClient = anonymousObject, code = code, msg = msg, setting });
- }
- else
- {
- msg="未找到评测信息。";
- code=6;
- }
- //foreach (var subject in evaluationClient.subjects)
- //{
- // foreach (var paper in subject.papers)
- // {
- // paper.blob=$"package/{evaluationClient.id}/papers/{paper.paperId}";
- // }
- //}
-
- }
- }
- else
- {
- msg="暂无正在开考的评测";
- code=1;
- }
- }
- catch (Exception ex) { }
- return Ok(new { msg ,code});
- }
- private (int code, string msg) CheckActivate(EvaluationClient evaluationClient, EvaluationRoundSetting setting)
- {
- code = 200;
- if (evaluationClient.scope!.Equals("school"))
- {
- if (!evaluationClient!.ownerId!.Equals($"{_connectionService.serverDevice?.school?.id}"))
- {
- msg="授权学校与评测归属学校不一致。";
- code=3;
- }
- }
- //当前时间
- long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
- //if (setting.countdownType>0)
- //{
-
- //}
- //else
- //{
-
- //}
- if ((setting.startline>0 &&setting.startline>now) || evaluationClient.stime>now)
- {
- msg="评测暂未开始。";
- code=4;
- }
- if ((setting.deadline>0 && setting.deadline<now)|| evaluationClient.etime<now)
- {
- msg="评测已经结束。";
- code=5;
- }
- return (code, msg);
- }
-
- }
- }
|