UserExamService.cs 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  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. namespace Hotline.Application.Exam.Service.ExamManages
  44. {
  45. public class UserExamService : ApiService<ExamUserExam, AddUserExamDto, UpdateUserExamDto, HotlineDbContext>, IUserExamService, IScopeDependency
  46. {
  47. private readonly IUserExamRepository _repository;
  48. private readonly IUserExamItemRepository _userExamItemRepository;
  49. private readonly IUserExamItemOptionRepository _userExamItemOptionRepository;
  50. private readonly IExamAnswerRepository _examAnswerRepository;
  51. private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder;
  52. private readonly IServiceProvider _serviceProvider;
  53. private readonly IMapper _mapper;
  54. private readonly ISessionContext _sessionContext
  55. ;
  56. public UserExamService(IUserExamRepository repository,
  57. IUserExamItemRepository userExamItemRepository,
  58. IUserExamItemOptionRepository userExamItemOptionRepository,
  59. IExamAnswerRepository examAnswerRepository,
  60. IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider,
  61. IMapper mapper, ISessionContext sessionContext) : base(repository, mapper, sessionContext)
  62. {
  63. this._repository = repository;
  64. this._userExamItemRepository = userExamItemRepository;
  65. this._userExamItemOptionRepository = userExamItemOptionRepository;
  66. this._examAnswerRepository = examAnswerRepository;
  67. this._dataPermissionFilterBuilder = dataPermissionFilterBuilder;
  68. this._serviceProvider = serviceProvider;
  69. this._mapper = mapper;
  70. this._sessionContext = sessionContext;
  71. }
  72. #region public method
  73. public Task<UserExamDto> GetAsync(EntityQueryRequest entityQueryRequest)
  74. {
  75. throw new NotImplementedException();
  76. }
  77. public Task<(int, List<UserExamResultViewResponse>)> GetListAsync(UserExamPagedRequest queryRequest)
  78. {
  79. throw new NotImplementedException();
  80. }
  81. public async Task<ExamQuestionDto> GetExamQuestionDto(ExamQuestionRequest examQuestionRequest)
  82. {
  83. var expression = examQuestionRequest.GetExpression();
  84. var quesetion = await new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(expression).FirstAsync();
  85. if (quesetion != null)
  86. {
  87. var examQuestionDto = _mapper.Map<ExamQuestionDto>(quesetion);
  88. if (examQuestionDto.QuestionType.CheckSelectType())
  89. {
  90. var questionOptions = await new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.ExamQuestionId == quesetion.Id).ToListAsync();
  91. List<ExamUserExamItemOptions> userItemItemOptions = await GetUserExteamItemOptios(quesetion);
  92. if (questionOptions != null)
  93. {
  94. examQuestionDto.QuestionOptions = new List<ExamQuestionOptionsDto>();
  95. questionOptions.ForEach(item =>
  96. {
  97. var examQuestionOptionsDto = _mapper.Map<ExamQuestionOptionsDto>(item);
  98. if (userItemItemOptions != null)
  99. {
  100. examQuestionOptionsDto.IsSelected = userItemItemOptions.Any(m => m.QuestionOptionId == item.Id);
  101. }
  102. examQuestionDto.QuestionOptions.Add(examQuestionOptionsDto);
  103. });
  104. }
  105. }
  106. else
  107. {
  108. List<ExamAnswer> examAnswers = await GetExamAnswers(examQuestionRequest);
  109. examQuestionDto.Answer = examAnswers != null ? examAnswers.FirstOrDefault()?.Answer : null;
  110. }
  111. return examQuestionDto;
  112. }
  113. else
  114. {
  115. throw new UserFriendlyException(ExamErrorMessage.ServiceError, string.Format(ExamErrorMessage.IsNotExists, string.Concat(typeof(ExamQuestion).GetDescription(), ":", examQuestionRequest.QuestionId)));
  116. }
  117. }
  118. private async Task<List<ExamAnswer>> GetExamAnswers(ExamQuestionRequest examQuestionRequest)
  119. {
  120. var examAnswerRepository = new ExamRepository<ExamAnswer>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  121. var userExamItemRepository = new ExamRepository<ExamUserExamItem>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  122. var userExamItemTable = userExamItemRepository.Queryable().Where(i=> i.QuestionId == examQuestionRequest.QuestionId);
  123. var userExamTable = _repository.Queryable().Where(u=> u.UserId == _sessionContext.UserId);
  124. var examAnswerTable = examAnswerRepository.Queryable();
  125. var examAnswers = await examAnswerTable.InnerJoin(userExamItemTable, (e, i) => e.UserExamItemId == i.Id)
  126. .InnerJoin(userExamTable, (e, i, u) => i.UserExamId == u.Id)
  127. .Select((e, i, u) => e).ToListAsync();
  128. return examAnswers;
  129. }
  130. private async Task<List<ExamUserExamItemOptions>> GetUserExteamItemOptios(Exams.ExamManages.ExamQuestionBak quesetion)
  131. {
  132. var userExamItemOptionsRepository = new ExamRepository<ExamUserExamItemOptions>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  133. var userExamItemOptionsTable = userExamItemOptionsRepository.Queryable();
  134. var userExamItemTable = _userExamItemRepository.Queryable();
  135. var userExamTable = _repository.Queryable();
  136. var userItemItemOptions = await userExamItemOptionsTable
  137. .InnerJoin(userExamItemTable, (o, u) => o.UserExamItemId == u.Id)
  138. .InnerJoin(userExamTable, (o, u, e) => u.UserExamId == e.Id)
  139. .Where((o, u, e) => u.QuestionId == quesetion.QuestionId && e.UserId == _sessionContext.UserId).
  140. Select((o, u, e) => o).ToListAsync();
  141. return userItemItemOptions;
  142. }
  143. public async Task<List<ExamQuestionViewResponse>> GetExamQuestionViewResponses(ExamQuestionGroupRequest examQuestionGroupRequest)
  144. {
  145. if (examQuestionGroupRequest.ExamId.IsNull() && examQuestionGroupRequest.UserId.IsNull())
  146. throw UserFriendlyException.SameMessage("查询参数不能为空");
  147. var expression = examQuestionGroupRequest.GetExpression();
  148. var examManageTable = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(expression);
  149. var testPaperItemTable = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  150. var queryable = await examManageTable.InnerJoin(testPaperItemTable, (e, i) => e.Id == i.ExamId)
  151. .Select((e, i) => i).ToListAsync();
  152. var result = queryable.GroupBy(x => x.QuestionType).Select(m => new ExamQuestionViewResponse
  153. {
  154. QuestionType = m.Key,
  155. Questions = m.Select(n => new SimpleViewResponse
  156. {
  157. Id = n.QuestionId
  158. }).ToList()
  159. }).ToList();
  160. return result;
  161. }
  162. public async Task<List<GradingQuestionViewResponce>> GetGradingQuestionViewResponces(ExamQuestionGroupRequest examQuestionGroupRequest)
  163. {
  164. var expression = examQuestionGroupRequest.GetExpression();
  165. var examManageTable = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(expression);
  166. var testPaperItemTable = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  167. var queryable = await examManageTable.InnerJoin(testPaperItemTable, (e, i) => e.Id == i.ExamId)
  168. .Select((e, i) => i).ToListAsync();
  169. var examQuestionScores = await new ExamRepository<ExamQuestionScoreBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.ExamManageId == examQuestionGroupRequest.ExamId).ToListAsync();
  170. var userExamItemTable = _userExamItemRepository.Queryable();
  171. var userExamTable = _repository.Queryable().Where(x => x.ExamId == examQuestionGroupRequest.ExamId && x.UserId == examQuestionGroupRequest.UserId);
  172. var userExamItems = await userExamItemTable.InnerJoin(userExamTable, (i, u) => i.UserExamId == u.Id)
  173. .Select((i, u) => i).ToListAsync();
  174. var result = queryable.GroupBy(x => x.QuestionType).Select(m => new GradingQuestionViewResponce
  175. {
  176. QuestionType = m.Key,
  177. Questions = m.Select(n => new GradingExamViewResponse
  178. {
  179. IsCorrect = CheckCorrect(n, examQuestionScores, userExamItems),
  180. Id = userExamItems.FirstOrDefault(x => x.QuestionId == n.QuestionId)?.Id ?? n.Id
  181. }).ToList()
  182. }).ToList();
  183. return result;
  184. }
  185. private bool CheckCorrect(Exams.ExamManages.ExamQuestionBak n, List<ExamQuestionScoreBak> examQuestionScores, List<ExamUserExamItem> userExamItems)
  186. {
  187. var examQuestionScore = examQuestionScores.FirstOrDefault(x => x.QuestionType == n.QuestionType);
  188. var userItem = userExamItems.FirstOrDefault(x => x.QuestionId == n.QuestionId);
  189. if (userItem != null && examQuestionScore != null)
  190. {
  191. return userItem.Score == examQuestionScore.Score;
  192. }
  193. return false;
  194. }
  195. public async Task<PageViewResponse<UserExamResultViewResponse>> GetPagedListAsync(UserExamPagedRequest queryRequest)
  196. {
  197. SqlSugar.ISugarQueryable<UserExamResultViewResponse> queryable = GetQueryable(queryRequest);
  198. var list = await queryable.ToPageListAsync(queryRequest.PageIndex, queryRequest.PageSize);
  199. var total = await queryable.CountAsync();
  200. var result = new UserExamResultPageViewResponse
  201. {
  202. Items = list,
  203. Pagination = new Pagination(queryRequest.PageIndex, queryRequest.PageSize, total)
  204. };
  205. return result;
  206. }
  207. public async Task<GradingExamQuestionDto> GradingAsync(GradingExamItemDto gradingExtamItemDto, CancellationToken cancellationToken)
  208. {
  209. var userExamItem = await _userExamItemRepository.GetAsync(m => m.Id == gradingExtamItemDto.UserExamItemId);
  210. if (userExamItem != null)
  211. {
  212. userExamItem = _mapper.Map<GradingExamItemDto, ExamUserExamItem>(gradingExtamItemDto, userExamItem);
  213. await _userExamItemRepository.ValidateUpdateAsync(userExamItem, cancellationToken);
  214. }
  215. return await GetNextExamQuestion(gradingExtamItemDto);
  216. }
  217. public async Task SubmitAsync(SubmitExamDto submitExamDto, CancellationToken cancellationToken)
  218. {
  219. var userExam = await _repository.GetAsync(x => x.Id == submitExamDto.Id);
  220. if (userExam != null)
  221. {
  222. userExam = _mapper.Map<SubmitExamDto, ExamUserExam>(submitExamDto, userExam);
  223. await _repository.ValidateUpdateAsync(userExam, cancellationToken);
  224. }
  225. }
  226. public async Task<StartExamViewResponse> ExamAsync(UpdateUserExamItemDto addUserExamItemDto, CancellationToken cancellationToken)
  227. {
  228. var userExam = await new ExamRepository<ExamUserExam>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.Id == addUserExamItemDto.UserExamId).FirstAsync();
  229. var startExamViewResponse = await CheckExamValid(userExam);
  230. if (!startExamViewResponse.CheckValidate())
  231. {
  232. return startExamViewResponse;
  233. }
  234. var hasUserExamItem = _userExamItemRepository.Queryable().Where(x => x.UserExamId == addUserExamItemDto.UserExamId && x.QuestionId == addUserExamItemDto.QuestionId).Any();
  235. if (!hasUserExamItem)
  236. {
  237. await AddExamAsync(_userExamItemRepository, addUserExamItemDto, cancellationToken);
  238. }
  239. else
  240. {
  241. await UpdateExamAsync(_userExamItemRepository, addUserExamItemDto, cancellationToken);
  242. }
  243. await CalcuteExamItemScore(_userExamItemRepository, addUserExamItemDto, cancellationToken);
  244. return startExamViewResponse;
  245. }
  246. public async Task<StartExamViewResponse> StartUserExamAsync(StartUserExamDto startUserExamDto, CancellationToken cancellationToken)
  247. {
  248. var userExam = await _repository.GetAsync(x => x.Id == startUserExamDto.Id);
  249. if (userExam == null) return new StartExamViewResponse
  250. {
  251. IsJoin = false
  252. };
  253. if (userExam.StartTime == null)
  254. userExam.StartTime = DateTime.Now;
  255. var startExamViewResponse = await CheckExamValid(userExam);
  256. if (!startExamViewResponse.CheckValidate())
  257. {
  258. return startExamViewResponse;
  259. }
  260. userExam.ExamStatus = Share.Enums.Exams.EExamStatus.Executing;
  261. userExam.ToUpdate(_sessionContext);
  262. await _repository.UpdateWithValidateAsync(userExam, cancellationToken);
  263. var examManage = await new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).GetAsync(x => x.Id == userExam.ExamId);
  264. return new StartExamViewResponse
  265. {
  266. StartTime = userExam.StartTime,
  267. TimeSpan = examManage?.TimeSpan,
  268. IsCompleted = false
  269. };
  270. }
  271. private async Task<StartExamViewResponse> CheckExamValid(ExamUserExam examUserExam)
  272. {
  273. var examManageRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  274. var examManage = await examManageRepository.Queryable().Where(x => x.Id == examUserExam.ExamId).FirstAsync();
  275. var startExamViewResponse = new StartExamViewResponse
  276. {
  277. IsJoin = true,
  278. IsCompleted = false
  279. };
  280. if (examManage != null)
  281. {
  282. var examStrategyProxy = new ExamStrategyProxy();
  283. var examStrategys = new List<IExamStrategy>();
  284. startExamViewResponse = AddCheckStartTimeStrategy(examUserExam, examManage, startExamViewResponse, examStrategys);
  285. startExamViewResponse = AddCheckEndTimeStrategy(examUserExam, examManage, startExamViewResponse, examStrategys);
  286. startExamViewResponse = AddCheckValidateTimeStrategy(examUserExam, examManage, startExamViewResponse, examStrategys);
  287. startExamViewResponse = AddCheckValidateCountStrategy(examUserExam, examManage, startExamViewResponse, examStrategys);
  288. if (!examStrategyProxy.Validate())
  289. {
  290. return startExamViewResponse;
  291. }
  292. }
  293. startExamViewResponse.IsStart = true;
  294. return startExamViewResponse;
  295. }
  296. private StartExamViewResponse AddCheckValidateCountStrategy(ExamUserExam examUserExam, ExamManage examManage, StartExamViewResponse startExamViewResponse, List<IExamStrategy> examStrategys)
  297. {
  298. if (examManage.ExamType == Share.Enums.Exams.EExamType.Simulate)
  299. {
  300. var checkStartTime = new CheckValidateCountStrategy(1, 1)
  301. {
  302. CallBack = () =>
  303. {
  304. startExamViewResponse = new StartExamViewResponse
  305. {
  306. IsJoin = false,
  307. IsStart = false,
  308. IsCompleted = true
  309. };
  310. }
  311. };
  312. examStrategys.Add(checkStartTime);
  313. return startExamViewResponse;
  314. }
  315. else
  316. {
  317. var count = new ExamRepository<ExamUserExam>(_uow, _dataPermissionFilterBuilder, _serviceProvider).CountAsync(x => x.ExamId == examManage.Id && x.UserId == examUserExam.UserId).Result;
  318. var checkStartTime = new CheckValidateCountStrategy(examManage.Count, count)
  319. {
  320. CallBack = () =>
  321. {
  322. startExamViewResponse = new StartExamViewResponse
  323. {
  324. IsJoin = false,
  325. IsStart = false,
  326. IsCompleted = true
  327. };
  328. }
  329. };
  330. examStrategys.Add(checkStartTime);
  331. return startExamViewResponse;
  332. }
  333. }
  334. private StartExamViewResponse AddCheckValidateTimeStrategy(ExamUserExam examUserExam, ExamManage examManage, StartExamViewResponse startExamViewResponse, List<IExamStrategy> examStrategys)
  335. {
  336. if (examManage.ExamType == Share.Enums.Exams.EExamType.Simulate) return startExamViewResponse;
  337. var checkStartTime = new CheckValidateTimeStrategy(examManage.TimeSpan, examUserExam.StartTime)
  338. {
  339. CallBack = () =>
  340. {
  341. startExamViewResponse = new StartExamViewResponse
  342. {
  343. IsJoin = false,
  344. IsStart = false,
  345. IsCompleted = true
  346. };
  347. }
  348. };
  349. examStrategys.Add(checkStartTime);
  350. return startExamViewResponse;
  351. }
  352. private StartExamViewResponse AddCheckEndTimeStrategy(ExamUserExam examUserExam, ExamManage examManage, StartExamViewResponse startExamViewResponse, List<IExamStrategy> examStrategys)
  353. {
  354. if (examManage.ExamType == Share.Enums.Exams.EExamType.Simulate) return startExamViewResponse;
  355. var checkStartTime = new CheckEndTimeStrategy(examManage.EndTime, DateTime.Now)
  356. {
  357. CallBack = () =>
  358. {
  359. startExamViewResponse = new StartExamViewResponse
  360. {
  361. IsJoin = false,
  362. IsStart = false,
  363. IsCompleted = true
  364. };
  365. }
  366. };
  367. examStrategys.Add(checkStartTime);
  368. return startExamViewResponse;
  369. }
  370. private static StartExamViewResponse AddCheckStartTimeStrategy(ExamUserExam examUserExam, ExamManage examManage, StartExamViewResponse startExamViewResponse, List<IExamStrategy> examStrategys)
  371. {
  372. if (examManage.ExamType == Share.Enums.Exams.EExamType.Simulate) return startExamViewResponse;
  373. var checkStartTime = new CheckStartTimeStrategy(examManage.StartTime, examUserExam.StartTime)
  374. {
  375. CallBack = () =>
  376. {
  377. startExamViewResponse = new StartExamViewResponse
  378. {
  379. IsJoin = false,
  380. IsStart = false,
  381. IsCompleted = false
  382. };
  383. }
  384. };
  385. examStrategys.Add(checkStartTime);
  386. return startExamViewResponse;
  387. }
  388. public async Task CompleteGradingAsync(GradingExamDto gradingExtamDto, CancellationToken cancellationToken)
  389. {
  390. var userExam = await _repository.GetAsync(x => x.Id == gradingExtamDto.Id);
  391. if (userExam == null) return;
  392. var userExamItems = await _userExamItemRepository.Queryable().Where(x => x.UserExamId == gradingExtamDto.Id).ToListAsync();
  393. if (userExamItems != null)
  394. {
  395. var totalScore = userExamItems.Sum(x => x.Score);
  396. userExam.Score = totalScore;
  397. var examManage = await new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).GetAsync(x => x.Id == userExam.ExamId);
  398. userExam.IsSuccess = totalScore >= examManage.CutoffScore;
  399. userExam.ExamStatus = Share.Enums.Exams.EExamStatus.Complete;
  400. userExam.ToUpdate(_sessionContext);
  401. await _repository.ValidateUpdateAsync(userExam, cancellationToken);
  402. }
  403. }
  404. public async Task<List<GradingExamQuestionDto>> GetGradingExamQuestion(GradingExamRequest gradingExamRequest)
  405. {
  406. var expression = gradingExamRequest.GetExpression();
  407. var userExamTable = _repository.Queryable().Where(expression);
  408. var questionScoreRepository = new ExamRepository<ExamQuestionScoreBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  409. var userExamItemTable = _userExamItemRepository.Queryable();
  410. var userExamItemOptionTable = _userExamItemOptionRepository.Queryable();
  411. var examAnswerTable = new ExamRepository<ExamAnswer>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  412. var questionTable = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  413. var quesitonOptionTable = new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  414. var testPaperItemAnswerTable = new ExamRepository<ExamQuestionAnswerBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  415. var questionScoreTable = questionScoreRepository.Queryable();
  416. var queryable = userExamTable.InnerJoin(userExamItemTable, (e, i) => e.Id == i.UserExamId)
  417. .InnerJoin(questionTable, (e, i, q) => i.QuestionId == q.Id)
  418. .LeftJoin(userExamItemOptionTable, (e, i, q, o) => i.Id == o.UserExamItemId)
  419. .LeftJoin(quesitonOptionTable, (e, i, q, o, qo) => o.QuestionOptionId == qo.Id)
  420. .LeftJoin(examAnswerTable, (e, i, q, o, qo, a) => i.Id == a.UserExamItemId)
  421. .LeftJoin(testPaperItemAnswerTable, (e, i, q, o, qo, a, ta) => ta.QuestionId == qo.QuestionId)
  422. .InnerJoin(questionScoreTable, (e, i, q, o, qo, a, ta, s) => q.QuestionType == s.QuestionType && e.ExamId == s.ExamManageId)
  423. .Where((e, i, q, o, qo, a, ta, s) => q.QuestionType == EQuestionType.Single || q.QuestionType == EQuestionType.Multi || q.QuestionType == EQuestionType.Judge)
  424. .Select(
  425. (e, i, q, o, qo, a, ta, s) => new GradingExamQuestionTempDto
  426. {
  427. Id = i.Id,
  428. QuestionType = q.QuestionType,
  429. CorrectAnswer = ta.Id != null ? ta.Answer : string.Empty,
  430. Answer = a.Id != null ? a.Answer : string.Empty,
  431. Title = q.Title,
  432. QuestionOptionId = o.Id,
  433. UserExamItemId = i.Id,
  434. Content = qo.Content,
  435. Label = qo.Label,
  436. IsAnswer = qo.IsAnswer,
  437. IsSelected = o.Id != null,
  438. Score = s.Score
  439. }
  440. );
  441. var queryResult = await queryable.ToListAsync();
  442. var gradingExamQuestionDtos = queryResult.GroupBy(x => new
  443. {
  444. Id = x.Id,
  445. QuestionType = x.QuestionType
  446. }).Select(g => new GradingExamQuestionDto
  447. {
  448. Answer = g.FirstOrDefault().Answer,
  449. QuestionType = g.Key.QuestionType,
  450. Id = g.Key.Id,
  451. Score = g.FirstOrDefault().Score,
  452. Title = g.FirstOrDefault().Title,
  453. CorrectAnswer = g.Key.QuestionType.CheckSelectType() ? string.Join(",", g.Where(i => i.IsAnswer).Select(n => n.Label)) : g.FirstOrDefault()?.CorrectAnswer
  454. }).ToList();
  455. return gradingExamQuestionDtos;
  456. }
  457. public async Task<GradingExamQuestionDto> ViewGradingExamQuestion(ViewGradingExamRequest viewGradingExamRequest)
  458. {
  459. var gradingExtamItemDto = _mapper.Map<ViewGradingExamRequest, GradingExamItemDto>(viewGradingExamRequest);
  460. return await GetNextExamQuestion(gradingExtamItemDto);
  461. }
  462. public async Task<UnExamUserPageViewResponse> GetUnExamUsers(UnExamUserReportPagedRequest unExamUserReportPagedRequest)
  463. {
  464. unExamUserReportPagedRequest.ResoleEndTime();
  465. var examManageRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  466. var userRepository = new ExamRepository<User>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  467. var expression = unExamUserReportPagedRequest.GetExpression();
  468. var userExamExpression = unExamUserReportPagedRequest.GetUserExamExpression();
  469. var examManageTable = examManageRepository.Queryable().Where(expression);
  470. var userTable = userRepository.Queryable();
  471. var userExamTable = _repository.Queryable().Where(userExamExpression);
  472. var queryResult = userExamTable.InnerJoin(examManageTable, (ue, e) => ue.ExamId == e.Id)
  473. .InnerJoin(userTable, (ue, e, u) => ue.UserId == u.Id)
  474. .Select((ue, e, u) => new UnExamUserViewResponse
  475. {
  476. ExamName = e.Name,
  477. OrgName = u.Organization.Name,
  478. UserName = u.Name
  479. });
  480. var total = await queryResult.CountAsync();
  481. var items = await queryResult.ToPageListAsync(unExamUserReportPagedRequest.PageIndex, unExamUserReportPagedRequest.PageSize);
  482. return new UnExamUserPageViewResponse
  483. {
  484. Items = items,
  485. Pagination = new Pagination(unExamUserReportPagedRequest.PageIndex, unExamUserReportPagedRequest.PageSize, total)
  486. };
  487. }
  488. public async Task<UserExamResultPageViewResponse> GetUserExamResults(UserExamResultReportPagedRequest userExamResultReportPagedRequest)
  489. {
  490. userExamResultReportPagedRequest.ResoleEndTime();
  491. var examManageRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  492. var userRepository = new ExamRepository<User>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  493. var expression = userExamResultReportPagedRequest.GetExpression();
  494. var userExamExpression = userExamResultReportPagedRequest.GetUserExamExpression();
  495. var examManageTable = examManageRepository.Queryable().Where(expression);
  496. var userTable = userRepository.Queryable();
  497. var userExamTable = _repository.Queryable().Where(userExamExpression);
  498. var queryResult = userExamTable.InnerJoin(examManageTable, (ue, e) => ue.ExamId == e.Id)
  499. .InnerJoin(userTable, (ue, e, u) => ue.UserId == u.Id)
  500. .Select((ue, e, u) => new UserExamResultViewResponse
  501. {
  502. ExamName = e.Name,
  503. OrgName = u.Organization.Name,
  504. UserName = u.Name,
  505. TotalScore = e.TotalScore,
  506. CutoffScore = e.CutoffScore,
  507. Score = ue.Score ?? 0,
  508. });
  509. var total = await queryResult.CountAsync();
  510. var items = await queryResult.ToPageListAsync(userExamResultReportPagedRequest.PageIndex, userExamResultReportPagedRequest.PageSize);
  511. return new UserExamResultPageViewResponse
  512. {
  513. Items = items,
  514. Pagination = new Pagination(userExamResultReportPagedRequest.PageIndex, userExamResultReportPagedRequest.PageSize, total)
  515. };
  516. }
  517. public async Task<GradingResultPageViewResponse> GetGradingResultPagedList(GradingPagedRequest gradingPagedRequest)
  518. {
  519. // 只要有阅卷记录就在已阅卷列表中,已阅卷和未阅卷会有重复数据,只有所有记录都已阅卷才会从未阅卷列表中排除
  520. var userExamTable = _repository.Queryable().WhereIF(gradingPagedRequest.IsCheck!=null, x => x.IsCheck == gradingPagedRequest.IsCheck);
  521. var examManageTable = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  522. var queryable = userExamTable.InnerJoin(examManageTable, (u, e) => u.ExamId == e.Id).GroupBy((u, e) => new
  523. {
  524. ExamName = e.Name,
  525. ExamCode = e.Code,
  526. CutoffScore = e.CutoffScore,
  527. TotalScore = e.TotalScore,
  528. Id = e.Id,
  529. Status = e.Status,
  530. Remark = e.Remark
  531. }).Select((u, e) => new GradingResultViewResponse
  532. {
  533. CutoffScore = e.CutoffScore,
  534. TotalScore = e.TotalScore,
  535. ExamName = e.Name,
  536. ExamCode = e.Code,
  537. IsCheck = SqlFunc.Subqueryable<ExamUserExam>().Where(x=>x.ExamId == e.Id && x.IsCheck).Any(),
  538. Id = e.Id,
  539. Remark = e.Remark
  540. });
  541. var list = await queryable.ToPageListAsync(gradingPagedRequest.PageIndex, gradingPagedRequest.PageSize);
  542. var total = await queryable.CountAsync();
  543. var result = new GradingResultPageViewResponse
  544. {
  545. Items = list,
  546. Pagination = new Pagination(gradingPagedRequest.PageIndex, gradingPagedRequest.PageSize, total)
  547. };
  548. return result;
  549. }
  550. public async Task BatchGradingAsync(BatchGradingExamItemDto batchGradingExamItemDto, CancellationToken cancellationToken)
  551. {
  552. var userExamItemIds = batchGradingExamItemDto.Items.Select(x => x.UserExamItemId);
  553. var userExamItems = await _userExamItemRepository.Queryable().Where(m => userExamItemIds.Contains(m.Id)).ToListAsync();
  554. if (userExamItems != null && userExamItemIds.Any())
  555. {
  556. userExamItems = _mapper.Map<List<GradingExamItemDto>, List<ExamUserExamItem>>(batchGradingExamItemDto.Items, userExamItems);
  557. await _userExamItemRepository.ValidateUpdateAsync(userExamItems, cancellationToken);
  558. }
  559. }
  560. #endregion
  561. #region private method
  562. private async Task CalcuteExamItemScore(IUserExamItemRepository userExamRepository, UpdateUserExamItemDto addUserExamItemDto, CancellationToken cancellationToken)
  563. {
  564. if (!addUserExamItemDto.QuestionType.CheckSelectType()) return;
  565. var testPaperItemOptionsRepository = new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  566. var examManageRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  567. var testPaperItemRepository = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  568. var examQuestionScoreRepository = new ExamRepository<ExamQuestionScoreBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  569. var testPaperOptionsTable = testPaperItemOptionsRepository.Queryable().Where(x => x.QuestionId == addUserExamItemDto.QuestionId && x.IsAnswer);
  570. var testPaperItemTable = testPaperItemRepository.Queryable();
  571. var userExamTable = _repository.Queryable().Where(x => x.Id == addUserExamItemDto.UserExamId);
  572. var examManageTable = examManageRepository.Queryable();
  573. var testPaperOptionIds = await testPaperOptionsTable.InnerJoin(testPaperItemTable, (t, i) => t.ExamQuestionId == i.Id)
  574. .InnerJoin(examManageTable, (t, i, e) => i.ExamId == e.Id)
  575. .InnerJoin(userExamTable, (t, i, e, u) => e.Id == u.ExamId)
  576. .Select((t, i, e, u) => t.Id).ToListAsync();
  577. var isCorrect = addUserExamItemDto.UserExamItemOptionDtos.Select(x => x.QuestionOptionId).OrderBy(x => x).SequenceEqual(testPaperOptionIds.OrderBy(x => x));
  578. var userExamItem = await userExamRepository.GetAsync(x => x.UserExamId == addUserExamItemDto.UserExamId && x.QuestionId == addUserExamItemDto.QuestionId);
  579. var examQuesiontScores = await examQuestionScoreRepository.Queryable().Where(x => x.QuestionType == addUserExamItemDto.QuestionType)
  580. .InnerJoin(userExamTable, (e, u) => e.Id == u.ExamId)
  581. .Select((e, u) => e).ToListAsync();
  582. userExamItem.IsCheck = true;
  583. userExamItem.Score = isCorrect ? examQuesiontScores.FirstOrDefault()?.Score : 0;
  584. userExamItem.ToUpdate(_sessionContext);
  585. await userExamRepository.UpdateWithValidateAsync(userExamItem, cancellationToken);
  586. }
  587. private async Task AddExamAsync(IRepository<ExamUserExamItem> userExamItemRepository, AddUserExamItemDto addUserExamItemDto, CancellationToken cancellationToken)
  588. {
  589. var userExamItem = await AddUserExamItem(addUserExamItemDto, cancellationToken);
  590. userExamItem.UserExamItemOptionses = await AddUserExamItemOptions(addUserExamItemDto, cancellationToken);
  591. userExamItem.ExamAnswers = await AddExamAnswer(addUserExamItemDto, userExamItem.Id, cancellationToken);
  592. await userExamItemRepository.AddNav(userExamItem)
  593. .Include(x => x.UserExamItemOptionses)
  594. .Include(x => x.ExamAnswers)
  595. .ExecuteCommandAsync();
  596. }
  597. private async Task UpdateExamAsync(IRepository<ExamUserExamItem> userExamItemRepository, UpdateUserExamItemDto updateUserExamItemDto, CancellationToken cancellationToken)
  598. {
  599. var userExamItem = await UpdateUserExamItem(updateUserExamItemDto, cancellationToken);
  600. userExamItem.UserExamItemOptionses = await ModifyUserItemOptions(updateUserExamItemDto, cancellationToken);
  601. userExamItem.ExamAnswers = await UpdateExamAnswer(updateUserExamItemDto, cancellationToken);
  602. await userExamItemRepository.UpdateNav(userExamItem)
  603. .Include(x => x.UserExamItemOptionses)
  604. .Include(x => x.ExamAnswers)
  605. .ExecuteCommandAsync();
  606. }
  607. private async Task<GradingExamQuestionDto> GetNextExamQuestion(GradingExamItemDto gradingExtamItemDto)
  608. {
  609. // TODO: 获取未阅卷的第一道题
  610. var current = _userExamItemRepository.Queryable().Where(x => x.Id == gradingExtamItemDto.UserExamItemId);
  611. var userExamItemTable = _userExamItemRepository.Queryable().Where(x => !x.IsCheck);
  612. var userExamItem = current.InnerJoin(userExamItemTable, (c, u) => c.UserExamId == u.UserExamId).OrderBy((c, u) => c.SortIndex).First();
  613. if (userExamItem != null)
  614. {
  615. var testPaperItem = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.Id == userExamItem.Id && !x.QuestionType.CheckSelectType()).First();
  616. if (testPaperItem == null) return null;
  617. var gradingExamQuestionDto = new GradingExamQuestionDto();
  618. gradingExamQuestionDto = _mapper.Map<Exams.ExamManages.ExamQuestionBak, GradingExamQuestionDto>(testPaperItem, gradingExamQuestionDto);
  619. var examAnswer = new ExamRepository<ExamAnswer>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.UserExamItemId == userExamItem.Id).First();
  620. var testPaperItemAnswer = await new ExamRepository<ExamQuestionAnswerBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().FirstAsync(x => x.QuestionId == testPaperItem.QuestionId && x.ExamQuestionId == testPaperItem.Id);
  621. gradingExamQuestionDto.Answer = examAnswer.Answer ?? string.Empty;
  622. gradingExamQuestionDto.CorrectAnswer = testPaperItemAnswer != null ? testPaperItemAnswer.Answer ?? string.Empty : string.Empty;
  623. return gradingExamQuestionDto;
  624. }
  625. return null;
  626. }
  627. private async Task<List<ExamAnswer>> AddExamAnswer(AddUserExamItemDto addUserExamItemDto,string id, CancellationToken cancellationToken)
  628. {
  629. if (addUserExamItemDto.QuestionType.CheckSelectType()) return null;
  630. var examAnswers = new List<ExamAnswer>();
  631. var examAnswer = new ExamAnswer
  632. {
  633. UserId = _sessionContext.UserId,
  634. UserExamItemId = id,
  635. Answer = addUserExamItemDto.Answer
  636. };
  637. examAnswer.ToInsert(_sessionContext);
  638. await _examAnswerRepository.ValidateAddAsync(examAnswer, cancellationToken);
  639. return examAnswers;
  640. }
  641. private async Task<UserExamQuestionDto> GetNextExamQuestion(AddUserExamItemDto addUserExamItemDto)
  642. {
  643. // TODO: 获取未阅卷的第一道题
  644. var testPaperItemRepository = new ExamRepository<Exams.ExamManages.ExamQuestionBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  645. var examRepository = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  646. var userExamTable = _repository.Queryable().Where(x => x.Id == addUserExamItemDto.UserExamId);
  647. var userExamItemTable = _userExamItemRepository.Queryable().WhereIF(addUserExamItemDto.QuestionId.IsNotNullOrEmpty(), x => x.QuestionId == addUserExamItemDto.QuestionId);
  648. var examTable = examRepository.Queryable();
  649. var testPaperItemTable = testPaperItemRepository.Queryable();
  650. var current = examTable.InnerJoin(testPaperItemTable, (e, t) => e.Id == t.ExamId)
  651. .InnerJoin(userExamTable, (e, t, u) => e.Id == u.ExamId)
  652. .InnerJoin(userExamItemTable, (e, t, u, i) => t.QuestionId == i.QuestionId).Select((e, t, u, i) => t);
  653. var nextTable = testPaperItemTable.InnerJoin(current, (t, c) => t.SortIndex > c.SortIndex).OrderBy((t, c) => t.SortIndex).Select((t, c) => t);
  654. var userExamItem = userExamItemTable.InnerJoin(nextTable, (u, n) => u.QuestionId == n.QuestionId).OrderBy((u, n) => u.SortIndex).Select((u, n) => u).First();
  655. if (userExamItem != null)
  656. {
  657. var question = testPaperItemRepository.Queryable().Where(x => x.Id == userExamItem.Id).First();
  658. if (question == null) return null;
  659. var userExamQuestionDto = new UserExamQuestionDto();
  660. userExamQuestionDto = _mapper.Map<Exams.ExamManages.ExamQuestionBak, UserExamQuestionDto>(question, userExamQuestionDto);
  661. if (question.QuestionType.CheckSelectType())
  662. {
  663. var userExamItemOptionTable = _userExamItemOptionRepository.Queryable().Where(x => x.UserExamItemId == userExamItem.Id);
  664. var quesitonOptionTable = new ExamRepository<ExamQuestionOptionsBak>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  665. var queryResult = userExamItemOptionTable.InnerJoin(quesitonOptionTable, (u, q) => u.QuestionOptionId == q.Id)
  666. .Select((u, q) => new UserExamItemOptionDto
  667. {
  668. Content = q.Content,
  669. QuestionOptionId = u.QuestionOptionId,
  670. UserExamItemId = u.UserExamItemId
  671. });
  672. userExamQuestionDto.UserExamItemOptionDtos = queryResult.ToList();
  673. }
  674. else
  675. {
  676. var examAnswer = new ExamRepository<ExamAnswer>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(x => x.UserExamItemId == userExamItem.Id).First();
  677. userExamQuestionDto.Answer = examAnswer.Answer ?? string.Empty;
  678. }
  679. return userExamQuestionDto;
  680. }
  681. else
  682. {
  683. return null;
  684. }
  685. }
  686. private async Task<List<ExamAnswer>> UpdateExamAnswer(UpdateUserExamItemDto updateUserExamItemDto, CancellationToken cancellationToken)
  687. {
  688. var examAnswerTable = _examAnswerRepository.Queryable();
  689. var userExamItemTable = _userExamItemRepository.Queryable().Where(x => x.Id == updateUserExamItemDto.Id);
  690. var examAnswer = await examAnswerTable.InnerJoin(userExamItemTable, (e, u) => e.UserExamItemId == u.Id).Select((e, u) => e).FirstAsync();
  691. if (!updateUserExamItemDto.QuestionType.CheckSelectType())
  692. {
  693. var examAnswers = new List<ExamAnswer>();
  694. if (examAnswer != null)
  695. {
  696. examAnswer.Answer = updateUserExamItemDto.Answer;
  697. examAnswer.UserId = _sessionContext.UserId;
  698. examAnswer.UserExamItemId = updateUserExamItemDto.Id;
  699. examAnswer.ToUpdate(_sessionContext);
  700. await _examAnswerRepository.ValidateUpdateAsync(examAnswer, cancellationToken);
  701. examAnswers.Add(examAnswer);
  702. }
  703. else
  704. {
  705. examAnswer = new ExamAnswer
  706. {
  707. Answer = updateUserExamItemDto.Answer,
  708. UserId = _sessionContext.UserId,
  709. UserExamItemId = updateUserExamItemDto.Id
  710. };
  711. examAnswer.ToInsert(_sessionContext);
  712. await _examAnswerRepository.ValidateAddAsync(examAnswer, cancellationToken);
  713. examAnswers.Add(examAnswer);
  714. }
  715. return examAnswers;
  716. }
  717. return null;
  718. }
  719. private async Task<List<ExamUserExamItemOptions>> ModifyUserItemOptions(UpdateUserExamItemDto updateUserExamItemDto, CancellationToken cancellationToken)
  720. {
  721. if (updateUserExamItemDto.QuestionType.CheckSelectType())
  722. {
  723. var entityQuestionRequest = new EntityQueryRequest
  724. {
  725. Expression = ExpressionableUtility.CreateExpression<ExamUserExamItemOptions>()
  726. .AndIF(updateUserExamItemDto.Id.IsNotEmpty(), x => x.UserExamItemId == updateUserExamItemDto.Id).ToExpression()
  727. };
  728. await DeleteUserExamItemOptions(entityQuestionRequest, cancellationToken);
  729. //await UpdateUserItemOptions(updateUserExamItemDto, cancellationToken);
  730. var addUserExamItemDto = _mapper.Map<AddUserExamItemDto>(updateUserExamItemDto);
  731. addUserExamItemDto.UserExamItemOptionDtos = new List<AddUserExamItemOptionDto>();
  732. updateUserExamItemDto.UserExamItemOptionDtos.ForEach(item =>
  733. {
  734. addUserExamItemDto.UserExamItemOptionDtos.Add(_mapper.Map<AddUserExamItemOptionDto>(item));
  735. });
  736. return await AddUserExamItemOptions(addUserExamItemDto, cancellationToken);
  737. }
  738. return null;
  739. }
  740. private async Task UpdateUserItemOptions(UpdateUserExamItemDto updateUserExamItemDto, CancellationToken cancellationToken)
  741. {
  742. if (updateUserExamItemDto.QuestionType.CheckSelectType())
  743. {
  744. var userExamItemOptions = await _userExamItemOptionRepository.Queryable().Where(x => x.UserExamItemId == updateUserExamItemDto.Id).ToListAsync();
  745. var entities = new List<ExamUserExamItemOptions>();
  746. if (updateUserExamItemDto.UserExamItemOptionDtos != null)
  747. {
  748. updateUserExamItemDto.UserExamItemOptionDtos.Where(m => m.OperationStatus == EEOperationStatus.Update).ToList().ForEach(x =>
  749. {
  750. var entity = userExamItemOptions.FirstOrDefault(m => m.Id == x.Id);
  751. if (entity != null)
  752. {
  753. entities.Add(_mapper.Map<UpdateUserExamItemOptionDto, ExamUserExamItemOptions>(x, entity));
  754. }
  755. });
  756. }
  757. entities.ToUpdate(_sessionContext);
  758. await _userExamItemOptionRepository.ValidateUpdateAsync(entities, cancellationToken);
  759. }
  760. }
  761. private async Task<ExamUserExamItem> UpdateUserExamItem(UpdateUserExamItemDto updateUserExamItemDto, CancellationToken cancellationToken)
  762. {
  763. var userExamItem = await _userExamItemRepository.GetAsync(x => x.UserExamId == updateUserExamItemDto.UserExamId && x.QuestionId == updateUserExamItemDto.QuestionId);
  764. userExamItem = _mapper.Map<UpdateUserExamItemDto, ExamUserExamItem>(updateUserExamItemDto, userExamItem);
  765. updateUserExamItemDto.Id = userExamItem.Id;
  766. userExamItem.ToUpdate(_sessionContext);
  767. await _userExamItemRepository.ValidateUpdateAsync(userExamItem, cancellationToken);
  768. if (updateUserExamItemDto.QuestionType.CheckSelectType())
  769. {
  770. if (updateUserExamItemDto.UserExamItemOptionDtos != null)
  771. {
  772. updateUserExamItemDto.UserExamItemOptionDtos.ForEach(x => x.UserExamItemId = updateUserExamItemDto.Id);
  773. }
  774. }
  775. return userExamItem;
  776. }
  777. private async Task<List<ExamUserExamItemOptions>> AddUserExamItemOptions(AddUserExamItemDto addUserExamItemDto, CancellationToken cancellationToken)
  778. {
  779. var userExamItemOptions = new List<ExamUserExamItemOptions>();
  780. if (addUserExamItemDto.QuestionType.CheckSelectType())
  781. {
  782. if (addUserExamItemDto.UserExamItemOptionDtos != null)
  783. {
  784. addUserExamItemDto.UserExamItemOptionDtos.ToList().ForEach(x =>
  785. {
  786. userExamItemOptions.Add(_mapper.Map<ExamUserExamItemOptions>(x));
  787. });
  788. }
  789. }
  790. userExamItemOptions.ToInsert(_sessionContext);
  791. await _userExamItemOptionRepository.ValidateAddAsync(userExamItemOptions, cancellationToken);
  792. return userExamItemOptions;
  793. }
  794. private async Task<ExamUserExamItem> AddUserExamItem(AddUserExamItemDto addUserExamItemDto, CancellationToken cancellationToken)
  795. {
  796. var userExamItem = _mapper.Map<ExamUserExamItem>(addUserExamItemDto);
  797. userExamItem.ToInsert(_sessionContext);
  798. await _userExamItemRepository.ValidateAddAsync(userExamItem, cancellationToken);
  799. if (addUserExamItemDto.QuestionType.CheckSelectType())
  800. {
  801. if (addUserExamItemDto.UserExamItemOptionDtos != null)
  802. {
  803. addUserExamItemDto.UserExamItemOptionDtos.ForEach(x => x.UserExamItemId = userExamItem.Id);
  804. }
  805. }
  806. return userExamItem;
  807. }
  808. private async Task DeleteUserExamItemOptions(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken)
  809. {
  810. await _userExamItemOptionRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken);
  811. }
  812. private SqlSugar.ISugarQueryable<UserExamResultViewResponse> GetQueryable(UserExamPagedRequest queryRequest)
  813. {
  814. if (_sessionContext.UserId != null)
  815. {
  816. queryRequest.UserId = _sessionContext.UserId;
  817. }
  818. var expression = queryRequest.GetExpression();
  819. var userExamTable = _repository.Queryable().Where(expression);
  820. var examManageExpression = queryRequest.GetExamManageExpression();
  821. var examManageTable = new ExamRepository<ExamManage>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(examManageExpression);
  822. var queryable = userExamTable.InnerJoin(examManageTable, (u, e) => u.ExamId == e.Id).Select((u, e) => new UserExamResultViewResponse
  823. {
  824. Id = u.Id,
  825. CutoffScore = e.CutoffScore,
  826. TotalScore = e.TotalScore,
  827. ExamName = e.Name,
  828. Score = u.Score ?? 0,
  829. Status = u.Status,
  830. SortIndex = u.SortIndex,
  831. ExamStatus = u.ExamStatus,
  832. IsSuccess = u.IsSuccess,
  833. EndTime = e.EndTime,
  834. StartTime = e.StartTime,
  835. TimeSpan = e.TimeSpan,
  836. ExamType = e.ExamType,
  837. ExamId = e.Id
  838. });
  839. return queryable;
  840. }
  841. #endregion
  842. }
  843. }