|
@@ -4,6 +4,7 @@ using System.Linq;
|
|
|
using System.Threading.Tasks;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using TEAMModelOS.Models;
|
|
|
+using TEAMModelOS.SDK.Context.Exception;
|
|
|
using TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest;
|
|
|
using TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse;
|
|
|
using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
|
|
@@ -38,23 +39,23 @@ namespace TEAMModelOS.Controllers
|
|
|
if (string.IsNullOrEmpty(request.@params.id))
|
|
|
{
|
|
|
request.@params.id = Guid.NewGuid().ToString();
|
|
|
- request.@params.state = 100;
|
|
|
+ request.@params.status = 100;
|
|
|
// await cosmosDBV3Repository.SaveOrUpdate(request.@params);
|
|
|
}
|
|
|
if (request.@params.publish.Equals("0"))
|
|
|
{
|
|
|
request.@params.startTime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
|
|
|
- request.@params.state = 200;
|
|
|
+ request.@params.status = 200;
|
|
|
}
|
|
|
else if (request.@params.publish.Equals("1"))
|
|
|
{
|
|
|
//设定开始时间
|
|
|
// _timerWorkService.TimerWork<ExamInfo>(request.@params.startTime, 200, new Dictionary<string, object> { { "id", request.@params.id } });
|
|
|
}
|
|
|
- if (request.@params.state == 0)
|
|
|
+ if (request.@params.status == 0)
|
|
|
{
|
|
|
- if (request.@params.startTime < new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds()) request.@params.state = 200;
|
|
|
- else request.@params.state = 100;
|
|
|
+ if (request.@params.startTime < new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds()) request.@params.status = 200;
|
|
|
+ else request.@params.status = 100;
|
|
|
}
|
|
|
await cosmosDBV3Repository.SaveOrUpdate(request.@params);
|
|
|
//设定结束时间
|
|
@@ -90,10 +91,184 @@ namespace TEAMModelOS.Controllers
|
|
|
else {
|
|
|
return builder.build();
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
-
|
|
|
+ /// <summary>
|
|
|
+ /// 教师阅卷
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="request"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpPost("marking")]
|
|
|
+ public async Task<BaseJosnRPCResponse> Marking(JosnRPCRequest<ExamRecord> request)
|
|
|
+ {
|
|
|
+ JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
|
|
|
+ //判断是否每一个题目都有分数
|
|
|
+ List<ExamInfo> exams = await cosmosDBV3Repository.FindByDict<ExamInfo>(new Dictionary<string, object> { { "id", request.@params.examCode } });
|
|
|
+
|
|
|
+ if (exams.IsNotEmpty())
|
|
|
+ {
|
|
|
+ ExamInfo examInfo = exams[0];
|
|
|
+ //提交答案时间必须是状态已发布,且时间在起止时间内
|
|
|
+ if ( examInfo.status == 300 &&
|
|
|
+ examInfo.endTime <= new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds())
|
|
|
+ {
|
|
|
+ return builder.Data(await cosmosDBV3Repository.SaveOrUpdate(request.@params)).build();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ throw new BizException("请在作答时间段内提交答案!", ResponseCode.FAILED);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ throw new BizException("考试不存在!", ResponseCode.DATA_EXIST);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 学生回答问题
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="request"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpPost("answer")]
|
|
|
+ public async Task<BaseJosnRPCResponse> Answer(JosnRPCRequest<ExamRecord> request)
|
|
|
+ {
|
|
|
+ JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
|
|
|
+ //要先处理状态,判断卷子是否存在,并判断卷子归属的考试是否允许再次提交
|
|
|
+ List<ExamInfo> exams= await cosmosDBV3Repository.FindByDict<ExamInfo>(new Dictionary<string, object> { { "id", request.@params.examCode } });
|
|
|
+ if (exams.IsNotEmpty())
|
|
|
+ {
|
|
|
+ ExamInfo examInfo = exams[0];
|
|
|
+ //提交答案时间必须是状态已发布,且时间在起止时间内
|
|
|
+ if (examInfo.startTime <= new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds() && examInfo.status == 200 &&
|
|
|
+ examInfo.endTime >= new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds())
|
|
|
+ {
|
|
|
+ return builder.Data(await cosmosDBV3Repository.SaveOrUpdate(request.@params)).build();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ throw new BizException("请在作答时间段内提交答案!", ResponseCode.FAILED);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ throw new BizException("考试不存在!", ResponseCode.DATA_EXIST);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 查询作答摘要信息
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="request"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpPost("findSummaryRecord")]
|
|
|
+ public async Task<BaseJosnRPCResponse> findSummaryRecord(JosnRPCRequest<Dictionary<string,object>> request)
|
|
|
+ {
|
|
|
+ JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
|
|
|
+ // 如果只有学生id则返回学生参加过的考试 只返回相关摘要信息
|
|
|
+ if (request.@params.Keys.Count == 1 && request.@params.ContainsKey("code"))
|
|
|
+ {
|
|
|
+ List<string> props = new List<string> { "id", "code", "examCode", "status", "mark", "score" };
|
|
|
+ List<ExamRecord> examRecords = await cosmosDBV3Repository.FindByDict<ExamRecord>(request.@params, props);
|
|
|
+ return builder.Data(examRecords).Extend(new Dictionary<string, object> { { "props", props } }).build();
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if (request.@params.ContainsKey("examCode"))
|
|
|
+ {
|
|
|
+ List<string> props = new List<string> { "id", "code", "examCode", "status", "mark", "score" };
|
|
|
+ List<ExamRecord> examRecords = await cosmosDBV3Repository.FindByDict<ExamRecord>(request.@params, props);
|
|
|
+ return builder.Data(examRecords).Extend(new Dictionary<string, object> { { "props", props } }).build();
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ throw new BizException("参数错误",ResponseCode.PARAMS_ERROR);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// 查询单个作答信息 试卷id ,
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="request"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpPost("findByIdPk")]
|
|
|
+ public async Task<BaseJosnRPCResponse> findByIdPk(JosnRPCRequest<IdPk> request)
|
|
|
+ {
|
|
|
+ JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
|
|
|
+ ExamRecord record = await cosmosDBV3Repository.FindByIdPk<ExamRecord>(request.@params.id,request.@params.pk);
|
|
|
+ if (record != null) {
|
|
|
+ //处理客观题自动阅卷
|
|
|
+ Paper paper = await cosmosDBV3Repository.FindByIdPk<Paper>(record.id, record.examCode);
|
|
|
+ if (paper.markConfig != null && paper.markConfig.auto) {
|
|
|
+ autoMark(paper.item, paper.answers, record.answers, paper.markConfig);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return builder.Data(record).build();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void autoMark(List<ItemInfo> items ,List<Answer> stdAnswers, List<Answer> stuAnswers ,MarkConfig markConfig) {
|
|
|
+ int size = stuAnswers.Count;
|
|
|
+ for (int i = 0; i < size; i++) {
|
|
|
+ //客观题
|
|
|
+ if (stuAnswers[i].type.Equals("Single") || stuAnswers[i].type.Equals("Multiple") || stuAnswers[i].type.Equals("Judge")) {
|
|
|
+ //多选题单独处理
|
|
|
+ if (stuAnswers[i].type.Equals("Multiple"))
|
|
|
+ {
|
|
|
+ List<string> stuAns = stuAnswers[i].ans;
|
|
|
+ Answer stdAnswer = stdAnswers.Where(x =>x.num== stuAnswers[i].num).FirstOrDefault();
|
|
|
+ if (stdAnswer != null) {
|
|
|
+ //处理多选答案是否有选错的 选错的则直接0分 ,如果少选则处理部分分数
|
|
|
+ bool right = true;
|
|
|
+ List<string> rightStr = new List<string>();
|
|
|
+ if (stuAns.IsNotEmpty())
|
|
|
+ {
|
|
|
+ foreach (string stuAn in stuAns)
|
|
|
+ {
|
|
|
+ if (!stdAnswer.ans.Contains(stuAn))
|
|
|
+ {
|
|
|
+ right = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ rightStr.Add(stuAn);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ right = false;
|
|
|
+ }
|
|
|
+ if (right && rightStr.IsNotEmpty() && rightStr.Count != stdAnswer.ans.Count)
|
|
|
+ {
|
|
|
+
|
|
|
+ if (markConfig.type == 1)
|
|
|
+ {
|
|
|
+ //1多选漏选不得分
|
|
|
+ stuAnswers[i].score = 0;
|
|
|
+ }
|
|
|
+ else if(markConfig.type==3){
|
|
|
+ stuAnswers[i].score=Math.Floor((double)(1.0 * rightStr.Count / stdAnswer.ans.Count * stdAnswer.score));
|
|
|
+ if (stuAnswers[i].score == 0) {
|
|
|
+ stuAnswers[i].score = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (markConfig.type == 4)
|
|
|
+ {
|
|
|
+ stuAnswers[i].score = markConfig.score;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ { //2多选漏选得一半的分数(默认)
|
|
|
+ stuAnswers[i].score = stdAnswer.score/2;
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ //选错不得分
|
|
|
+ stuAnswers[i].score = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
/// <summary>
|
|
|
/// 生成题目
|
|
|
/// </summary>
|