UserExamService.cs 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551
  1. using Exam.Application.Interface.Exam;
  2. using Exam.Infrastructure.Data.Entity;
  3. using Exam.Infrastructure.Enums;
  4. using Exam.Infrastructure.Extensions;
  5. using Exam.Share;
  6. using Exam.Share.Dtos.ExamManage;
  7. using Exam.Share.ViewResponses.Exam;
  8. using Hotline.Application.Exam.Core.Extensions;
  9. using Hotline.Application.Exam.Extensions;
  10. using Hotline.Application.Exam.Interface.Strategy;
  11. using Hotline.Application.Exam.QueryExtensions.ExamManages;
  12. using Hotline.Application.Exam.Strategy;
  13. using Hotline.Exams.ExamManages;
  14. using Hotline.Repository.SqlSugar;
  15. using Hotline.Repository.SqlSugar.DataPermissions;
  16. using Hotline.Repository.SqlSugar.Exam.Interfaces.ExamManages;
  17. using Hotline.Share.Dtos.ExamManages;
  18. using Hotline.Share.Exams.Extensions;
  19. using Hotline.Share.Requests.Exam;
  20. using Hotline.Share.ViewResponses;
  21. using Hotline.Share.ViewResponses.Exam;
  22. using Hotline.Users;
  23. using JiebaNet.Segmenter.Common;
  24. using MapsterMapper;
  25. using Hotline.Application.Exam.Core.Utilities;
  26. using Hotline.Application.Exam.Interface.ExamManages;
  27. using Hotline.Exams.Validate;
  28. using Hotline.Repository.SqlSugar.Exam.Repositories;
  29. using XF.Domain.Authentications;
  30. using XF.Domain.Dependency;
  31. using XF.Domain.Exceptions;
  32. using XF.Domain.Repository;
  33. using ExamQuestion = Hotline.Exams.Questions.ExamQuestion;
  34. using Hotline.Repository.SqlSugar.Exam.Service;
  35. using Hotline.Repository.SqlSugar.Exam.Extensions;
  36. using Exam.Infrastructure.Data.Interface;
  37. using Hotline.Repository.SqlSugar.Exam.Interface;
  38. using DocumentFormat.OpenXml.Drawing.Charts;
  39. using SqlSugar;
  40. using System.Threading;
  41. using DocumentFormat.OpenXml.Office2013.Excel;
  42. using Hotline.Share.Enums.Exams;
  43. using DocumentFormat.OpenXml.Wordprocessing;
  44. using Hotline.Repository.SqlSugar.Exam.Repositories.ExamManages;
  45. using Hotline.Exams.Questions;
  46. using Hotline.Exams.Sourcewares;
  47. using Hotline.Share.Dtos.Questions;
  48. using DocumentFormat.OpenXml.Office2010.Excel;
  49. using System.Linq.Expressions;
  50. using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
  51. namespace Hotline.Application.Exam.Service.ExamManages
  52. {
  53. public class UserExamService : ApiService<ExamUserExam, AddUserExamDto, UpdateUserExamDto, HotlineDbContext>, IUserExamService, IScopeDependency
  54. {
  55. private readonly IUserExamRepository _repository;
  56. private readonly IUserExamItemRepository _userExamItemRepository;
  57. private readonly IUserExamItemOptionRepository _userExamItemOptionRepository;
  58. private readonly IExamAnswerRepository _examAnswerRepository;
  59. private readonly IExamManageRepository _examManageRepository;
  60. private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder;
  61. private readonly IServiceProvider _serviceProvider;
  62. private readonly IMapper _mapper;
  63. private readonly ISessionContext _sessionContext
  64. ;
  65. public UserExamService(IUserExamRepository repository,
  66. IUserExamItemRepository userExamItemRepository,
  67. IUserExamItemOptionRepository userExamItemOptionRepository,
  68. IExamAnswerRepository examAnswerRepository,
  69. IExamManageRepository examManageRepository,
  70. IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider,
  71. IMapper mapper, ISessionContext sessionContext) : base(repository, mapper, sessionContext)
  72. {
  73. this._repository = repository;
  74. this._userExamItemRepository = userExamItemRepository;
  75. this._userExamItemOptionRepository = userExamItemOptionRepository;
  76. this._examAnswerRepository = examAnswerRepository;
  77. this._examManageRepository = examManageRepository;
  78. this._dataPermissionFilterBuilder = dataPermissionFilterBuilder;
  79. this._serviceProvider = serviceProvider;
  80. this._mapper = mapper;
  81. this._sessionContext = sessionContext;
  82. }
  83. #region public method
  84. public Task<UserExamDto> GetAsync(EntityQueryRequest entityQueryRequest)
  85. {
  86. throw new NotImplementedException();
  87. }
  88. public Task<(int, List<UserExamResultViewResponse>)> GetListAsync(UserExamPagedRequest queryRequest)
  89. {
  90. throw new NotImplementedException();
  91. }
  92. public async Task<ExamQuestionDto> GetExamQuestionDto(ExamQuestionRequest examQuestionRequest)
  93. {
  94. var expression = examQuestionRequest.GetExpression();
  95. var userUserExpression = examQuestionRequest.GetUserExamExpression();
  96. //var question = await new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(expression).FirstAsync();
  97. var querable = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(expression);
  98. var userExamTable = new ExamRepository<Exams.ExamManages.ExamUserExam>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(userUserExpression);
  99. querable = querable.InnerJoin(userExamTable, (q, u) => q.ExamId == u.ExamId).Select((q, u) => q);
  100. var question = await querable.FirstAsync();
  101. if (question != null)
  102. {
  103. var examQuestionDto = _mapper.Map<ExamQuestionDto>(question);
  104. var questionScore = await new ExamRepository<ExamQuestionScoreBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).GetAsync(x => x.QuestionType == question.QuestionType && x.ExamManageId == question.ExamId);
  105. if (questionScore != null)
  106. {
  107. examQuestionDto.Score = questionScore.Score;
  108. }
  109. if (examQuestionDto.QuestionType.CheckSelectType())
  110. {
  111. var questionOptions = await new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.ExamQuestionId == question.Id).ToListAsync();
  112. List<ExamUserExamItemOptions> userItemItemOptions = await GetUserExteamItemOptios(question);
  113. if (questionOptions != null)
  114. {
  115. examQuestionDto.QuestionOptions = new List<ExamQuestionOptionsDto>();
  116. questionOptions.ForEach(item =>
  117. {
  118. var examQuestionOptionsDto = _mapper.Map<ExamQuestionOptionsDto>(item);
  119. if (userItemItemOptions != null)
  120. {
  121. examQuestionOptionsDto.IsSelected = userItemItemOptions.Any(m => m.QuestionOptionId == item.Id);
  122. }
  123. examQuestionDto.QuestionOptions.Add(examQuestionOptionsDto);
  124. });
  125. }
  126. }
  127. else
  128. {
  129. List<ExamAnswer> examAnswers = await GetExamAnswers(examQuestionRequest);
  130. examQuestionDto.Answer = examAnswers != null ? examAnswers.FirstOrDefault()?.Answer : null;
  131. }
  132. return examQuestionDto;
  133. }
  134. else
  135. {
  136. throw new UserFriendlyException(ExamErrorMessage.ServiceError, string.Format(ExamErrorMessage.IsNotExists, string.Concat(typeof(ExamQuestion).GetDescription(), ":", examQuestionRequest.QuestionId)));
  137. }
  138. }
  139. private async Task<List<ExamAnswer>> GetExamAnswers(ExamQuestionRequest examQuestionRequest)
  140. {
  141. var examAnswerRepository = new ExamRepository<ExamAnswer>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  142. var userExamItemRepository = new ExamRepository<ExamUserExamItem>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  143. var userExamItemTable = userExamItemRepository.Queryable().Where(i => i.QuestionId == examQuestionRequest.QuestionId);
  144. var userExamTable = _repository.Queryable().Where(u => u.UserId == _sessionContext.UserId && u.Id == examQuestionRequest.UserExamId);
  145. var examAnswerTable = examAnswerRepository.Queryable();
  146. var examAnswers = await examAnswerTable.InnerJoin(userExamItemTable, (e, i) => e.UserExamItemId == i.Id)
  147. .InnerJoin(userExamTable, (e, i, u) => i.UserExamId == u.Id)
  148. .Select((e, i, u) => e).ToListAsync();
  149. return examAnswers;
  150. }
  151. private async Task<List<ExamUserExamItemOptions>> GetUserExteamItemOptios(Exams.ExamManages.ExamQuestionBak quesetion)
  152. {
  153. var userExamItemOptionsRepository = new ExamRepository<ExamUserExamItemOptions>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  154. var userExamItemOptionsTable = userExamItemOptionsRepository.Queryable();
  155. var userExamItemTable = _userExamItemRepository.Queryable();
  156. var userExamTable = _repository.Queryable();
  157. var userItemItemOptions = await userExamItemOptionsTable
  158. .InnerJoin(userExamItemTable, (o, u) => o.UserExamItemId == u.Id)
  159. .InnerJoin(userExamTable, (o, u, e) => u.UserExamId == e.Id)
  160. .Where((o, u, e) => u.QuestionId == quesetion.QuestionId && e.UserId == _sessionContext.UserId && e.ExamStatus == EExamStatus.Executing).
  161. Select((o, u, e) => o).ToListAsync();
  162. return userItemItemOptions;
  163. }
  164. public async Task<List<ExamQuestionViewResponse>> GetExamQuestionViewResponses(ExamQuestionGroupRequest examQuestionGroupRequest)
  165. {
  166. if (examQuestionGroupRequest.ExamId.IsNull() && examQuestionGroupRequest.UserId.IsNull())
  167. throw UserFriendlyException.SameMessage("查询参数不能为空");
  168. var expression = examQuestionGroupRequest.GetExpression();
  169. var examManageTable = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(expression);
  170. var testPaperItemTable = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  171. var queryable = await examManageTable.InnerJoin(testPaperItemTable, (e, i) => e.Id == i.ExamId)
  172. .Select((e, i) => i).ToListAsync();
  173. var result = queryable.GroupBy(x => x.QuestionType).Select(m => new ExamQuestionViewResponse
  174. {
  175. QuestionType = m.Key,
  176. Questions = m.GroupBy(g => g.QuestionId).Select(n => new SimpleViewResponse
  177. {
  178. Id = n.Key
  179. }).ToList()
  180. }).ToList();
  181. return result;
  182. }
  183. public async Task<List<GradingQuestionViewResponce>> GetGradingQuestionViewResponces(ExamQuestionGroupRequest examQuestionGroupRequest)
  184. {
  185. var expression = examQuestionGroupRequest.GetExpression();
  186. var examManageTable = _examManageRepository.Queryable().Where(expression);
  187. var testPaperItemTable = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  188. var queryable = await examManageTable.InnerJoin(testPaperItemTable, (e, i) => e.Id == i.ExamId)
  189. .Select((e, i) => i).ToListAsync();
  190. var examQuestionScores = await new ExamRepository<ExamQuestionScoreBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.ExamManageId == examQuestionGroupRequest.ExamId).ToListAsync();
  191. var userExamItemTable = _userExamItemRepository.Queryable();
  192. var userExamTable = _repository.Queryable().Where(x => x.ExamId == examQuestionGroupRequest.ExamId && x.UserId == examQuestionGroupRequest.UserId);
  193. var userExamItems = await userExamItemTable.InnerJoin(userExamTable, (i, u) => i.UserExamId == u.Id)
  194. .Select((i, u) => i).ToListAsync();
  195. var result = queryable.GroupBy(x => x.QuestionType).Select(m => new GradingQuestionViewResponce
  196. {
  197. QuestionType = m.Key,
  198. Questions = m.Select(n => new GradingExamViewResponse
  199. {
  200. IsCorrect = CheckCorrect(n, examQuestionScores, userExamItems),
  201. Id = userExamItems.FirstOrDefault(x => x.QuestionId == n.QuestionId)?.Id ?? n.Id
  202. }).ToList()
  203. }).ToList();
  204. return result;
  205. }
  206. private bool CheckCorrect(Exams.ExamManages.ExamQuestionBak n, List<ExamQuestionScoreBak> examQuestionScores, List<ExamUserExamItem> userExamItems)
  207. {
  208. var examQuestionScore = examQuestionScores.FirstOrDefault(x => x.QuestionType == n.QuestionType);
  209. var userItem = userExamItems.FirstOrDefault(x => x.QuestionId == n.QuestionId);
  210. if (userItem != null && examQuestionScore != null)
  211. {
  212. return userItem.Score == examQuestionScore.Score;
  213. }
  214. return false;
  215. }
  216. public async Task<PageViewResponse<UserExamResultViewResponse>> GetPagedListAsync(UserExamPagedRequest queryRequest)
  217. {
  218. SqlSugar.ISugarQueryable<UserExamResultViewResponse> queryable = GetQueryable(queryRequest);
  219. var list = await queryable.ToPageListAsync(queryRequest.PageIndex, queryRequest.PageSize);
  220. var total = await queryable.CountAsync();
  221. var result = new UserExamResultPageViewResponse
  222. {
  223. Items = list,
  224. Pagination = new Pagination(queryRequest.PageIndex, queryRequest.PageSize, total)
  225. };
  226. return result;
  227. }
  228. public async Task<GradingExamQuestionDto> GradingAsync(GradingExamItemDto gradingExtamItemDto, CancellationToken cancellationToken)
  229. {
  230. var userExamItem = await _userExamItemRepository.GetAsync(m => m.Id == gradingExtamItemDto.UserExamItemId);
  231. if (userExamItem != null)
  232. {
  233. userExamItem = _mapper.Map<GradingExamItemDto, ExamUserExamItem>(gradingExtamItemDto, userExamItem);
  234. await _userExamItemRepository.UpdateWithValidateAsync(userExamItem, cancellationToken);
  235. }
  236. return await GetNextExamQuestion(gradingExtamItemDto);
  237. }
  238. public async Task SubmitAsync(SubmitExamDto submitExamDto, CancellationToken cancellationToken)
  239. {
  240. var userExam = await _repository.GetAsync(x => x.Id == submitExamDto.Id);
  241. if (userExam != null)
  242. {
  243. userExam = _mapper.Map<SubmitExamDto, ExamUserExam>(submitExamDto, userExam);
  244. userExam.ExamStatus = EExamStatus.Complete;
  245. await _repository.UpdateWithValidateAsync(userExam, cancellationToken);
  246. await CompleteExamManage(userExam.ExamId, cancellationToken);
  247. }
  248. }
  249. private async Task CompleteExamManage(string examId, CancellationToken cancellationToken)
  250. {
  251. var userExams = await _repository.Queryable().Where(x => x.ExamId == examId).ToListAsync();
  252. if (userExams.All(x => x.IsSubmit))
  253. {
  254. var examManage = await _examManageRepository.GetAsync(x => x.Id == examId);
  255. examManage.ExamStatus = EExamStatus.Complete;
  256. await _examManageRepository.UpdateWithValidateAsync(examManage, cancellationToken);
  257. }
  258. }
  259. public async Task<StartExamViewResponse> ExamAsync(UpdateUserExamItemDto updateUserExamItemDto, CancellationToken cancellationToken)
  260. {
  261. var userExam = await new ExamRepository<ExamUserExam>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.Id == updateUserExamItemDto.UserExamId).FirstAsync();
  262. var startExamViewResponse = await CheckExamValid(userExam, cancellationToken);
  263. if (!startExamViewResponse.CheckValidate())
  264. {
  265. await SetExamStatus(userExam, startExamViewResponse, cancellationToken);
  266. return startExamViewResponse;
  267. }
  268. var hasUserExamItem = _userExamItemRepository.Queryable().Where(x => x.UserExamId == updateUserExamItemDto.UserExamId && x.QuestionId == updateUserExamItemDto.QuestionId).Any();
  269. if (!hasUserExamItem)
  270. {
  271. var addUserExamItemDto = _mapper.Map<UpdateUserExamItemDto, AddUserExamItemDto>(updateUserExamItemDto);
  272. await AddExamAsync(_userExamItemRepository, addUserExamItemDto, cancellationToken);
  273. }
  274. else
  275. {
  276. await UpdateExamAsync(_userExamItemRepository, updateUserExamItemDto, cancellationToken);
  277. }
  278. await CalcuteExamItemScore(_userExamItemRepository, updateUserExamItemDto, cancellationToken);
  279. return startExamViewResponse;
  280. }
  281. private async Task SetExamStatus(ExamUserExam userExam, StartExamViewResponse startExamViewResponse, CancellationToken cancellationToken)
  282. {
  283. userExam.ExamStatus = startExamViewResponse.IsCompleted ? EExamStatus.Complete : EExamStatus.NoStart;
  284. userExam.ToUpdate(_sessionContext);
  285. await _repository.UpdateWithValidateAsync(userExam, cancellationToken);
  286. }
  287. public async Task<StartExamViewResponse> StartUserExamAsync(StartUserExamDto startUserExamDto, CancellationToken cancellationToken)
  288. {
  289. var userExam = await _repository.GetAsync(x => x.Id == startUserExamDto.Id);
  290. if (userExam == null) return new StartExamViewResponse
  291. {
  292. IsJoin = false
  293. };
  294. if (userExam.ExamStatus == EExamStatus.NoStart || userExam.ExamStatus == EExamStatus.Complete)
  295. userExam.StartTime = DateTime.Now;
  296. var startExamViewResponse = await CheckExamValid(userExam, cancellationToken);
  297. if (!startExamViewResponse.CheckValidate())
  298. {
  299. await SetExamStatus(userExam, startExamViewResponse, cancellationToken);
  300. return startExamViewResponse;
  301. }
  302. if (userExam.ExamStatus == EExamStatus.NoStart)
  303. {
  304. userExam.ExamStatus = Share.Enums.Exams.EExamStatus.Executing;
  305. userExam.ToUpdate(_sessionContext);
  306. await _repository.UpdateWithValidateAsync(userExam, cancellationToken);
  307. }
  308. // TODO: 删除之前选项和答案
  309. else if (userExam.ExamStatus == EExamStatus.Complete)
  310. {
  311. await ReExam(userExam, cancellationToken);
  312. }
  313. var examManage = await _examManageRepository.GetAsync(x => x.Id == userExam.ExamId);
  314. return new StartExamViewResponse
  315. {
  316. StartTime = userExam.StartTime,
  317. TimeSpan = examManage?.TimeSpan,
  318. IsCompleted = false
  319. };
  320. }
  321. /// <summary>
  322. /// 重考
  323. /// </summary>
  324. /// <param name="userExam"></param>
  325. /// <param name="cancellationToken"></param>
  326. /// <returns></returns>
  327. private async Task ReExam(ExamUserExam userExam, CancellationToken cancellationToken)
  328. {
  329. //新增重考记录
  330. var reExamUserExam = _mapper.Map<ExamUserExam, ExamUserExam>(userExam);
  331. reExamUserExam.IsCheck = false;
  332. reExamUserExam.IsSubmit = false;
  333. reExamUserExam.IsSuccess = false;
  334. reExamUserExam.IsReExam = true;
  335. reExamUserExam.Score = 0;
  336. reExamUserExam.ExamStatus = EExamStatus.NoStart;
  337. reExamUserExam.ToInsert(_sessionContext);
  338. await _repository.AddWithValidateAsync(reExamUserExam, cancellationToken);
  339. }
  340. private async Task<StartExamViewResponse> CheckExamValid(ExamUserExam examUserExam, CancellationToken cancellationToken)
  341. {
  342. var examManage = await _examManageRepository.Queryable().Where(x => x.Id == examUserExam.ExamId).FirstAsync();
  343. var startExamViewResponse = new StartExamViewResponse
  344. {
  345. IsJoin = true,
  346. IsCompleted = false
  347. };
  348. if (examManage != null)
  349. {
  350. var examStrategyProxy = new ExamStrategyProxy();
  351. var examStrategys = new List<IExamStrategy>();
  352. startExamViewResponse = AddCheckStartTimeStrategy(examUserExam, examManage, startExamViewResponse, examStrategys);
  353. startExamViewResponse = AddCheckEndTimeStrategy(examUserExam, examManage, startExamViewResponse, examStrategys);
  354. startExamViewResponse = AddCheckValidateTimeStrategy(examUserExam, examManage, startExamViewResponse, examStrategys);
  355. startExamViewResponse = AddCheckValidateCountStrategy(examUserExam, examManage, startExamViewResponse, examStrategys);
  356. examStrategyProxy.Initial(examStrategys);
  357. if (!examStrategyProxy.Validate())
  358. {
  359. startExamViewResponse = (StartExamViewResponse)examStrategyProxy.GetResult();
  360. return startExamViewResponse;
  361. }
  362. }
  363. startExamViewResponse.IsStart = true;
  364. if (examManage.ExamStatus == EExamStatus.NoStart)
  365. {
  366. await UpdateExamStatus(examManage, cancellationToken);
  367. }
  368. startExamViewResponse.TimeSpan = examManage?.TimeSpan ?? 0;
  369. startExamViewResponse.StartTime = examUserExam?.StartTime;
  370. return startExamViewResponse;
  371. }
  372. private async Task UpdateExamStatus(ExamManage? examManage, CancellationToken cancellationToken)
  373. {
  374. examManage.ExamStatus = EExamStatus.Executing;
  375. examManage.ToUpdate(_sessionContext);
  376. await _examManageRepository.UpdateWithValidateAsync(examManage, cancellationToken);
  377. }
  378. private StartExamViewResponse AddCheckValidateCountStrategy(ExamUserExam examUserExam, ExamManage examManage, StartExamViewResponse startExamViewResponse, List<IExamStrategy> examStrategys)
  379. {
  380. if (examManage.ExamType == Share.Enums.Exams.EExamType.Simulate)
  381. {
  382. var checkStartTime = new CheckValidateCountStrategy(1, 1)
  383. {
  384. CallBack = () =>
  385. {
  386. var response = new StartExamViewResponse
  387. {
  388. IsJoin = false,
  389. IsStart = false,
  390. IsCompleted = true,
  391. StartTime = examUserExam.StartTime,
  392. TimeSpan = examManage.TimeSpan
  393. };
  394. return response;
  395. }
  396. };
  397. examStrategys.Add(checkStartTime);
  398. return startExamViewResponse;
  399. }
  400. else
  401. {
  402. var count = new ExamRepository<ExamUserExam>(_uow, _dataPermissionFilterBuilder, _serviceProvider).CountAsync(x => x.ExamId == examManage.Id && x.UserId == examUserExam.UserId).Result;
  403. var checkStartTime = new CheckValidateCountStrategy(examManage.Count, count)
  404. {
  405. CallBack = () =>
  406. {
  407. var response = new StartExamViewResponse
  408. {
  409. IsJoin = false,
  410. IsStart = false,
  411. IsCompleted = true,
  412. StartTime = examUserExam.StartTime,
  413. TimeSpan = examManage.TimeSpan
  414. };
  415. return response;
  416. }
  417. };
  418. examStrategys.Add(checkStartTime);
  419. return startExamViewResponse;
  420. }
  421. }
  422. private StartExamViewResponse AddCheckValidateTimeStrategy(ExamUserExam examUserExam, ExamManage examManage, StartExamViewResponse startExamViewResponse, List<IExamStrategy> examStrategys)
  423. {
  424. if (examManage.ExamType == Share.Enums.Exams.EExamType.Simulate) return startExamViewResponse;
  425. var checkStartTime = new CheckValidateTimeStrategy(examManage.TimeSpan, examUserExam.StartTime)
  426. {
  427. CallBack = () =>
  428. {
  429. var response = new StartExamViewResponse
  430. {
  431. IsJoin = false,
  432. IsStart = false,
  433. IsCompleted = true,
  434. StartTime = examUserExam.StartTime,
  435. TimeSpan = examManage.TimeSpan
  436. };
  437. return response;
  438. }
  439. };
  440. examStrategys.Add(checkStartTime);
  441. return startExamViewResponse;
  442. }
  443. private StartExamViewResponse AddCheckEndTimeStrategy(ExamUserExam examUserExam, ExamManage examManage, StartExamViewResponse startExamViewResponse, List<IExamStrategy> examStrategys)
  444. {
  445. if (examManage.ExamType == Share.Enums.Exams.EExamType.Simulate) return startExamViewResponse;
  446. var checkStartTime = new CheckEndTimeStrategy(examManage.EndTime, DateTime.Now)
  447. {
  448. CallBack = () =>
  449. {
  450. var response = new StartExamViewResponse
  451. {
  452. IsJoin = false,
  453. IsStart = false,
  454. IsCompleted = true,
  455. StartTime = examUserExam.StartTime,
  456. TimeSpan = examManage.TimeSpan
  457. };
  458. return response;
  459. }
  460. };
  461. examStrategys.Add(checkStartTime);
  462. return startExamViewResponse;
  463. }
  464. private static StartExamViewResponse AddCheckStartTimeStrategy(ExamUserExam examUserExam, ExamManage examManage, StartExamViewResponse startExamViewResponse, List<IExamStrategy> examStrategys)
  465. {
  466. if (examManage.ExamType == Share.Enums.Exams.EExamType.Simulate) return startExamViewResponse;
  467. var checkStartTime = new CheckStartTimeStrategy(examManage.StartTime, examUserExam.StartTime)
  468. {
  469. CallBack = () =>
  470. {
  471. var response = new StartExamViewResponse
  472. {
  473. IsJoin = false,
  474. IsStart = false,
  475. IsCompleted = false,
  476. StartTime = examUserExam.StartTime,
  477. TimeSpan = examManage.TimeSpan
  478. };
  479. return response;
  480. }
  481. };
  482. examStrategys.Add(checkStartTime);
  483. return startExamViewResponse;
  484. }
  485. public async Task CompleteGradingAsync(GradingExamDto gradingExtamDto, CancellationToken cancellationToken)
  486. {
  487. var userExam = await _repository.GetAsync(x => x.Id == gradingExtamDto.Id);
  488. if (userExam == null) return;
  489. var userExamItems = await _userExamItemRepository.Queryable().Where(x => x.UserExamId == gradingExtamDto.Id).ToListAsync();
  490. if (userExamItems != null)
  491. {
  492. var totalScore = userExamItems.Sum(x => x.Score);
  493. userExam.Score = totalScore;
  494. var examManage = await new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).GetAsync(x => x.Id == userExam.ExamId);
  495. userExam.IsSuccess = totalScore >= examManage.CutoffScore;
  496. userExam.ExamStatus = Share.Enums.Exams.EExamStatus.Complete;
  497. userExam.ToUpdate(_sessionContext);
  498. await _repository.UpdateWithValidateAsync(userExam, cancellationToken);
  499. }
  500. }
  501. public async Task<List<GradingExamQuestionDto>> GetGradingExamQuestion(GradingExamRequest gradingExamRequest)
  502. {
  503. var expression = gradingExamRequest.GetExpression();
  504. ISugarQueryable<GradingExamQuestionTempDto> queryable = GetViewExamQuestionTempDtos(expression);
  505. queryable =
  506. queryable.MergeTable().Where((q) => !(q.QuestionType == EQuestionType.Single || q.QuestionType == EQuestionType.Multi || q.QuestionType == EQuestionType.Judge));
  507. var queryResult = await queryable.ToListAsync();
  508. var gradingExamQuestionDtos = queryResult.GroupBy(x => new
  509. {
  510. Id = x.Id,
  511. QuestionType = x.QuestionType
  512. }).Select(g => new GradingExamQuestionDto
  513. {
  514. Answer = g.FirstOrDefault().Answer,
  515. QuestionType = g.Key.QuestionType,
  516. Id = g.Key.Id,
  517. QuestionScore = g.FirstOrDefault().QuestionScore,
  518. Score = g.FirstOrDefault().Score,
  519. Title = g.FirstOrDefault().Title,
  520. CorrectAnswer = g.Key.QuestionType.CheckSelectType() ? string.Join(",", g.Where(i => i.IsAnswer).Select(n => n.Label).Distinct()) : g.FirstOrDefault()?.CorrectAnswer
  521. }).ToList();
  522. return gradingExamQuestionDtos;
  523. }
  524. private ISugarQueryable<GradingExamQuestionTempDto> GetViewExamQuestionTempDtos(Expression<Func<ExamUserExam, bool>> expression)
  525. {
  526. var userExamTable = _repository.Queryable().Where(expression);
  527. var questionScoreRepository = new ExamRepository<ExamQuestionScoreBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  528. var userExamItemTable = _userExamItemRepository.Queryable();
  529. var userExamItemOptionTable = _userExamItemOptionRepository.Queryable();
  530. var examAnswerTable = new ExamRepository<ExamAnswer>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  531. var questionTable = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  532. var quesitonOptionTable = new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  533. var testPaperItemAnswerTable = new ExamRepository<ExamQuestionAnswerBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  534. var questionScoreTable = questionScoreRepository.Queryable();
  535. return userExamTable.InnerJoin(userExamItemTable, (e, i) => e.Id == i.UserExamId)
  536. .InnerJoin(questionTable, (e, i, q) => i.QuestionId == q.QuestionId && q.ExamId == e.ExamId)
  537. .LeftJoin(userExamItemOptionTable, (e, i, q, o) => i.Id == o.UserExamItemId)
  538. .LeftJoin(quesitonOptionTable, (e, i, q, o, qo) => o.QuestionOptionId == qo.Id)
  539. .LeftJoin(examAnswerTable, (e, i, q, o, qo, a) => i.Id == a.UserExamItemId)
  540. .LeftJoin(testPaperItemAnswerTable, (e, i, q, o, qo, a, ta) => ta.QuestionId == q.QuestionId)
  541. .InnerJoin(questionScoreTable, (e, i, q, o, qo, a, ta, s) => q.QuestionType == s.QuestionType && e.ExamId == s.ExamManageId)
  542. .Select(
  543. (e, i, q, o, qo, a, ta, s) => new GradingExamQuestionTempDto
  544. {
  545. Id = i.Id,
  546. QuestionType = q.QuestionType,
  547. CorrectAnswer = ta.Id != null ? ta.Answer : string.Empty,
  548. Answer = a.Id != null ? a.Answer : string.Empty,
  549. Title = q.Title,
  550. QuestionOptionId = o.Id,
  551. QuestionId = q.QuestionId,
  552. ExamQuestionId = q.Id,
  553. UserExamItemId = i.Id,
  554. Content = qo.Content,
  555. Label = qo.Label,
  556. IsAnswer = qo.IsAnswer,
  557. IsSelected = o.Id != null,
  558. QuestionScore = s.Score,
  559. Score = i.Score
  560. }
  561. );
  562. }
  563. public async Task<GradingExamQuestionDto> ViewGradingExamQuestion(ViewGradingExamRequest viewGradingExamRequest)
  564. {
  565. var gradingExtamItemDto = _mapper.Map<ViewGradingExamRequest, GradingExamItemDto>(viewGradingExamRequest);
  566. return await GetNextExamQuestion(gradingExtamItemDto);
  567. }
  568. public async Task<UnExamUserPageViewResponse> GetUnExamUsersPaged(UnExamUserReportPagedRequest unExamUserReportPagedRequest)
  569. {
  570. ISugarQueryable<UnExamUserViewResponse> queryResult = GEtUnExamUserQueryable(unExamUserReportPagedRequest);
  571. var total = await queryResult.CountAsync();
  572. var items = unExamUserReportPagedRequest.IsPaged ?
  573. await queryResult.ToPageListAsync(unExamUserReportPagedRequest.PageIndex, unExamUserReportPagedRequest.PageSize)
  574. : await queryResult.ToListAsync();
  575. return new UnExamUserPageViewResponse
  576. {
  577. Items = items,
  578. Pagination = new Pagination(unExamUserReportPagedRequest.PageIndex, unExamUserReportPagedRequest.PageSize, total)
  579. };
  580. }
  581. public async Task<List<UnExamUserViewResponse>> GetUnExamUsers(UnExamUserReportPagedRequest unExamUserReportPagedRequest)
  582. {
  583. ISugarQueryable<UnExamUserViewResponse> queryResult = GEtUnExamUserQueryable(unExamUserReportPagedRequest);
  584. var items = await queryResult.ToListAsync();
  585. return items;
  586. }
  587. private ISugarQueryable<UnExamUserViewResponse> GEtUnExamUserQueryable(UnExamUserReportPagedRequest unExamUserReportPagedRequest)
  588. {
  589. if (unExamUserReportPagedRequest.EndTime == null)
  590. unExamUserReportPagedRequest.ResolveEndTime();
  591. var examManageRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  592. var userRepository = new ExamRepository<User>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  593. var expression = unExamUserReportPagedRequest.GetExpression();
  594. var userExamExpression = unExamUserReportPagedRequest.GetUserExamExpression();
  595. var examManageTable = examManageRepository.Queryable().Where(expression);
  596. var userTable = userRepository.Queryable();
  597. var userExamTable = _repository.Queryable().Where(userExamExpression);
  598. var queryResult = userExamTable.InnerJoin(examManageTable, (ue, e) => ue.ExamId == e.Id)
  599. .InnerJoin(userTable, (ue, e, u) => ue.UserId == u.Id)
  600. .Select((ue, e, u) => new UnExamUserViewResponse
  601. {
  602. ExamName = e.Name,
  603. OrgName = u.Organization.Name,
  604. UserName = u.Name
  605. })
  606. .MergeTable()
  607. .OrderByPropertyNameIF(!string.IsNullOrEmpty(unExamUserReportPagedRequest.SortField), unExamUserReportPagedRequest.SortField, (OrderByType)(unExamUserReportPagedRequest.SortRule ?? 0));
  608. return queryResult;
  609. }
  610. public async Task<UserExamResultPageViewResponse> GetUserExamResults(UserExamResultReportPagedRequest userExamResultReportPagedRequest)
  611. {
  612. if (userExamResultReportPagedRequest.EndTime == null)
  613. userExamResultReportPagedRequest.ResolveEndTime();
  614. var examManageRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  615. var userRepository = new ExamRepository<User>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  616. var expression = userExamResultReportPagedRequest.GetExpression();
  617. var userExamExpression = userExamResultReportPagedRequest.GetUserExamExpression();
  618. var examManageTable = examManageRepository.Queryable().Where(expression);
  619. var userTable = userRepository.Queryable();
  620. var userExamTable = _repository.Queryable().Where(userExamExpression);
  621. var queryResult = userExamTable.InnerJoin(examManageTable, (ue, e) => ue.ExamId == e.Id)
  622. .InnerJoin(userTable, (ue, e, u) => ue.UserId == u.Id)
  623. .Select((ue, e, u) => new UserExamResultViewResponse
  624. {
  625. ExamName = e.Name,
  626. OrgName = u.Organization.Name,
  627. UserName = u.Name,
  628. TotalScore = e.TotalScore,
  629. CutoffScore = e.CutoffScore,
  630. Score = ue.Score ?? 0,
  631. })
  632. .MergeTable()
  633. .OrderByPropertyNameIF(!string.IsNullOrEmpty(userExamResultReportPagedRequest.SortField), userExamResultReportPagedRequest.SortField, (OrderByType)(userExamResultReportPagedRequest.SortRule ?? 0))
  634. .OrderByDescending(x => x.Score)
  635. ;
  636. var total = await queryResult.CountAsync();
  637. var items = userExamResultReportPagedRequest.IsPaged ?
  638. await queryResult.ToPageListAsync(userExamResultReportPagedRequest.PageIndex, userExamResultReportPagedRequest.PageSize)
  639. : await queryResult.ToListAsync();
  640. ;
  641. return new UserExamResultPageViewResponse
  642. {
  643. Items = items,
  644. Pagination = new Pagination(userExamResultReportPagedRequest.PageIndex, userExamResultReportPagedRequest.PageSize, total)
  645. };
  646. }
  647. public async Task<GradingResultPageViewResponse> GetGradingResultPagedList(GradingPagedRequest gradingPagedRequest)
  648. {
  649. // 只要有阅卷记录就在已阅卷列表中,已阅卷和未阅卷会有重复数据,只有所有记录都已阅卷才会从未阅卷列表中排除
  650. var userExamTable = _repository.Queryable().Where(x => x.IsSubmit);
  651. var examManageTable = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  652. var queryable = userExamTable.InnerJoin(examManageTable, (u, e) => u.ExamId == e.Id).GroupBy((u, e) => new
  653. {
  654. ExamName = e.Name,
  655. ExamCode = e.Code,
  656. CutoffScore = e.CutoffScore,
  657. TotalScore = e.TotalScore,
  658. Id = e.Id,
  659. Status = e.Status,
  660. Remark = e.Remark
  661. }).Select((u, e) => new GradingResultViewResponse
  662. {
  663. CutoffScore = e.CutoffScore,
  664. TotalScore = e.TotalScore,
  665. ExamName = e.Name,
  666. ExamCode = e.Code,
  667. IsCheck = SqlFunc.Subqueryable<ExamUserExam>().Where(x => x.ExamId == e.Id && !x.IsCheck).Count() <= 0,
  668. Id = e.Id,
  669. Remark = e.Remark
  670. }).MergeTable();
  671. queryable = queryable.WhereIF(gradingPagedRequest.IsCheck != null, x => x.IsCheck == gradingPagedRequest.IsCheck);
  672. var list = await queryable.ToPageListAsync(gradingPagedRequest.PageIndex, gradingPagedRequest.PageSize);
  673. var total = await queryable.CountAsync();
  674. var result = new GradingResultPageViewResponse
  675. {
  676. Items = list,
  677. Pagination = new Pagination(gradingPagedRequest.PageIndex, gradingPagedRequest.PageSize, total)
  678. };
  679. return result;
  680. }
  681. public async Task BatchGradingAsync(BatchGradingExamItemDto batchGradingExamItemDto, CancellationToken cancellationToken)
  682. {
  683. var userExamItemIds = batchGradingExamItemDto.Items.Select(x => x.UserExamItemId);
  684. var userExamItems = await _userExamItemRepository.Queryable().Where(m => userExamItemIds.Contains(m.Id)).ToListAsync();
  685. if (userExamItems != null && userExamItemIds.Any())
  686. {
  687. var updateUserExamItems = new List<ExamUserExamItem>();
  688. userExamItems.ForEach(x =>
  689. {
  690. var gradingExamItemDto = batchGradingExamItemDto.Items.Find(m => m.UserExamItemId == x.Id);
  691. var updateUserExamItem = _mapper.Map<GradingExamItemDto, ExamUserExamItem>(gradingExamItemDto, x);
  692. updateUserExamItem.IsCheck = true;
  693. updateUserExamItems.Add(updateUserExamItem);
  694. });
  695. updateUserExamItems.ToUpdate(_sessionContext);
  696. await _userExamItemRepository.UpdateWithValidateAsync(updateUserExamItems, cancellationToken);
  697. var userExamId = userExamItems.FirstOrDefault()?.UserExamId;
  698. // 计算本次考试得分
  699. var userExamItemsInCheck = await _userExamItemRepository.Queryable()
  700. .InnerJoin<ExamQuestionBak>((u, q) => u.QuestionId == q.QuestionId)
  701. .Where((u, q) => u.UserExamId == userExamId && (q.QuestionType == EQuestionType.Single || q.QuestionType == EQuestionType.Multi || q.QuestionType == EQuestionType.Judge)).Select((u, q) => new UpdateUserExamItemDto
  702. {
  703. QuestionId = u.QuestionId,
  704. QuestionType = q.QuestionType,
  705. UserExamId = u.UserExamId,
  706. Id = u.Id
  707. }).Distinct().ToListAsync();
  708. await CalcuteExamItemScore(_userExamItemRepository, userExamItemsInCheck, cancellationToken);
  709. await CalcuteTotalScore(_userExamItemRepository, userExamId, cancellationToken);
  710. }
  711. }
  712. public async Task<List<ExamUserViewResponse>> GetUserListAsync(ExamUserQueryRequest examUserQueryRequest)
  713. {
  714. var userExamTable = _repository.Queryable().Where(x => x.ExamId == examUserQueryRequest.ExamId);
  715. var queryable = await userExamTable.InnerJoin<User>((ux, u) => ux.UserId == u.Id).Select((ux, u) => new ExamUserViewResponse
  716. {
  717. ExamId = ux.ExamId,
  718. UserId = ux.UserId,
  719. UserName = u.Name,
  720. Id = ux.Id
  721. }).ToListAsync();
  722. return queryable;
  723. }
  724. #endregion
  725. #region private method
  726. private async Task CalcuteExamItemScore(IUserExamItemRepository userExamRepository, UpdateUserExamItemDto addUserExamItemDto, CancellationToken cancellationToken)
  727. {
  728. if (!addUserExamItemDto.QuestionType.CheckSelectType()) return;
  729. var testPaperItemOptionsRepository = new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  730. var examManageRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  731. var testPaperItemRepository = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  732. var examQuestionScoreRepository = new ExamRepository<ExamQuestionScoreBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  733. var testPaperOptionsTable = testPaperItemOptionsRepository.Queryable().Where(x => x.QuestionId == addUserExamItemDto.QuestionId && x.IsAnswer);
  734. var testPaperItemTable = testPaperItemRepository.Queryable();
  735. var userExamTable = _repository.Queryable().Where(x => x.Id == addUserExamItemDto.UserExamId);
  736. var examManageTable = examManageRepository.Queryable();
  737. var testPaperOptionIds = await testPaperOptionsTable.InnerJoin(testPaperItemTable, (t, i) => t.ExamQuestionId == i.Id)
  738. .InnerJoin(examManageTable, (t, i, e) => i.ExamId == e.Id)
  739. .InnerJoin(userExamTable, (t, i, e, u) => e.Id == u.ExamId)
  740. .Select((t, i, e, u) => t.Id).ToListAsync();
  741. var isCorrect = addUserExamItemDto.UserExamItemOptionDtos.Select(x => x.QuestionOptionId).OrderBy(x => x).SequenceEqual(testPaperOptionIds.OrderBy(x => x));
  742. var userExamItem = await userExamRepository.GetAsync(x => x.UserExamId == addUserExamItemDto.UserExamId && x.QuestionId == addUserExamItemDto.QuestionId);
  743. var examQuesiontScores = await examQuestionScoreRepository.Queryable().Where(x => x.QuestionType == addUserExamItemDto.QuestionType)
  744. .InnerJoin(userExamTable, (e, u) => e.Id == u.ExamId)
  745. .Select((e, u) => e).ToListAsync();
  746. userExamItem.IsCheck = true;
  747. userExamItem.Score = isCorrect ? examQuesiontScores.FirstOrDefault()?.Score : 0;
  748. userExamItem.ToUpdate(_sessionContext);
  749. await userExamRepository.UpdateWithValidateAsync(userExamItem, cancellationToken);
  750. }
  751. private async Task CalcuteExamItemScore(IUserExamItemRepository userExamItemRepository, List<UpdateUserExamItemDto> addUserExamItemDtos, CancellationToken cancellationToken)
  752. {
  753. var questionIds = addUserExamItemDtos.Select(x => x.QuestionId).ToList();
  754. var userExamIds = addUserExamItemDtos.Select(x => x.UserExamId).ToList();
  755. var questionTypes = addUserExamItemDtos.Select(x => x.QuestionType).ToList();
  756. List<ExamQuestionOptionsBak> examQuestionOptions = await GetQuestionOptionBaks(questionIds, userExamIds, true).ToListAsync();
  757. var userExamItemOptionRepository = new ExamRepository<ExamUserExamItemOptions>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  758. var examQuestionScoreRepository = new ExamRepository<ExamQuestionScoreBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  759. var userExamTable = _repository.Queryable().Where(x => userExamIds.Contains(x.Id));
  760. var userExamItems = await userExamItemRepository.Queryable().Where(x => userExamIds.Contains(x.UserExamId)).ToListAsync();
  761. var userExamItemIds = userExamItems.Select(x => x.Id).ToList();
  762. var userExamItemOptions = await userExamItemOptionRepository.Queryable().Where(x => userExamItemIds.Contains(x.UserExamItemId)).ToListAsync();
  763. var examQuesiontScores = await examQuestionScoreRepository.Queryable().Where(x => questionTypes.Contains(x.QuestionType))
  764. .InnerJoin(userExamTable, (e, u) => e.ExamManageId == u.ExamId)
  765. .Select((e, u) => e).ToListAsync();
  766. foreach (var addUserExamItemDto in addUserExamItemDtos)
  767. {
  768. var examQuestionOptionIds = examQuestionOptions.Where(x => x.QuestionId == addUserExamItemDto.QuestionId).Select(x => x.Id).ToList();
  769. var isCorrect = userExamItemOptions.Where(x => x.UserExamItemId == addUserExamItemDto.Id).Select(x => x.QuestionOptionId).OrderBy(x => x).SequenceEqual(examQuestionOptionIds.OrderBy(x => x));
  770. var userExamItem = userExamItems.FirstOrDefault(x => x.QuestionId == addUserExamItemDto.QuestionId);
  771. if (userExamItem != null)
  772. {
  773. userExamItem.IsCheck = true;
  774. userExamItem.Score = isCorrect ? examQuesiontScores.FirstOrDefault(x => x.QuestionType == addUserExamItemDto.QuestionType)?.Score : 0;
  775. userExamItem.ToUpdate(_sessionContext);
  776. }
  777. }
  778. await userExamItemRepository.UpdateWithValidateAsync(userExamItems, cancellationToken);
  779. }
  780. private ISugarQueryable<ExamQuestionOptionsBak> GetQuestionOptionBaks(List<string> questionIds, List<string> userExamIds, bool isFilterAnswer)
  781. {
  782. var questionRepository = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  783. var questionTable = questionRepository.Queryable().Where(x => x.QuestionType == EQuestionType.Single || x.QuestionType == EQuestionType.Multi || x.QuestionType == EQuestionType.Judge);
  784. var userExamTable = _repository.Queryable().Where(x => userExamIds.Contains(x.Id));
  785. var examManageRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  786. var examManageTable = examManageRepository.Queryable();
  787. var examQuestionOptionsRepository = new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  788. var examQuestionOptionsTable = examQuestionOptionsRepository.Queryable()
  789. .Where(x => questionIds.Contains(x.QuestionId))
  790. .WhereIF(isFilterAnswer, x => x.IsAnswer);
  791. var examQuestionOptions = examQuestionOptionsTable.InnerJoin(questionTable, (t, i) => t.ExamQuestionId == i.Id)
  792. .InnerJoin(examManageTable, (t, i, e) => i.ExamId == e.Id)
  793. .InnerJoin(userExamTable, (t, i, e, u) => e.Id == u.ExamId)
  794. .Select((t, i, e, u) => new ExamQuestionOptionsBak
  795. {
  796. Id = t.Id,
  797. Content = t.Content,
  798. IsAnswer = t.IsAnswer,
  799. Label = t.Label,
  800. ExamQuestionId = t.ExamQuestionId,
  801. QuestionId = t.QuestionId
  802. });
  803. return examQuestionOptions;
  804. }
  805. private async Task CalcuteTotalScore(IUserExamItemRepository userExamItemRepository, string userExamId, CancellationToken cancellationToken)
  806. {
  807. var userExam = await _repository.GetAsync(x => x.Id == userExamId);
  808. if (userExam != null)
  809. {
  810. var userExamItems = await userExamItemRepository.Queryable().Where(x => x.UserExamId == userExamId).ToListAsync();
  811. var examManageRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  812. var examManage = await examManageRepository.GetAsync(x => x.Id == userExam.ExamId);
  813. var totalScore = userExamItems.Sum(x => x.Score);
  814. userExam.Score = totalScore;
  815. userExam.IsCheck = true;
  816. userExam.ExamStatus = EExamStatus.Complete;
  817. if (examManage != null)
  818. {
  819. userExam.IsSuccess = userExam.Score > examManage.CutoffScore;
  820. }
  821. userExam.ToUpdate(_sessionContext);
  822. await _repository.UpdateWithValidateAsync(userExam, cancellationToken);
  823. }
  824. }
  825. private async Task AddExamAsync(IRepository<ExamUserExamItem> userExamItemRepository, AddUserExamItemDto addUserExamItemDto, CancellationToken cancellationToken)
  826. {
  827. var userExamItem = await AddUserExamItem(addUserExamItemDto, cancellationToken);
  828. userExamItem.UserExamItemOptionses = await AddUserExamItemOptions(addUserExamItemDto, cancellationToken);
  829. userExamItem.ExamAnswers = await AddExamAnswer(addUserExamItemDto, userExamItem.Id, cancellationToken);
  830. await userExamItemRepository.AddNav(userExamItem)
  831. .Include(x => x.UserExamItemOptionses)
  832. .Include(x => x.ExamAnswers)
  833. .ExecuteCommandAsync();
  834. }
  835. private async Task UpdateExamAsync(IRepository<ExamUserExamItem> userExamItemRepository, UpdateUserExamItemDto updateUserExamItemDto, CancellationToken cancellationToken)
  836. {
  837. var userExamItem = await UpdateUserExamItem(updateUserExamItemDto, cancellationToken);
  838. userExamItem.UserExamItemOptionses = await ModifyUserItemOptions(updateUserExamItemDto, cancellationToken);
  839. userExamItem.ExamAnswers = await UpdateExamAnswer(updateUserExamItemDto, cancellationToken);
  840. await userExamItemRepository.UpdateNav(userExamItem)
  841. .Include(x => x.UserExamItemOptionses)
  842. .Include(x => x.ExamAnswers)
  843. .ExecuteCommandAsync();
  844. }
  845. private async Task<GradingExamQuestionDto> GetNextExamQuestion(GradingExamItemDto gradingExtamItemDto)
  846. {
  847. // TODO: 获取未阅卷的第一道题
  848. var current = _userExamItemRepository.Queryable().Where(x => x.Id == gradingExtamItemDto.UserExamItemId);
  849. var userExamItemTable = _userExamItemRepository.Queryable().Where(x => !x.IsCheck);
  850. var userExamItem = current.InnerJoin(userExamItemTable, (c, u) => c.UserExamId == u.UserExamId).OrderBy((c, u) => c.SortIndex).First();
  851. if (userExamItem != null)
  852. {
  853. var testPaperItem = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.Id == userExamItem.Id && !x.QuestionType.CheckSelectType()).First();
  854. if (testPaperItem == null) return null;
  855. var gradingExamQuestionDto = new GradingExamQuestionDto();
  856. gradingExamQuestionDto = _mapper.Map<Exams.ExamManages.ExamQuestionBak, GradingExamQuestionDto>(testPaperItem, gradingExamQuestionDto);
  857. var examAnswer = new ExamRepository<ExamAnswer>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.UserExamItemId == userExamItem.Id).First();
  858. var testPaperItemAnswer = await new ExamRepository<ExamQuestionAnswerBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().FirstAsync(x => x.QuestionId == testPaperItem.QuestionId && x.ExamQuestionId == testPaperItem.Id);
  859. gradingExamQuestionDto.Answer = examAnswer.Answer ?? string.Empty;
  860. gradingExamQuestionDto.CorrectAnswer = testPaperItemAnswer != null ? testPaperItemAnswer.Answer ?? string.Empty : string.Empty;
  861. return gradingExamQuestionDto;
  862. }
  863. return null;
  864. }
  865. private async Task<List<ExamAnswer>> AddExamAnswer(AddUserExamItemDto addUserExamItemDto, string id, CancellationToken cancellationToken)
  866. {
  867. if (addUserExamItemDto.QuestionType.CheckSelectType()) return null;
  868. var examAnswers = new List<ExamAnswer>();
  869. var examAnswer = new ExamAnswer
  870. {
  871. UserId = _sessionContext.UserId,
  872. UserExamItemId = id,
  873. Answer = addUserExamItemDto.Answer
  874. };
  875. examAnswer.ToInsert(_sessionContext);
  876. await _examAnswerRepository.ValidateAddAsync(examAnswer, cancellationToken);
  877. examAnswers.Add(examAnswer);
  878. return examAnswers;
  879. }
  880. private async Task<UserExamQuestionDto> GetNextExamQuestion(AddUserExamItemDto addUserExamItemDto)
  881. {
  882. // TODO: 获取未阅卷的第一道题
  883. var testPaperItemRepository = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  884. var examRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  885. var userExamTable = _repository.Queryable().Where(x => x.Id == addUserExamItemDto.UserExamId);
  886. var userExamItemTable = _userExamItemRepository.Queryable().WhereIF(addUserExamItemDto.QuestionId.IsNotNullOrEmpty(), x => x.QuestionId == addUserExamItemDto.QuestionId);
  887. var examTable = examRepository.Queryable();
  888. var testPaperItemTable = testPaperItemRepository.Queryable();
  889. var current = examTable.InnerJoin(testPaperItemTable, (e, t) => e.Id == t.ExamId)
  890. .InnerJoin(userExamTable, (e, t, u) => e.Id == u.ExamId)
  891. .InnerJoin(userExamItemTable, (e, t, u, i) => t.QuestionId == i.QuestionId).Select((e, t, u, i) => t);
  892. var nextTable = testPaperItemTable.InnerJoin(current, (t, c) => t.SortIndex > c.SortIndex).OrderBy((t, c) => t.SortIndex).Select((t, c) => t);
  893. var userExamItem = userExamItemTable.InnerJoin(nextTable, (u, n) => u.QuestionId == n.QuestionId).OrderBy((u, n) => u.SortIndex).Select((u, n) => u).First();
  894. if (userExamItem != null)
  895. {
  896. var question = testPaperItemRepository.Queryable().Where(x => x.Id == userExamItem.Id).First();
  897. if (question == null) return null;
  898. var userExamQuestionDto = new UserExamQuestionDto();
  899. userExamQuestionDto = _mapper.Map<Exams.ExamManages.ExamQuestionBak, UserExamQuestionDto>(question, userExamQuestionDto);
  900. if (question.QuestionType.CheckSelectType())
  901. {
  902. var userExamItemOptionTable = _userExamItemOptionRepository.Queryable().Where(x => x.UserExamItemId == userExamItem.Id);
  903. var quesitonOptionTable = new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  904. var queryResult = userExamItemOptionTable.InnerJoin(quesitonOptionTable, (u, q) => u.QuestionOptionId == q.Id)
  905. .Select((u, q) => new UserExamItemOptionDto
  906. {
  907. Content = q.Content,
  908. QuestionOptionId = u.QuestionOptionId,
  909. UserExamItemId = u.UserExamItemId
  910. });
  911. userExamQuestionDto.UserExamItemOptionDtos = queryResult.ToList();
  912. }
  913. else
  914. {
  915. var examAnswer = new ExamRepository<ExamAnswer>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.UserExamItemId == userExamItem.Id).First();
  916. userExamQuestionDto.Answer = examAnswer.Answer ?? string.Empty;
  917. }
  918. return userExamQuestionDto;
  919. }
  920. else
  921. {
  922. return null;
  923. }
  924. }
  925. private async Task<List<ExamAnswer>> UpdateExamAnswer(UpdateUserExamItemDto updateUserExamItemDto, CancellationToken cancellationToken)
  926. {
  927. var examAnswerTable = _examAnswerRepository.Queryable();
  928. var userExamItemTable = _userExamItemRepository.Queryable().Where(x => x.Id == updateUserExamItemDto.Id);
  929. var examAnswer = await examAnswerTable.InnerJoin(userExamItemTable, (e, u) => e.UserExamItemId == u.Id).Select((e, u) => e).FirstAsync();
  930. if (!updateUserExamItemDto.QuestionType.CheckSelectType())
  931. {
  932. var examAnswers = new List<ExamAnswer>();
  933. if (examAnswer != null)
  934. {
  935. examAnswer.Answer = updateUserExamItemDto.Answer;
  936. examAnswer.UserId = _sessionContext.UserId;
  937. examAnswer.UserExamItemId = updateUserExamItemDto.Id;
  938. examAnswer.ToUpdate(_sessionContext);
  939. await _examAnswerRepository.UpdateWithValidateAsync(examAnswer, cancellationToken);
  940. examAnswers.Add(examAnswer);
  941. }
  942. else
  943. {
  944. examAnswer = new ExamAnswer
  945. {
  946. Answer = updateUserExamItemDto.Answer,
  947. UserId = _sessionContext.UserId,
  948. UserExamItemId = updateUserExamItemDto.Id
  949. };
  950. examAnswer.ToInsert(_sessionContext);
  951. await _examAnswerRepository.ValidateAddAsync(examAnswer, cancellationToken);
  952. examAnswers.Add(examAnswer);
  953. }
  954. return examAnswers;
  955. }
  956. return null;
  957. }
  958. private async Task<List<ExamUserExamItemOptions>> ModifyUserItemOptions(UpdateUserExamItemDto updateUserExamItemDto, CancellationToken cancellationToken)
  959. {
  960. if (updateUserExamItemDto.QuestionType.CheckSelectType())
  961. {
  962. var entityQuestionRequest = new EntityQueryRequest
  963. {
  964. Expression = ExpressionableUtility.CreateExpression<ExamUserExamItemOptions>()
  965. .AndIF(updateUserExamItemDto.Id.IsNotEmpty(), x => x.UserExamItemId == updateUserExamItemDto.Id).ToExpression()
  966. };
  967. await DeleteUserExamItemOptions(entityQuestionRequest, cancellationToken);
  968. //await UpdateUserItemOptions(updateUserExamItemDto, cancellationToken);
  969. var addUserExamItemDto = _mapper.Map<AddUserExamItemDto>(updateUserExamItemDto);
  970. addUserExamItemDto.UserExamItemOptionDtos = new List<AddUserExamItemOptionDto>();
  971. updateUserExamItemDto.UserExamItemOptionDtos.ForEach(item =>
  972. {
  973. addUserExamItemDto.UserExamItemOptionDtos.Add(_mapper.Map<AddUserExamItemOptionDto>(item));
  974. });
  975. return await AddUserExamItemOptions(addUserExamItemDto, cancellationToken);
  976. }
  977. return null;
  978. }
  979. private async Task UpdateUserItemOptions(UpdateUserExamItemDto updateUserExamItemDto, CancellationToken cancellationToken)
  980. {
  981. if (updateUserExamItemDto.QuestionType.CheckSelectType())
  982. {
  983. var userExamItemOptions = await _userExamItemOptionRepository.Queryable().Where(x => x.UserExamItemId == updateUserExamItemDto.Id).ToListAsync();
  984. var entities = new List<ExamUserExamItemOptions>();
  985. if (updateUserExamItemDto.UserExamItemOptionDtos != null)
  986. {
  987. updateUserExamItemDto.UserExamItemOptionDtos.Where(m => m.OperationStatus == EEOperationStatus.Update).ToList().ForEach(x =>
  988. {
  989. var entity = userExamItemOptions.FirstOrDefault(m => m.Id == x.Id);
  990. if (entity != null)
  991. {
  992. entities.Add(_mapper.Map<UpdateUserExamItemOptionDto, ExamUserExamItemOptions>(x, entity));
  993. }
  994. });
  995. }
  996. entities.ToUpdate(_sessionContext);
  997. await _userExamItemOptionRepository.UpdateWithValidateAsync(entities, cancellationToken);
  998. }
  999. }
  1000. private async Task<ExamUserExamItem> UpdateUserExamItem(UpdateUserExamItemDto updateUserExamItemDto, CancellationToken cancellationToken)
  1001. {
  1002. var userExamItem = await _userExamItemRepository.GetAsync(x => x.UserExamId == updateUserExamItemDto.UserExamId && x.QuestionId == updateUserExamItemDto.QuestionId);
  1003. userExamItem = _mapper.Map<UpdateUserExamItemDto, ExamUserExamItem>(updateUserExamItemDto, userExamItem);
  1004. updateUserExamItemDto.Id = userExamItem.Id;
  1005. userExamItem.ToUpdate(_sessionContext);
  1006. await _userExamItemRepository.UpdateWithValidateAsync(userExamItem, cancellationToken);
  1007. if (updateUserExamItemDto.QuestionType.CheckSelectType())
  1008. {
  1009. if (updateUserExamItemDto.UserExamItemOptionDtos != null)
  1010. {
  1011. updateUserExamItemDto.UserExamItemOptionDtos.ForEach(x => x.UserExamItemId = updateUserExamItemDto.Id);
  1012. }
  1013. }
  1014. return userExamItem;
  1015. }
  1016. private async Task<List<ExamUserExamItemOptions>> AddUserExamItemOptions(AddUserExamItemDto addUserExamItemDto, CancellationToken cancellationToken)
  1017. {
  1018. var userExamItemOptions = new List<ExamUserExamItemOptions>();
  1019. if (addUserExamItemDto.QuestionType.CheckSelectType())
  1020. {
  1021. if (addUserExamItemDto.UserExamItemOptionDtos != null)
  1022. {
  1023. addUserExamItemDto.UserExamItemOptionDtos.ToList().ForEach(x =>
  1024. {
  1025. userExamItemOptions.Add(_mapper.Map<ExamUserExamItemOptions>(x));
  1026. });
  1027. }
  1028. }
  1029. userExamItemOptions.ToInsert(_sessionContext);
  1030. await _userExamItemOptionRepository.ValidateAddAsync(userExamItemOptions, cancellationToken);
  1031. return userExamItemOptions;
  1032. }
  1033. private async Task<ExamUserExamItem> AddUserExamItem(AddUserExamItemDto addUserExamItemDto, CancellationToken cancellationToken)
  1034. {
  1035. var userExamItem = _mapper.Map<ExamUserExamItem>(addUserExamItemDto);
  1036. userExamItem.ToInsert(_sessionContext);
  1037. await _userExamItemRepository.ValidateAddAsync(userExamItem, cancellationToken);
  1038. if (addUserExamItemDto.QuestionType.CheckSelectType())
  1039. {
  1040. if (addUserExamItemDto.UserExamItemOptionDtos != null)
  1041. {
  1042. addUserExamItemDto.UserExamItemOptionDtos.ForEach(x => x.UserExamItemId = userExamItem.Id);
  1043. }
  1044. }
  1045. return userExamItem;
  1046. }
  1047. private async Task DeleteUserExamItemOptions(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken)
  1048. {
  1049. await _userExamItemOptionRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken);
  1050. }
  1051. private SqlSugar.ISugarQueryable<UserExamResultViewResponse> GetQueryable(UserExamPagedRequest queryRequest)
  1052. {
  1053. if (_sessionContext.UserId != null)
  1054. {
  1055. queryRequest.UserId = _sessionContext.UserId;
  1056. }
  1057. var expression = queryRequest.GetExpression();
  1058. var userExamTable = _repository.Queryable().Where(expression);
  1059. var examManageExpression = queryRequest.GetExamManageExpression();
  1060. var examManageTable = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(examManageExpression);
  1061. var queryable = userExamTable.InnerJoin(examManageTable, (u, e) => u.ExamId == e.Id).Select((u, e) => new UserExamResultViewResponse
  1062. {
  1063. Id = u.Id,
  1064. CutoffScore = e.CutoffScore,
  1065. TotalScore = e.TotalScore,
  1066. ExamName = e.Name,
  1067. Score = u.Score ?? 0,
  1068. Status = u.Status,
  1069. SortIndex = u.SortIndex,
  1070. ExamStatus = u.ExamStatus == EExamStatus.Absent? EExamStatus.Complete: u.ExamStatus,
  1071. IsSuccess = u.IsCheck ? u.IsSuccess : null,
  1072. EndTime = e.EndTime,
  1073. StartTime = e.StartTime,
  1074. TimeSpan = e.TimeSpan,
  1075. ExamType = e.ExamType,
  1076. ExamId = e.Id,
  1077. IsCheck = u.IsCheck,
  1078. IsReExam = u.IsReExam,
  1079. CanReExam = SqlFunc.Subqueryable<ExamUserExamItem>().Where(x => x.UserExamId == u.Id).Count() < e.Count
  1080. });
  1081. return queryable;
  1082. }
  1083. public async Task<List<ViewExamQuestionDto>> View(string id)
  1084. {
  1085. List<ViewExamQuestionDto> viewExamQuestionDtos = await GetViewExamQuestion(id, null);
  1086. var examQuestionIds = viewExamQuestionDtos.Select(x => x.ExamQuestionId).ToList();
  1087. var questionIds = viewExamQuestionDtos.Select(x => x.QuestionId).ToList();
  1088. var userExamIds = new List<string>
  1089. {
  1090. id
  1091. };
  1092. //List<ViewQuestionAnswerDto> questionAnswers = await GetQuestionAnswers(id, questionIds);
  1093. List<ViewQuestionOptionDto> questionOptions = await GetQuestionOptions(questionIds, userExamIds);
  1094. List<QuestionKnowladgeDto> questionKnowladges = await GetQuestionKnowladges(examQuestionIds);
  1095. List<QuestionSourcewareDto> sourcewares = await GetSourcewares(examQuestionIds);
  1096. ResolveExamQuestions(viewExamQuestionDtos, questionOptions, questionKnowladges, sourcewares);
  1097. return viewExamQuestionDtos;
  1098. }
  1099. public async Task<ViewExamQuestionDto> View(string id, string questionId)
  1100. {
  1101. List<ViewExamQuestionDto> viewExamQuestionDtos = await GetViewExamQuestion(id, questionId);
  1102. var examQuestionIds = viewExamQuestionDtos.Select(x => x.ExamQuestionId).ToList();
  1103. var questionIds = viewExamQuestionDtos.Select(x => x.QuestionId).ToList();
  1104. var userExamIds = new List<string>
  1105. {
  1106. id
  1107. };
  1108. //List<ViewQuestionAnswerDto> questionAnswers = await GetQuestionAnswers(id, questionIds);
  1109. List<ViewQuestionOptionDto> questionOptions = await GetQuestionOptions(questionIds, userExamIds);
  1110. List<QuestionKnowladgeDto> questionKnowladges = await GetQuestionKnowladges(examQuestionIds);
  1111. List<QuestionSourcewareDto> sourcewares = await GetSourcewares(examQuestionIds);
  1112. ResolveExamQuestions(viewExamQuestionDtos, questionOptions, questionKnowladges, sourcewares);
  1113. return viewExamQuestionDtos.FirstOrDefault();
  1114. }
  1115. private static void ResolveExamQuestions(List<ViewExamQuestionDto> viewExamQuestionDtos, List<ViewQuestionOptionDto> questionOptions, List<QuestionKnowladgeDto> questionKnowladges, List<QuestionSourcewareDto> sourcewares)
  1116. {
  1117. viewExamQuestionDtos.ForEach(item =>
  1118. {
  1119. item.QuestionKnowladgeDtos = questionKnowladges.Where(x => x.QuestionId == item.ExamQuestionId).ToList();
  1120. item.QuestionSourcewareDtos = sourcewares.Where(x => x.QuestionId == item.ExamQuestionId).ToList();
  1121. if (item.QuestionType.CheckSelectType())
  1122. {
  1123. item.QuestionOptions = questionOptions.Where(x => x.QuestionId == item.ExamQuestionId).ToList();
  1124. item.CorrectAnswer = string.Join(",", item.QuestionOptions.Where(m => m.IsAnswer).Select(m => m.Label).ToArray());
  1125. }
  1126. });
  1127. }
  1128. private async Task<List<QuestionSourcewareDto>> GetSourcewares(List<string> questionIds)
  1129. {
  1130. var questionSourcewareTable = new ExamRepository<ExamQuestionSourcewareBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  1131. var sourcewareTable = new ExamRepository<ExamSourceware>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  1132. var querable = questionSourcewareTable.InnerJoin<ExamQuestionSourceware>((qsb, qs) => qsb.SourcewareId == qs.Id).InnerJoin(sourcewareTable, (qsb, qs, s) => qs.SourcewareId == s.Id).Select((qsb, qs, s) => new QuestionSourcewareDto
  1133. {
  1134. Id = qs.Id,
  1135. Name = s.Name,
  1136. QuestionId = qsb.ExamQuestionId,
  1137. SourcewareId = s.Id,
  1138. AttachmentId = s.AttachmentId
  1139. }).MergeTable().Where(x => questionIds.Contains(x.QuestionId));
  1140. return await querable.ToListAsync();
  1141. }
  1142. private async Task<List<QuestionKnowladgeDto>> GetQuestionKnowladges(List<string> questionIds)
  1143. {
  1144. var questionKnowladgeTable = new ExamRepository<ExamQuestionKnowladgeBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  1145. return await questionKnowladgeTable.Where(x => questionIds.Contains(x.ExamQuestionId))
  1146. .InnerJoin<ExamQuestionKnowladge>((kb, k) => kb.KnowladgeId == k.Id).Select((kb, k) => new QuestionKnowladgeDto
  1147. {
  1148. Id = kb.Id,
  1149. QuestionId = kb.ExamQuestionId,
  1150. KnowladgeId = k.KnowladgeId,
  1151. Title = kb.Title
  1152. }).ToListAsync();
  1153. }
  1154. private async Task<List<ViewQuestionOptionDto>> GetQuestionOptions(List<string> questionIds, List<string> userExamIds)
  1155. {
  1156. var selectQuestionOptions = GetQuestionOptionBaks(questionIds, userExamIds, false).MergeTable();
  1157. var userExamItemOptionTable = _userExamItemOptionRepository.Queryable();
  1158. var querable = selectQuestionOptions
  1159. .LeftJoin(userExamItemOptionTable, (op, uio) => op.Id == uio.QuestionOptionId)
  1160. .Select((op, uio) => new ViewQuestionOptionDto
  1161. {
  1162. Content = op.Content,
  1163. Id = op.Id,
  1164. IsAnswer = op.IsAnswer,
  1165. Label = op.Label,
  1166. QuestionId = op.ExamQuestionId,
  1167. IsSelected = uio.Id != null
  1168. }).MergeTable().OrderBy(x => x.Label);
  1169. return await querable.Distinct()
  1170. .ToListAsync();
  1171. }
  1172. private async Task<List<ViewQuestionAnswerDto>> GetQuestionAnswers(string id, List<string> questionIds)
  1173. {
  1174. var userExamTable = _repository.Queryable().Where(x => x.Id == id);
  1175. var userExamItemTable = _userExamItemRepository.Queryable();
  1176. var examAnswerTable = _examAnswerRepository.Queryable();
  1177. var questionTable = new ExamRepository<ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  1178. var questionAnswerTable = new ExamRepository<ExamQuestionAnswerBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  1179. var querable = examAnswerTable
  1180. .InnerJoin(userExamItemTable, (a, ui) => ui.Id == a.UserExamItemId && ui.UserExamId == id)
  1181. .LeftJoin(questionAnswerTable, (a, ui, qab) => qab.QuestionId == ui.QuestionId)
  1182. .LeftJoin<ExamQuestionAnswer>((a, ui, qab, qa) => qab.QuestionAnswerId == qa.Id)
  1183. .LeftJoin(questionTable, (a, ui, qab, qa, q) => qab.QuestionId == q.QuestionId && questionIds.Contains(q.Id))
  1184. .Select((a, ui, qab, qa, q) => new ViewQuestionAnswerDto
  1185. {
  1186. Answer = a.Answer,
  1187. CorrectAnswer = qa.Answer != null ? qa.Answer : string.Empty,
  1188. QuestionId = q.Id
  1189. }).MergeTable();
  1190. return await querable.ToListAsync();
  1191. }
  1192. private async Task<List<ViewExamQuestionDto>> GetViewExamQuestion(string id, string questionId)
  1193. {
  1194. var expression = ExpressionableUtility.CreateExpression<ExamUserExam>()
  1195. .And(x => x.Id == id).ToExpression();
  1196. ISugarQueryable<GradingExamQuestionTempDto> queryable = GetViewExamQuestionTempDtos(expression);
  1197. queryable = queryable.MergeTable().WhereIF(!string.IsNullOrEmpty(questionId), x => x.QuestionId == questionId);
  1198. var queryResult = await queryable.ToListAsync();
  1199. var viewExamQuestion = queryResult.GroupBy(x => new
  1200. {
  1201. Id = x.Id,
  1202. QuestionType = x.QuestionType
  1203. }).Select(g => new ViewExamQuestionDto
  1204. {
  1205. Answer = g.FirstOrDefault().Answer,
  1206. QuestionType = g.Key.QuestionType,
  1207. QuestionId = g.FirstOrDefault().QuestionId,
  1208. ExamQuestionId = g.FirstOrDefault().ExamQuestionId,
  1209. Id = g.Key.Id,
  1210. Score = g.FirstOrDefault().QuestionScore,
  1211. RealScore = g.FirstOrDefault().Score,
  1212. Title = g.FirstOrDefault().Title,
  1213. CorrectAnswer = g.Key.QuestionType.CheckSelectType() ? string.Empty : g.FirstOrDefault()?.CorrectAnswer
  1214. }).ToList();
  1215. return viewExamQuestion;
  1216. }
  1217. #endregion
  1218. }
  1219. }