using Tiobon.Core.IServices; using Tiobon.Core.Model.Models; using Tiobon.Core.Services.BASE; using Tiobon.Core.IRepository.Base; using Tiobon.Core.Common.Caches; using Newtonsoft.Json.Linq; using Tiobon.Core.Common; using Tiobon.Core.Model; using Newtonsoft.Json; using System.Text.RegularExpressions; using System.Net; using Tiobon.Core.Common.Helper; using AgileObjects.AgileMapper.Extensions; using SqlSugar; using Tiobon.Core.DataAccess; using System.Data; using static Tiobon.Core.Model.Consts; using Mysqlx.Crud; using MongoDB.Driver.Linq; namespace Tiobon.Core.Services; /// /// 考试记录 (服务) /// public class Ghre_ExamRecordServices : BaseServices, IGhre_ExamRecordServices { private readonly IBaseRepository _dal; //private readonly IGhre_ExamPaperServices _ghre_ExamPaperServices; public Ghre_ExamRecordServices(ICaching caching, //IGhre_ExamPaperServices ghre_ExamPaperServices, IBaseRepository dal) { this._dal = dal; base.BaseDal = dal; base._caching = caching; //_ghre_ExamPaperServices = ghre_ExamPaperServices; } public override async Task> QueryFilterPage(QueryBody filter, string condition, bool? IsEnable = true) { if (string.IsNullOrWhiteSpace(filter.orderBy)) filter.orderBy = "CreateTime1 DESC"; if (filter.pageSize == 0) filter.pageSize = 10000; var countSql = @$" SELECT COUNT(1) FROM Ghre_ExamRecord_V"; var sql = @$" SELECT * FROM Ghre_ExamRecord_V"; string conditions = " WHERE IsEnable = 1"; if (!string.IsNullOrEmpty(condition)) conditions += " AND " + condition; if (filter.jsonParam != null) foreach (JProperty jProperty in filter.jsonParam.Properties()) { var name = jProperty.Name; var value = jProperty.Value.ToString(); if (name == "page" || name == "pageSize") continue; if (name == "DueDate") { var jsonParam = JsonConvert.DeserializeObject(value); conditions += $" AND FORMAT(DueDate, 'yyyy-MM-dd') = '{jsonParam.columnValue}'"; continue; } if (!string.IsNullOrWhiteSpace(value)) { var jsonParam = JsonConvert.DeserializeObject(value); switch (jsonParam.operationKey) { case "Include": conditions += $" AND {name} LIKE '%{jsonParam.columnValue}%'"; break; case "NotInclude": conditions += $" AND {name} NOT LIKE '%{jsonParam.columnValue}%'"; break; case "IsNull": conditions += $" AND {name} IS NULL"; break; case "NotNull": conditions += $" AND {name} IS NOT NULL"; break; case "Equal": conditions += $" AND {name} ='{jsonParam.columnValue}'"; break; case "NotEqual": conditions += $" AND {name} !='{jsonParam.columnValue}'"; break; default: break; } } } sql += conditions; countSql += conditions; int total = await Db.Ado.GetIntAsync(countSql); sql = "SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY " + filter.orderBy + ") NUM FROM (SELECT * FROM (" + sql + " "; sql += ") A ) B ) C"; sql += " WHERE NUM <= " + filter.pageNum * filter.pageSize + " AND NUM >" + (filter.pageNum - 1) * filter.pageSize; var entitys = await Db.Ado.SqlQueryAsync(sql); entitys.ForEach(async x => { x.ScoreMethodLabel = await GetParaLabel("ScoreMethod", x.ScoreMethod); x.ScoreStatus = await GetParaLabel("TrainingExamScoreStatus", x.ScoreStatus); //x.CourseStatusLabel = await GetParaLabel("TrainingCourseStatus", x.CourseStatus); //x.StudyStatusLabel = await GetParaLabel("TrainingStudyStatus", x.StudyStatus); x.IsPassLabel = x.IsPass == true ? "合格" : "不合格"; //x.InStatusLabel = x.InStatus == "1" ? "在职" : null; //x.InStatusLabel = x.InStatus == "2" ? "离职" : null; //x.InStatusLabel = x.InStatus == "0" ? "未入职" : null; if (x.BeginTime != null) x.ExamDate = x.BeginTime.Value.ToString("yyyy-MM-dd"); x.TotalScore += x.Score ?? 0; x.TotalScore += x.AdjustScore ?? 0; //if (x.DueDate != null) // x.DueDate1 = x.DueDate.Value.ToString("yyyy-MM-dd"); //if (x.ExamDate != null) // x.ExamDate1 = x.ExamDate.Value.ToString("yyyy-MM-dd"); }); return new ServicePageResult(filter.pageNum, total, filter.pageSize, entitys); } public async Task> Query(string examId, QueryBody body) { return await QueryFilterPage(body, $"ExamId='{examId}'"); } public async Task ModifyAdjustScore(string examRecordId, EditGhre_ExamRecordInput edit) { var entity = await QuerySingle(examRecordId); var paper = await Db.Queryable().FirstAsync(x => x.Id == entity.ExamPaperId); if (paper == null) return ServiceResult.OprateFailed("该考试管理的试卷已被删除,暂不可变更调整分!"); entity.AdjustScore = edit.AdjustScore; //entity.Score += entity.AdjustScore; string score1 = Regex.Replace(entity.Score.ToString(), @"\.(0+)$", "") + "/" + Regex.Replace(entity.Score.ToString(), @"\.(0+)$", ""); if (entity.Score < 0) return ServiceResult.OprateFailed($"调整后得分为【{score1}】,得分不可小于0!"); if (entity.Score > paper.TotalScore) return ServiceResult.OprateFailed($"调整后得分为【{score1}】,不可大于卷面总分【{Regex.Replace(paper.TotalScore.ToString(), @"\.(0+)$", "") + "/" + Regex.Replace(paper.TotalScore.ToString(), @"\.(0+)$", "")}】!"); var paperId = entity.ExamPaperId; var examPaper = await Db.Queryable().Where(x => x.Id == paperId).FirstAsync(); if (examPaper != null) entity.IsPass = examPaper.PassScore > (entity.Score + entity.AdjustScore) ? false : true; await Update(entity); return ServiceResult.OprateSuccess("修改成功!"); //return await QueryFilterPage(body, $"ExamId='{examId}'"); } public async Task> ExtendAsync(long examRecordId) { var extend = new Ghre_ExamRecordExtend(); var record = await QuerySingle(x => x.Id == examRecordId); var details = await Db.Queryable().Where(x => x.ExamRecordId == record.Id).ToListAsync(); var detailIds = details.Select(x => x.Id).ToList(); var recordAnswers = await Db.Queryable() .OrderBy(x => x.TaxisNo) .Where(x => x.ExamRecordDetailId != null && detailIds.Contains(x.ExamRecordDetailId.Value)) .ToListAsync(); if (record.ScoreStatus == Consts.DIC_EXAM_RECORD_SCORE_STATUS.NO_SCORE) await ExamHelper.SystemMarkAsync(Db, record, details, recordAnswers); var exampaper = await Db.Queryable().FirstAsync(x => x.Id == record.ExamPaperId); var baseData = new DefaultGhre_ExamPaperBaseData(); baseData.PaperNo = exampaper.PaperNo; baseData.PaperName = exampaper.PaperName; baseData.AnswerTime = exampaper.AnswerTime; baseData.ScoreMethod = exampaper.ScoreMethod; baseData.TotalScore = exampaper.TotalScore; baseData.PassScore = exampaper.PassScore; baseData.RetakeTimes = exampaper.RetakeTimes; baseData.RemarkSz = exampaper.RemarkSz; baseData.LinkType = exampaper.LinkType; baseData.CourseId = exampaper.LinkType == "CourseId" ? exampaper.LinkId : null; baseData.CourseSceneId = exampaper.LinkType == "CourseSceneId" ? exampaper.LinkId : null; extend.baseData = baseData; extend.styleInfo.coverImage = exampaper.CoverUrl; extend.styleInfo.paperStyle = exampaper.Style; extend.styleInfo.coverBackGround = exampaper.CoverBackGround; var questions = await Db.Queryable() //.Where(x => x.ExamPaperId == exampaper.Id) .Where(x => (x.ExamPaperId == exampaper.Id && exampaper.SetMethod == DIC_EXAM_PAPER_SET_METHOD.MANUAL) || (x.ExamPaperId == examRecordId && exampaper.SetMethod == DIC_EXAM_PAPER_SET_METHOD.RANDOM)) .ToListAsync(); var previews = questions.Where(x => x.QuestionId != null).Select(x => new DefaultGhre_ExamPaperPreview() { Id = x.Id, ConfigId = x.ConfigId, parentId = x.ConfigId, QuestionId = x.QuestionId.Value, ExamPaperId = x.ExamPaperId, Score = x.Score, RealScore = details.Where(m => m.QuestionId == x.QuestionId).Sum(m => (m.Score ?? 0) + (m.AdjustScore ?? 0)) }).ToList(); var questionIds = previews.Select(x => x.QuestionId).Distinct().ToList(); var questions1 = await Db.Queryable().Where(x => questionIds.Contains(x.Id)).ToListAsync(); var answers = await Db.Queryable().Where(x => x.QuestionId != null && questionIds.Contains(x.QuestionId.Value)).OrderBy(x => x.TaxisNo).ToListAsync(); ; previews.ForEach(x => { var answers1 = answers.Where(y => y.QuestionId == x.QuestionId).ToList(); x.QuestionType = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.QuestionType; x.QuestionContent = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.QuestionContent; if (!string.IsNullOrEmpty(x.QuestionContent)) x.QuestionContent = WebUtility.HtmlDecode(x.QuestionContent); var detail = new FromGhre_QuestionQuestionTypeDetail(); detail.content = x.QuestionContent; detail.difficulty = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.DifficultyLevel; detail.answer = answers1.Where(x => x.IsCorrect == true).FirstOrDefault()?.QuestionNo; detail.answer1 = answers1.Where(x => x.IsCorrect == true).Select(x => x.QuestionNo).ToList(); detail.answerList = answers1.Select(x => new FromGhre_QuestionQuestionAnswerList() { No = x.QuestionNo, label = x.AnswerContent, imageUrl = x.ImageUrl, imgWidthPc = x.ImageWidthPc, imgWidthApp = x.ImageWidthApp, }).ToList(); detail.RemarkSz = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.QuestionAnalysis; x.detail = detail; var recordDetail = details.FirstOrDefault(m => m.ExamPaperQuestionId == x.Id); switch (x.QuestionType) { case "Completion": case "ShortAnswer": var answerIds1 = recordAnswers.Where(m => m.ExamRecordDetailId == recordDetail?.Id && m.QuestionAnswerId == null).Select(m => m.AnswerContent).ToList(); answerIds1.ForEach(m => { x.value1.Add(m); }); if (x.value1.Any()) x.value = x.value1.First(); break; default: var answerIds = recordAnswers.Where(m => m.ExamRecordDetailId == recordDetail?.Id && m.QuestionAnswerId != null).Select(m => m.QuestionAnswerId).ToList(); answers1.Where(m => answerIds.Contains(m.Id)).ForEach(m => { x.value1.Add(m.QuestionNo); }); if (x.value1.Any()) x.value = x.value1.First(); break; } }); extend.questionList = previews; string sql = @$"SELECT StaffNo, StaffName, dbo.FO_DeptInfo (DeptID, getdate (), 1, 'DeptNo') DeptNo, dbo.FO_DeptInfo (DeptID, getdate (), 1, 'DeptFullPateName') DepteName FROM Ghra_Staff WHERE StaffID = {record.StaffId}"; extend.StaffInfo = await Db.Ado.SqlQuerySingleAsync(sql); extend.StaffInfo.StaffScore = record.Score != null ? record.Score.Value : 0; sql = @$"SELECT A.StaffNo, A.StaffName, dbo.FO_DeptInfo (A.DeptID, getdate (), 1, 'DeptNo') DeptNo, dbo.FO_DeptInfo (A.DeptID, getdate (), 1, 'DeptFullPateName') DepteName, A.PhotoUrl, B.TitleName FROM Ghra_Staff A LEFT JOIN Ghra_Title B ON B.TitleID = A.TitleID WHERE A.StaffID = {record.StaffId}"; extend.CommentData = await Db.Ado.SqlQuerySingleAsync(sql); if (record.ScoreStatus == Consts.DIC_EXAM_RECORD_SCORE_STATUS.NO_SCORE) extend.CommentData.IsFirstTime = true; extend.CommentData.Comment = record.Comment; var body = new QueryBody(); body.pageNum = 1; body.pageSize = 10000; var records = await QueryFilterPage(body, $"ExamId='{record.ExamId}'"); var records1 = records.result.DT_TableDataT1; int index = records1.FindIndex(x => x.Id == examRecordId); extend.PreviousRecordId = index - 1 >= 0 && records1.Count > 1 ? records1[index - 1].Id : null; extend.NextRecordId = records1.Count > index + 1 ? records1[index + 1].Id : null; return ServiceResult.OprateSuccess("查询成功!", extend); } public async Task CommentAsync(Ghre_ExamRecordExtend extend, long examRecordId) { var record = await QuerySingle(x => x.Id == examRecordId); record.Score = extend.StaffInfo.StaffScore; record.ScoreStatus = Consts.DIC_EXAM_RECORD_SCORE_STATUS.HAS_SCORE; record.Comment = extend.CommentData.Comment; var details = await Db.Queryable().Where(x => x.ExamRecordId == record.Id).ToListAsync(); extend.questionList.ForEach(x => { var recordDetail = details.FirstOrDefault(m => m.ExamPaperQuestionId == x.Id); recordDetail.Score = x.RealScore; recordDetail.IsCorrect = x.Score == x.RealScore ? true : false; }); var paperId = record.ExamPaperId; var examPaper = await Db.Queryable().Where(x => x.Id == paperId).FirstAsync(); if (examPaper != null) record.IsPass = examPaper.PassScore > (record.Score + record.AdjustScore) ? false : true; await Db.Updateable(record).ExecuteCommandAsync(); await Db.Updateable(details).ExecuteCommandAsync(); return ServiceResult.OprateSuccess("提交成功!"); } public async Task> QueryExamAsync(long id) { var extend = new QueryExam(); var body = new QueryBody(); body.pageNum = 1; body.pageSize = 10000; var staffId = GetStaffId(); long? examRecordId = null; Ghre_StudyRecord studyRecord = null; if (await Db.Queryable().AnyAsync(x => x.Id == id)) { studyRecord = await Db.Queryable().FirstAsync(x => x.ExamId == id && x.StaffId == staffId); if (studyRecord != null) id = studyRecord.Id; } Ghre_Exam exam = null; if (await Db.Queryable().AnyAsync(x => x.Id == id && x.StaffId == staffId)) { var examRecord = await Db.Queryable().FirstAsync(x => x.StudyRecordId == id && x.StaffId == staffId); if (!examRecord.IsNull()) examRecordId = examRecord.Id; else { studyRecord = await Db.Queryable().FirstAsync(x => x.Id == id && x.StaffId == staffId); exam = await Db.Queryable() .Where(x => x.Id == studyRecord.ExamId) .FirstAsync(x => x.Status == Consts.DIC_EXAM_STATUS.RELEASED); if (exam.IsNull()) exam = await Db.Queryable() .Where(x => x.Status == Consts.DIC_EXAM_STATUS.RELEASED && ((x.DateType == Consts.DicExamDateType.EXAM_DATE && x.BeginTime.Value.Date <= DateTime.Now.Date && x.EndTime.Value.Date >= DateTime.Now.Date) || x.DateType == Consts.DicExamDateType.AFTER_HOW_LONG)) .WhereIF(!studyRecord.CourseId.IsNull(), x => x.CourseId == studyRecord.CourseId) .WhereIF(!studyRecord.CourseSceneId.IsNull(), x => x.CourseSceneId == studyRecord.CourseSceneId) .FirstAsync(); if (exam.IsNull()) return ServiceResult.OprateFailed("该门课程尚未开启考试,请联系HR !"); var insrt = new InsertGhre_ExamRecordInput() { ExamId = exam.Id, StudyRecordId = studyRecord.Id, StaffId = studyRecord.StaffId, CourseSnapId = studyRecord.CourseSnapId, ExamPaperId = exam.ExamPaperId, ExamDate = DateTime.Now.Date, RetakeTimes = 0, Status = Consts.DIC_EXAM_RECORD_STATUS.WAIT, ScoreStatus = Consts.DIC_EXAM_RECORD_SCORE_STATUS.NO_SCORE, BeginTime = exam.BeginTime, EndTime = exam.EndTime }; examRecordId = await base.Add(insrt); if (studyRecord.ExamId.IsNull()) { string sql = $@"UPDATE Ghre_StudyRecord SET ExamId={exam.Id} WHERE Id='{studyRecord.Id}'; "; await Db.Ado.ExecuteCommandAsync(sql); } } } if (examRecordId == 0) examRecordId = id; var records = await QueryFilterPage(body, $"Id='{examRecordId}' AND StaffId='{staffId}'"); if (!records.result.DT_TableDataT1.Any()) return ServiceResult.OprateFailed("无效的考试链接!"); var record = records.result.DT_TableDataT1.FirstOrDefault(); if (studyRecord.IsNull()) studyRecord = await Db.Queryable().FirstAsync(x => x.Id == record.StudyRecordId); if (studyRecord.StudyProgress.IsNull() || (!studyRecord.StudyProgress.IsNull() && studyRecord.StudyProgress < 100)) return ServiceResult.OprateFailed("学习尚未结束暂不可考试!"); if (exam.IsNull()) exam = await Db.Queryable() .Where(x => x.Id == studyRecord.ExamId) .FirstAsync(x => x.Status == Consts.DIC_EXAM_STATUS.RELEASED); if (exam.IsNull()) return ServiceResult.OprateFailed("该门课程尚未开启考试,请联系HR !"); var dt = Db.GetDate(); if (exam.DateType == Consts.DicExamDateType.AFTER_HOW_LONG) { record.BeginTime = studyRecord?.EndTime; if (!record.BeginTime.IsNull()) record.EndTime = record.BeginTime.Value.AddDays(exam.AfterHowLong ?? 7); } if (!(record.BeginTime.Value.Date <= dt.Date && record.EndTime.Value.Date >= dt.Date)) return ServiceResult.OprateFailed("考试已结束!"); var details = await Db.Queryable().Where(x => x.ExamRecordId == record.Id).ToListAsync(); var detailIds = details.Select(x => x.Id).ToList(); var recordAnswers = await Db.Queryable() .OrderBy(x => x.TaxisNo) .Where(x => x.ExamRecordDetailId != null && detailIds.Contains(x.ExamRecordDetailId.Value)) .ToListAsync(); //if (record.ScoreStatus == "NoScore") // await ExamHelper.SystemMarkAsync(Db, record, details, recordAnswers); var exampaper = await Db.Queryable().FirstAsync(x => x.Id == record.ExamPaperId); var baseData = new DefaultGhre_ExamPaperBaseData(); baseData.PaperNo = exampaper.PaperNo; baseData.PaperName = exampaper.PaperName; baseData.AnswerTime = exampaper.AnswerTime; baseData.ScoreMethod = exampaper.ScoreMethod; baseData.TotalScore = exampaper.TotalScore; baseData.PassScore = exampaper.PassScore; baseData.RetakeTimes = exampaper.RetakeTimes; baseData.RemarkSz = exampaper.RemarkSz; baseData.LinkType = exampaper.LinkType; baseData.CourseId = exampaper.LinkType == "CourseId" ? exampaper.LinkId : null; baseData.CourseSceneId = exampaper.LinkType == "CourseSceneId" ? exampaper.LinkId : null; extend.baseData = baseData; extend.styleInfo.coverImage = exampaper.CoverUrl; extend.styleInfo.paperStyle = exampaper.Style; extend.styleInfo.coverBackGround = exampaper.CoverBackGround; if (exampaper.SetMethod == DIC_EXAM_PAPER_SET_METHOD.RANDOM && record.Status != DIC_EXAM_RECORD_STATUS.EXAM_END) { await Db.Deleteable().Where(x => x.ExamPaperId == examRecordId).ExecuteCommandAsync(); var configs = await Db.Queryable().OrderBy(x => x.TaxisNo).Where(x => x.ExamPaperId == exampaper.Id).ToListAsync(); for (int i = 0; i < configs.Count; i++) { var config = configs[i]; string sql = $@"SELECT TOP {config.Quantity} *,NEWID() AS GuidValue FROM Ghre_Question WHERE IsEnable=1"; if (!string.IsNullOrWhiteSpace(config.DifficultyLevel)) sql += $" AND DifficultyLevel='{config.DifficultyLevel}'"; if (!string.IsNullOrWhiteSpace(config.QuestionType)) sql += $" AND QuestionType='{config.QuestionType}'"; if (config.CourseId != null) sql += $" AND CourseId='{config.CourseId}'"; if (config.QuestionId != null) sql += $" AND Id='{config.QuestionId}'"; sql += $" ORDER BY GuidValue ASC"; var questions2 = await Db.Ado.SqlQueryAsync(sql); var insertExamPaperQuestions = questions2.Select(x => new Ghre_ExamPaperQuestion { Id = SnowFlakeSingle.instance.getID(), CreateTime = DateTime.Now, ExamPaperId = examRecordId, QuestionId = x.Id, ConfigId = x.Id, Score = config.Score }).ToList(); Db.Insertable(insertExamPaperQuestions).ExecuteCommand(); } } var questions = await Db.Queryable() .Where(x => (x.ExamPaperId == exampaper.Id && exampaper.SetMethod == DIC_EXAM_PAPER_SET_METHOD.MANUAL) || (x.ExamPaperId == examRecordId && exampaper.SetMethod == DIC_EXAM_PAPER_SET_METHOD.RANDOM)) .ToListAsync(); var previews = questions.Where(x => x.QuestionId != null).Select(x => new DefaultGhre_ExamPaperPreview() { Id = x.Id, ConfigId = x.ConfigId, parentId = x.ConfigId, QuestionId = x.QuestionId.Value, ExamPaperId = x.ExamPaperId, Score = x.Score, RealScore = details.Where(m => m.QuestionId == x.QuestionId).Sum(m => (m.Score ?? 0) + (m.AdjustScore ?? 0)) }).ToList(); var questionIds = previews.Select(x => x.QuestionId).Distinct().ToList(); var questions1 = await Db.Queryable().Where(x => questionIds.Contains(x.Id)).ToListAsync(); var answers = await Db.Queryable().Where(x => x.QuestionId != null && questionIds.Contains(x.QuestionId.Value)).OrderBy(x => x.TaxisNo).ToListAsync(); ; previews.ForEach(x => { var answers1 = answers.Where(y => y.QuestionId == x.QuestionId).ToList(); x.QuestionType = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.QuestionType; x.QuestionContent = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.QuestionContent; if (!string.IsNullOrEmpty(x.QuestionContent)) x.QuestionContent = WebUtility.HtmlDecode(x.QuestionContent); var detail = new FromGhre_QuestionQuestionTypeDetail(); detail.content = x.QuestionContent; detail.difficulty = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.DifficultyLevel; //detail.answer = answers1.Where(x => x.IsCorrect == true).FirstOrDefault()?.QuestionNo; //detail.answer1 = answers1.Where(x => x.IsCorrect == true).Select(x => x.QuestionNo).ToList(); detail.answerList = answers1.Select(x => new FromGhre_QuestionQuestionAnswerList() { No = x.QuestionNo, label = x.AnswerContent, imageUrl = x.ImageUrl, imgWidthPc = x.ImageWidthPc, imgWidthApp = x.ImageWidthApp, }).ToList(); x.detail = detail; var recordDetail = details.FirstOrDefault(m => m.ExamPaperQuestionId == x.Id); switch (x.QuestionType) { case "Completion": case "ShortAnswer": var answerIds1 = recordAnswers.Where(m => m.ExamRecordDetailId == recordDetail?.Id && m.QuestionAnswerId == null).Select(m => m.AnswerContent).ToList(); answerIds1.ForEach(m => { x.value1.Add(m); }); if (x.value1.Any()) x.value = x.value1.First(); break; default: var answerIds = recordAnswers.Where(m => m.ExamRecordDetailId == recordDetail?.Id && m.QuestionAnswerId != null).Select(m => m.QuestionAnswerId).ToList(); answers1.Where(m => answerIds.Contains(m.Id)).ForEach(m => { x.value1.Add(m.QuestionNo); }); if (x.value1.Any()) x.value = x.value1.First(); break; } }); extend.questionList = previews; extend.StaffNo = record.StaffNo; extend.StaffName = record.StaffName; extend.DeptNo = record.StaffNo; extend.DeptName = record.DepteName; extend.StaffPhoto = record.StaffPhotoUrl; extend.ExamName = record.ExamName + "(" + record.ExamNo + ")"; extend.ExamBeginDate = DateTimeHelper.ConvertToDayString(record.BeginTime); extend.ExamEndDate = DateTimeHelper.ConvertToDayString(record.EndTime); extend.ExamStatus = record.Status; extend.TotalScore = record.TotalScore; extend.Id = record.Id; extend.CourseName = record.CourseName; extend.CanRetake = true; extend.ScoreOut = false; if ((record.RetakeTimes ?? 0) >= (exampaper.RetakeTimes ?? 0)) extend.CanRetake = false; //TimeSpan timeDifference = record.EndTime.Value - DateTime.Now; //extend.RemainingSecond = Convert.ToInt32(timeDifference.TotalSeconds); //if (extend.RemainingSecond < 0) extend.RemainingSecond = 0; extend.RemainingSecond = 3600; if (!exampaper.AnswerTime.IsNull()) extend.RemainingSecond = exampaper.AnswerTime.Value * 60; #region 更新实际开始时间 if (extend.ExamStatus != Consts.DIC_EXAM_RECORD_STATUS.EXAM_END) { string sql = $"UPDATE Ghre_ExamRecord SET ActualBeginTime = GETDATE() WHERE Id={examRecordId}"; await Db.Ado.ExecuteCommandAsync(sql); } #endregion if (!record.ActualEndTime.IsNull()) { TimeSpan timeDifference = record.ActualEndTime.Value - record.ActualBeginTime.Value; extend.UsageTime = $"{timeDifference.Minutes}分{timeDifference.Seconds}秒"; } if (record.IsView == true) extend.CanRetake = false; if (exampaper.ScoreMethod == DIC_EXAM_PAPER_SCORE_METHOD.MANUAL && record.ScoreStatus == Consts.DIC_EXAM_RECORD_SCORE_STATUS.NO_SCORE) { extend.ScoreOut = true; extend.ScoreOutTime = "等待人工阅卷"; extend.IsAllowView = false; } return ServiceResult.OprateSuccess("查询成功!", extend); } public async Task StartExamAsync(long examRecordId) { var entity = await base.QuerySingle(examRecordId); if (entity is null) return ServiceResult.OprateFailed("无效的考试ID!"); var exam = await Db.Queryable() .Where(x => x.Id == entity.ExamId) .FirstAsync(x => x.Status == Consts.DIC_EXAM_STATUS.RELEASED); var studyRecord = await Db.Queryable().FirstAsync(x => x.Id == entity.StudyRecordId); if (exam.DateType == Consts.DicExamDateType.AFTER_HOW_LONG) { entity.BeginTime = studyRecord?.EndTime; if (!entity.BeginTime.IsNull()) entity.EndTime = entity.BeginTime.Value.AddDays(exam.AfterHowLong ?? 7); } var dt = Db.GetDate(); if (!(entity.BeginTime.Value.Date <= dt.Date && entity.EndTime.Value.Date >= dt.Date)) return ServiceResult.OprateFailed("考试已结束!"); #region 试卷 引用次数 if (entity.Status == Consts.DIC_EXAM_RECORD_STATUS.WAIT) { string sql = $"UPDATE Ghre_ExamPaper SET LinkTimes = ISNULL(LinkTimes, 0)+1 WHERE Id={entity.ExamPaperId}"; await Db.Ado.ExecuteCommandAsync(sql); } #endregion if (entity.ActualBeginTime is null) entity.ActualBeginTime = DateTime.Now; if (entity.Status == Consts.DIC_EXAM_RECORD_STATUS.WAIT) entity.Status = Consts.DIC_EXAM_RECORD_STATUS.EXAMING; await Update(entity, new List() { "ActualBeginTime", "Status" }); return ServiceResult.OprateSuccess("成功!"); } public async Task RetakeExamAsync(long examRecordId) { var entity = await base.QuerySingle(examRecordId); if (entity is null) return ServiceResult.OprateFailed("无效的考试ID!"); var exampaper = await Db.Queryable().FirstAsync(x => x.Id == entity.ExamPaperId); if ((entity.RetakeTimes ?? 0) >= (exampaper.RetakeTimes ?? 0)) return ServiceResult.OprateFailed($"重考次数已达上限,已重考次数【{entity.RetakeTimes ?? 0}】,允许重考次数【{exampaper.RetakeTimes ?? 0}】!"); if (entity.Status == Consts.DIC_EXAM_RECORD_STATUS.EXAM_END) entity.Status = Consts.DIC_EXAM_RECORD_STATUS.EXAMING; entity.RetakeTimes = entity.RetakeTimes is null ? 1 : entity.RetakeTimes + 1; entity.ScoreStatus = Consts.DIC_EXAM_RECORD_SCORE_STATUS.NO_SCORE; await Update(entity, new List() { "Status","RetakeTimes","ScoreStatus" }); return ServiceResult.OprateSuccess("成功!"); } public async Task AnswerExamAsync(List answers, long studyRecordId) { var record = await base.QuerySingle(x => x.Id == studyRecordId); if (record is null) return ServiceResult.OprateFailed("无效的考试ID"); using var _context = ContextFactory.CreateContext(); var exampaper = await Db.Queryable().FirstAsync(x => x.Id == record.ExamPaperId); var dt = Db.GetDate(); var exam = await Db.Queryable() .Where(x => x.Id == record.ExamId) .FirstAsync(x => x.Status == Consts.DIC_EXAM_STATUS.RELEASED); var studyRecord = await Db.Queryable().FirstAsync(x => x.Id == record.StudyRecordId); if (exam.DateType == Consts.DicExamDateType.AFTER_HOW_LONG) { record.BeginTime = studyRecord?.EndTime; if (!record.BeginTime.IsNull()) record.EndTime = record.BeginTime.Value.AddDays(exam.AfterHowLong ?? 7); } var endTime = record.EndTime.Value.AddDays(1).AddSeconds(9); if (!(record.BeginTime.Value.Date <= dt.Date && record.EndTime.Value.Date >= dt.Date)) return ServiceResult.OprateFailed("考试已结束!"); string sql = $@"UPDATE Ghre_ExamRecordDetail set IsEnable=0 where ExamRecordId='{record.Id}'; UPDATE Ghre_ExamRecordAnswer set IsEnable=0 where ExamRecordId='{record.Id}';"; await Db.Ado.ExecuteCommandAsync(sql); var questionIds = answers.Select(x => x.QuestionId).ToList(); var questionAnswers = await Db.Queryable().Where(x => x.QuestionId != null && questionIds.Contains(x.QuestionId.Value)).OrderBy(x => x.TaxisNo).ToListAsync(); ; var staff = await Db.Queryable().Where(x => x.UserId == App.User.ID).FirstAsync(); var recordDetails = new List(); var recordDetailAnswers = new List(); answers.ForEach(answer => { long id = SnowFlakeSingle.instance.getID(); recordDetails.Add(new Ghre_ExamRecordDetail() { Id = id, CreateTime = DateTime.Now, ExamRecordId = record.Id, ExamPaperId = answer.ExamPaperId, ExamPaperQuestionId = answer.Id, QuestionId = answer.QuestionId, StaffId = staff?.UserStaffID, Score = 0, AdjustScore = 0 }); var questionAnswers1 = questionAnswers.Where(x => x.QuestionId == answer.QuestionId).ToList(); switch (answer.QuestionType) { case "TrueOrFalse": case "Single": recordDetailAnswers.Add(new Ghre_ExamRecordAnswer() { Id = SnowFlakeSingle.instance.getID(), CreateTime = DateTime.Now, ExamRecordDetailId = id, ExamRecordId = record.Id, QuestionAnswerId = answer.value.IsNull() ? null : questionAnswers1.First(x => x.QuestionNo == answer.value)?.Id, }); break; case "Multiple": var TaxisNo = 100; if (answer.value1.IsNull() || (!answer.value1.IsNull() && !answer.value1.Any())) recordDetailAnswers.Add(new Ghre_ExamRecordAnswer() { Id = SnowFlakeSingle.instance.getID(), CreateTime = DateTime.Now, ExamRecordDetailId = id, ExamRecordId = record.Id, AnswerContent = null, TaxisNo = TaxisNo }); else foreach (var value in answer.value1) { recordDetailAnswers.Add(new Ghre_ExamRecordAnswer() { Id = SnowFlakeSingle.instance.getID(), CreateTime = DateTime.Now, ExamRecordDetailId = id, ExamRecordId = record.Id, QuestionAnswerId = value.IsNull() ? null : questionAnswers1.First(x => x.QuestionNo == value)?.Id, TaxisNo = TaxisNo }); TaxisNo += 100; } break; case "Completion": var TaxisNo1 = 100; if (answer.value1.IsNull() || (!answer.value1.IsNull() && !answer.value1.Any())) recordDetailAnswers.Add(new Ghre_ExamRecordAnswer() { Id = SnowFlakeSingle.instance.getID(), CreateTime = DateTime.Now, ExamRecordDetailId = id, ExamRecordId = record.Id, AnswerContent = null, TaxisNo = TaxisNo1 }); else foreach (var value in answer.value1) { recordDetailAnswers.Add(new Ghre_ExamRecordAnswer() { Id = SnowFlakeSingle.instance.getID(), CreateTime = DateTime.Now, ExamRecordDetailId = id, ExamRecordId = record.Id, AnswerContent = value, TaxisNo = TaxisNo1 }); TaxisNo1 += 100; } break; case "ShortAnswer": recordDetailAnswers.Add(new Ghre_ExamRecordAnswer() { Id = SnowFlakeSingle.instance.getID(), CreateTime = DateTime.Now, ExamRecordId = record.Id, ExamRecordDetailId = id, AnswerContent = answer.value }); break; default: break; } }); await _context.Ghre_ExamRecordDetail.AddRangeAsync(recordDetails); await _context.Ghre_ExamRecordAnswer.AddRangeAsync(recordDetailAnswers); await _context.SaveChangesAsync(); record.Status = Consts.DIC_EXAM_RECORD_STATUS.EXAM_END; record.ActualEndTime = DateTime.Now; #region 打分-系统评分 if (record.ScoreStatus == Consts.DIC_EXAM_RECORD_SCORE_STATUS.NO_SCORE && exampaper.ScoreMethod == DIC_EXAM_PAPER_SCORE_METHOD.SYSTEM) { await ExamHelper.SystemMarkAsync(Db, record, recordDetails, recordDetailAnswers); record.ScoreStatus = Consts.DIC_EXAM_RECORD_SCORE_STATUS.HAS_SCORE; _context.Ghre_ExamRecordDetail.UpdateRange(recordDetails); _context.Ghre_ExamRecordAnswer.UpdateRange(recordDetailAnswers); await _context.SaveChangesAsync(); } #endregion await Update(record, new List { "Status", "Score", "ActualEndTime", "ScoreStatus" }, null, $"Id='{record.Id}'"); if (exampaper.ScoreMethod == DIC_EXAM_PAPER_SCORE_METHOD.SYSTEM) await Task.Factory.StartNew(async () => await DealPass(Db, studyRecordId)); return ServiceResult.OprateSuccess("提交成功!"); } public async Task DealPass(ISqlSugarClient Db, long studyRecordId) { var record = await Db.Queryable().FirstAsync(x => x.Id == studyRecordId); var studyRecord = await Db.Queryable().FirstAsync(x => x.Id == record.StudyRecordId); var examPaper = await Db.Queryable().FirstAsync(x => x.Id == record.ExamPaperId); record.IsPass = examPaper.PassScore > (record.Score + record.AdjustScore) ? true : false; await Db.Updateable(record).UpdateColumns(it => new { it.IsPass }, true)//true表示追加AOP赋值列 .ExecuteCommandAsync(); if (record.IsPass == true) { if (studyRecord.CourseSceneId.IsNull() && !await Db.Queryable().AnyAsync(x => x.ExamId == studyRecord.ExamId)) { var course = await Db.Queryable().FirstAsync(x => x.Id == studyRecord.CourseId); #region 学分发放 var creditPoint = new Ghre_CreditPoint() { CourseId = studyRecord.CourseId, CourseSnapId = studyRecord.CourseSnapId, StaffId = studyRecord.StaffId, ExamId = studyRecord.ExamId, Date = DateTime.Now.Date, CreditPoints = course.CreditPoints }; await Db.Insertable(creditPoint).ExecuteReturnSnowflakeIdListAsync(); #endregion #region 证书发放 #endregion } } return true; } public async Task ViewExamPaperCallBackAsync(long examRecordId) { var entity = await base.QuerySingle(examRecordId); if (entity is null) return ServiceResult.OprateFailed("无效的考试ID!"); entity.IsView = true; entity.ViewTime = DateTime.Now; await Update(entity, new List() { "IsView","ViewTime" }); return ServiceResult.OprateSuccess("成功!"); } }