UserExamService.cs 69 KB

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