PracticeService.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. using Exam.Infrastructure.Data.Entity;
  2. using Exam.Infrastructure.Data.Interface;
  3. using Exam.Repository.Sqlsugar;
  4. using Exam.Share;
  5. using Exam.Share.ViewResponses.Exam;
  6. using Exam.Share.ViewResponses.Practices;
  7. using Hotline.Application.Exam.Core.Constants;
  8. using Hotline.Application.Exam.Core.Extensions;
  9. using Hotline.Application.Exam.Core.Utilities;
  10. using Hotline.Application.Exam.QueryExtensions.Practices;
  11. using Hotline.Application.Exam.QueryExtensions.TestPapers;
  12. using Hotline.Exams.Practices;
  13. using Hotline.Exams.Sourcewares;
  14. using Hotline.Exams.TestPapers;
  15. using Hotline.Repository.SqlSugar;
  16. using Hotline.Repository.SqlSugar.DataPermissions;
  17. using Hotline.Repository.SqlSugar.Exam.Core.Constants;
  18. using Hotline.Repository.SqlSugar.Exam.Interfaces.Practices;
  19. using Hotline.Repository.SqlSugar.Exam.Interfaces.Questions;
  20. using Hotline.Share.Dtos.Practices;
  21. using Hotline.Share.Dtos.Questions;
  22. using Hotline.Share.Dtos.TestPapers;
  23. using Hotline.Share.Requests.Exam;
  24. using Hotline.Share.Requests.TestPaper;
  25. using Hotline.Share.Requests.Train;
  26. using Hotline.Share.ViewResponses;
  27. using Hotline.Share.ViewResponses.Exam;
  28. using Hotline.Share.ViewResponses.Practices;
  29. using MapsterMapper;
  30. using NPOI.OpenXmlFormats.Dml;
  31. using NPOI.SS.Formula.Functions;
  32. using SqlSugar;
  33. using System.Linq;
  34. using Hotline.Application.Exam.Interface.Practices;
  35. using Hotline.Exams.Questions;
  36. using Hotline.Repository.SqlSugar.Exam.Repositories;
  37. using XF.Domain.Authentications;
  38. using XF.Domain.Dependency;
  39. using Hotline.Repository.SqlSugar.Exam.Service;
  40. using Hotline.Repository.SqlSugar.Exam.Extensions;
  41. using Exam.Infrastructure.Extensions;
  42. using Consul;
  43. namespace Hotline.Application.Exam.Service.Practices
  44. {
  45. public class PracticeService : ApiService<ExamPractice, AddPracticeDto, UpdatePracticeDto, HotlineDbContext>, IPracticeService, IScopeDependency
  46. {
  47. private readonly IPracticeRepository _repository;
  48. private readonly IPracticeRecordRepository _practiceRecordRepository;
  49. private readonly IPracticeQuestionOptionsRepository _practiceQuestionOptionsRepository;
  50. private readonly IPracticeQuestionRepository _practiceQuestionRepository;
  51. private readonly IPracticeQuestionSourcewareRepository _practiceQuestionSourcewareRepository;
  52. private readonly IPracticeQuestionKnowladgeRepository _practiceQuestionKnowladgeRepository;
  53. private readonly IPracticeResultItemRepository _practiceResultItemRepository;
  54. private readonly IPracticeResultRepository _practiceResultRepository;
  55. private readonly IPracticeAnswerRepository _practiceAnswerRepository;
  56. private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder;
  57. private readonly IServiceProvider _serviceProvider;
  58. private readonly ISessionContext _sessionContext;
  59. private readonly IMapper _mapper;
  60. public PracticeService(IPracticeRepository repository,
  61. IPracticeRecordRepository practiceRecordRepository,
  62. IPracticeQuestionOptionsRepository practiceQuestionOptionsRepository,
  63. IPracticeQuestionRepository practiceQuestionRepository,
  64. IPracticeQuestionSourcewareRepository practiceQuestionSourcewareRepository,
  65. IPracticeQuestionKnowladgeRepository practiceQuestionKnowladgeRepository,
  66. IPracticeResultItemRepository practiceResultItemRepository,
  67. IPracticeResultRepository practiceResultRepository,
  68. IPracticeAnswerRepository practiceAnswerRepository,
  69. IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider,
  70. ISessionContext sessionContext,
  71. IMapper mapper) : base(repository, mapper, sessionContext)
  72. {
  73. this._repository = repository;
  74. this._practiceRecordRepository = practiceRecordRepository;
  75. this._practiceQuestionOptionsRepository = practiceQuestionOptionsRepository;
  76. this._practiceQuestionRepository = practiceQuestionRepository;
  77. this._practiceQuestionSourcewareRepository = practiceQuestionSourcewareRepository;
  78. this._practiceQuestionKnowladgeRepository = practiceQuestionKnowladgeRepository;
  79. this._practiceResultItemRepository = practiceResultItemRepository;
  80. this._practiceResultRepository = practiceResultRepository;
  81. this._practiceAnswerRepository = practiceAnswerRepository;
  82. this._dataPermissionFilterBuilder = dataPermissionFilterBuilder;
  83. this._serviceProvider = serviceProvider;
  84. this._sessionContext = sessionContext;
  85. this._mapper = mapper;
  86. }
  87. #region public method
  88. public async Task<PracticeDto> GetAsync(EntityQueryRequest entityQueryRequest)
  89. {
  90. throw new NotImplementedException();
  91. }
  92. public async Task<(int, List<PracticeViewResponse>)> GetListAsync(PracticePagedRequest queryRequest)
  93. {
  94. SqlSugar.ISugarQueryable<PracticeViewResponse> queryResult = QueryResult(queryRequest);
  95. var total = await queryResult.CountAsync();
  96. var items = await queryResult.ToListAsync();
  97. return (total, items);
  98. }
  99. public async Task<PageViewResponse<PracticeViewResponse>> GetPagedListAsync(PracticePagedRequest queryRequest)
  100. {
  101. SqlSugar.ISugarQueryable<PracticeViewResponse> queryResult = QueryResult(queryRequest);
  102. var total = await queryResult.CountAsync();
  103. var items = await queryResult.ToPageListAsync(queryRequest.PageIndex, queryRequest.PageSize);
  104. return new PracticePageViewResponse
  105. {
  106. Items = items,
  107. Pagination = new Pagination(queryRequest.PageIndex, queryRequest.PageSize, total)
  108. };
  109. }
  110. public override async Task<string> AddAsync(AddPracticeDto actionRequest, CancellationToken cancellationToken)
  111. {
  112. var questions = await ExactractQuestion(actionRequest);
  113. base.StartTran();
  114. actionRequest.Code = await GenerateCode(ExamBusiConstants.PracticeCode,3);
  115. var id = await base.AddAsync(actionRequest, cancellationToken);
  116. var addPracticeQuestionDtos = new List<AddPracticeQuestionDto>();
  117. questions.ForEach(item =>
  118. {
  119. var addPracticeQuestionDto = _mapper.Map<AddPracticeQuestionDto>(item);
  120. addPracticeQuestionDto.PracticeId = id;
  121. addPracticeQuestionDto.QuestionId = item.Id;
  122. addPracticeQuestionDtos.Add(addPracticeQuestionDto);
  123. });
  124. var practiceRecord = await AddPracticeRecord(id, cancellationToken);
  125. base.Entity.PracticeRecords = new List<ExamPracticeRecord>();
  126. base.Entity.PracticeRecords.Add(practiceRecord);
  127. base.Entity.PracticeQuestions = await AddPracticeQuestions(addPracticeQuestionDtos, cancellationToken);
  128. var practiceQuestionOptions = await AddPracticeQuestionOptions(addPracticeQuestionDtos, cancellationToken);
  129. var practiceQuestionKnowladges = await AddPracticeQuestionKnowladgeAsync(addPracticeQuestionDtos, cancellationToken);
  130. var practiceQuestionSourcewares = await AddPracticeQuestionSourcewareAsync(addPracticeQuestionDtos, cancellationToken);
  131. base.Entity.PracticeQuestions.ForEach(item =>
  132. {
  133. item.PracticeQuestionKnowladges = practiceQuestionKnowladges.Where(x => item.Id == x.PracticeQuestionId).ToList();
  134. item.PracticeQuestionOptionses = practiceQuestionOptions.Where(x => item.Id == x.PracticeQuestionId).ToList();
  135. item.PracticeQuestionSourcewares = practiceQuestionSourcewares.Where(x => item.Id == x.PracticeQuestionId).ToList();
  136. });
  137. await base.Complete(base.Entity, OperationConstant.Create);
  138. return id;
  139. }
  140. public async Task<List<PracticeQuestionViewResponse>> GetPracticeQuestionViewResponses(PracticeQuestionGroupRequest practiceQuestionGroupRequest)
  141. {
  142. var expression = practiceQuestionGroupRequest.GetExpression();
  143. var practiceQuestionTable = _practiceQuestionRepository.Queryable().Where(expression);
  144. var queryable = await practiceQuestionTable.ToListAsync();
  145. var result = queryable.GroupBy(x => x.QuestionType).Select(m => new PracticeQuestionViewResponse
  146. {
  147. QuestionType = m.Key,
  148. Questions = m.Select(n => new SimpleViewResponse
  149. {
  150. Id = n.Id
  151. }).ToList()
  152. }).ToList();
  153. return result;
  154. }
  155. public async Task<List<PracticeQuestionViewResponse>> GetViewPracticeQuestions(PracticeQuestionGroupRequest practiceQuestionGroupRequest)
  156. {
  157. var expression = practiceQuestionGroupRequest.GetExpression();
  158. var practiceQuestionTable = _practiceQuestionRepository.Queryable().Where(expression);
  159. var practiceResultTable = _practiceResultRepository.Queryable();
  160. var queryable = await practiceQuestionTable
  161. .LeftJoin(practiceResultTable, (q, r) => q.Id == r.PracticeQuestionId)
  162. .Select((q, r) => new GradingExamViewResponse
  163. {
  164. Id = q.Id,
  165. IsCorrect = r.IsCorrect,
  166. QuestionType = q.QuestionType
  167. })
  168. .ToListAsync();
  169. var result = queryable.GroupBy(x => x.QuestionType).Select(m => new PracticeQuestionViewResponse
  170. {
  171. QuestionType = m.Key,
  172. Questions = m.Select(n => new SimpleViewResponse
  173. {
  174. Id = n.Id
  175. }).ToList()
  176. }).ToList();
  177. return result;
  178. }
  179. public async Task<PracticeQuestionDto> GetPracticeQuestion(PracticeQuestionRequest practiceQuestionRequest)
  180. {
  181. PracticeQuestionDto practiceQuestionDto = await QueryPracticeQuestion(practiceQuestionRequest);
  182. return practiceQuestionDto;
  183. }
  184. public async Task<ViewPracticeQuestionDto> ViewPracticeQuestion(PracticeQuestionRequest practiceQuestionRequest)
  185. {
  186. var practiceQuestionDto = await QueryPracticeQuestion(practiceQuestionRequest);
  187. var viewPracticeQuestionDto = _mapper.Map<ViewPracticeQuestionDto>(practiceQuestionDto);
  188. if (viewPracticeQuestionDto != null)
  189. {
  190. var practiceResultItemTable = _practiceResultItemRepository.Queryable();
  191. var practiceResultTable = _practiceResultRepository.Queryable().Where(x => x.PracticeQuestionId == practiceQuestionRequest.PracticeQuestionId);
  192. var practiceResultItems = await practiceResultTable.InnerJoin(practiceResultItemTable, (r, i) => r.Id == i.PracticeResultId).Select((r, i) => i).ToListAsync();
  193. var practiceAnswers = await _practiceAnswerRepository.Queryable().Where(x => x.PracticeQuestionId == practiceQuestionRequest.PracticeQuestionId).ToListAsync();
  194. viewPracticeQuestionDto.PracticeQuestionOptionsDtos.ForEach(item =>
  195. {
  196. item.IsSelected = practiceResultItems.Any(x => x.QuestionOptionId == item.QuestionOptionId);
  197. item.IsAnswer = practiceAnswers.Any(x => x.PracticeOptionId == item.QuestionOptionId);
  198. });
  199. viewPracticeQuestionDto.Answer = string.Join(",", viewPracticeQuestionDto.PracticeQuestionOptionsDtos.Where(x => x.IsAnswer).Select(m => m.Label));
  200. }
  201. return viewPracticeQuestionDto;
  202. }
  203. public async Task<PracticeQuestionDto> Practice(SubmitPracticeDto submitPracticeDto, CancellationToken cancellationToken)
  204. {
  205. var current = await _practiceQuestionRepository.GetAsync(submitPracticeDto.PracticeQuestionId);
  206. var practiceResult = await AddPracticeResult(submitPracticeDto, cancellationToken);
  207. practiceResult.PracticeResultItems = await AddPracticeResultItem(submitPracticeDto, cancellationToken);
  208. await _practiceResultRepository.AddNav(practiceResult).Include(x => x.PracticeResultItems).ExecuteCommandAsync();
  209. var nextId = await _practiceQuestionRepository.Queryable().Where(x => x.PracticeId == current.PracticeId && x.SortIndex > current.SortIndex).OrderBy(x => x.SortIndex).Select(x => x.Id).FirstAsync();
  210. var practiceQuestionRequest = new PracticeQuestionRequest
  211. {
  212. PracticeQuestionId = nextId
  213. };
  214. return await QueryPracticeQuestion(practiceQuestionRequest);
  215. }
  216. private async Task<ExamPracticeResult> AddPracticeResult(SubmitPracticeDto submitPracticeDto, CancellationToken cancellationToken)
  217. {
  218. var practiceQuetionOptions = await _practiceQuestionOptionsRepository.Queryable().Where(x => x.PracticeQuestionId == submitPracticeDto.PracticeQuestionId && x.IsAnswer).ToListAsync();
  219. var practiceRecordTable = _practiceRecordRepository.Queryable();
  220. var practiceQuestionTable = _practiceQuestionRepository.Queryable().Where(x => x.Id == submitPracticeDto.PracticeQuestionId);
  221. var practiceRecordId = await practiceRecordTable.InnerJoin(practiceQuestionTable, (p, q) => p.PracticeId == q.PracticeId)
  222. .Select((p, q) => p.Id).FirstAsync();
  223. var practiceResult = new ExamPracticeResult
  224. {
  225. PracticeRecordId = practiceRecordId,
  226. PracticeQuestionId = submitPracticeDto.PracticeQuestionId,
  227. IsCorrect = submitPracticeDto.PracticeResultItemDtos.Select(x => x.QuestionOptionId).All(m => practiceQuetionOptions.Any(t => t.QuestionOptionId == m))
  228. };
  229. practiceResult.ToInsert(_sessionContext);
  230. await _practiceResultRepository.ValidateAddAsync(practiceResult, cancellationToken);
  231. submitPracticeDto.PracticeResultId = practiceResult.Id;
  232. return practiceResult;
  233. }
  234. public async Task Complete(CompletePracticeRecordDto completePracticeRecordDto, CancellationToken cancellationToken)
  235. {
  236. var practiceRecord = await _practiceRecordRepository.Queryable().Where(x => x.PracticeId == completePracticeRecordDto.PracticeId && x.UserId == _sessionContext.UserId).FirstAsync();
  237. practiceRecord.IsComplete = true;
  238. practiceRecord.ToUpdate(_sessionContext);
  239. await _practiceRecordRepository.ValidateUpdateAsync(practiceRecord, cancellationToken);
  240. }
  241. #endregion
  242. #region private method
  243. private async Task<List<ExamPracticeResultItem>> AddPracticeResultItem(SubmitPracticeDto submitPracticeDto, CancellationToken cancellationToken)
  244. {
  245. if (submitPracticeDto.PracticeResultItemDtos == null) return null;
  246. var practiceResultItems = new List<ExamPracticeResultItem>();
  247. submitPracticeDto.PracticeResultItemDtos.ForEach(item =>
  248. {
  249. var practiceResultItem = _mapper.Map<ExamPracticeResultItem>(item);
  250. practiceResultItem.PracticeResultId = submitPracticeDto.PracticeResultId;
  251. practiceResultItem.ToInsert(_sessionContext);
  252. practiceResultItems.Add(practiceResultItem);
  253. });
  254. await _practiceResultItemRepository.ValidateAddAsync(practiceResultItems, cancellationToken);
  255. return practiceResultItems;
  256. }
  257. private async Task<PracticeQuestionDto> QueryPracticeQuestion(PracticeQuestionRequest practiceQuestionRequest)
  258. {
  259. if (practiceQuestionRequest.PracticeQuestionId.IsNullOrEmpty()) return null;
  260. var practiceQuestion = await _practiceQuestionRepository.GetAsync(x => x.Id == practiceQuestionRequest.PracticeQuestionId);
  261. var practiceQuestionDto = _mapper.Map<PracticeQuestionDto>(practiceQuestion);
  262. practiceQuestionDto.PracticeQuestionOptionsDtos = await GetPracticeQuestionOptions(practiceQuestionRequest);
  263. var practiceResultItems = await GetPracticeResultItems(practiceQuestionRequest);
  264. if (practiceResultItems != null)
  265. {
  266. practiceQuestionDto.PracticeQuestionOptionsDtos.ForEach(item =>
  267. {
  268. item.IsSelected = practiceResultItems.Any(x => x.QuestionOptionId == item.QuestionOptionId);
  269. });
  270. }
  271. practiceQuestionDto.PracticeQuestionSourcewareDtos = await GetPracticeQuestionSourceware(practiceQuestionRequest);
  272. practiceQuestionDto.PracticeQuestionKnowladgeDtos = await GetPracticeQuestionKnowladge(practiceQuestionRequest);
  273. return practiceQuestionDto;
  274. }
  275. private async Task<List<ExamPracticeResultItem>> GetPracticeResultItems(PracticeQuestionRequest practiceQuestionRequest)
  276. {
  277. var practiceRecordRepository = new ExamRepository<ExamPracticeRecord>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  278. var practiceRecordTable = practiceRecordRepository.Queryable().Where(x=>x.UserId == _sessionContext.UserId);
  279. var practiceResultItems = practiceRecordTable.InnerJoin<ExamPracticeResult>((p, r) => p.Id == r.PracticeRecordId)
  280. .InnerJoin<ExamPracticeResultItem>((p, r, i) => i.PracticeResultId == r.Id)
  281. .Where((p, r, i) => r.PracticeQuestionId == practiceQuestionRequest.PracticeQuestionId)
  282. .Select((p, r, i) => i);
  283. return await practiceResultItems.Distinct().ToListAsync();
  284. }
  285. private async Task<List<PracticeQuestionKnowladgeDto>> GetPracticeQuestionKnowladge(PracticeQuestionRequest practiceQuestionRequest)
  286. {
  287. var knowledgeRepository = new ExamRepository<KnowledgeBase.Knowledge>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  288. var expression = practiceQuestionRequest.GetExpression();
  289. var practiceQuestionTable = _practiceQuestionRepository.Queryable().Where(expression);
  290. var practiceQuestionKnowladgeTable = _practiceQuestionKnowladgeRepository.Queryable();
  291. var knowlegdeTable = knowledgeRepository.Queryable();
  292. var queryResult = practiceQuestionTable.InnerJoin(practiceQuestionKnowladgeTable, (t, ts) => t.QuestionId == ts.QuestionId && t.Id == ts.PracticeQuestionId)
  293. .InnerJoin(knowlegdeTable, (t, ts, sw) => ts.KnowladgeId == sw.Id)
  294. .Select((t, ts, sw) => new PracticeQuestionKnowladgeDto
  295. {
  296. KnowladgeId = ts.KnowladgeId,
  297. QuestionId = ts.QuestionId,
  298. Title = sw.Title,
  299. });
  300. return await queryResult.Distinct().ToListAsync();
  301. }
  302. private async Task<List<PracticeQuestionSourcewareDto>> GetPracticeQuestionSourceware(PracticeQuestionRequest practiceQuestionRequest)
  303. {
  304. var sourcewareRepository = new ExamRepository<ExamSourceware>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  305. var expression = practiceQuestionRequest.GetExpression();
  306. var practiceQuestionTable = _practiceQuestionRepository.Queryable().Where(expression);
  307. var practiceQuestionSourcewareTable = _practiceQuestionSourcewareRepository.Queryable();
  308. var sourcewareTable = sourcewareRepository.Queryable();
  309. var queryResult = practiceQuestionTable.InnerJoin(practiceQuestionSourcewareTable, (t, ts) => t.QuestionId == ts.QuestionId && t.Id == ts.PracticeQuestionId)
  310. .InnerJoin(sourcewareTable, (t, ts, sw) => ts.SourcewareId == sw.Id)
  311. .Select((t, ts, sw) => new PracticeQuestionSourcewareDto
  312. {
  313. AttachmentId = sw.AttachmentId,
  314. SourcewareId = ts.SourcewareId,
  315. QuestionId = ts.QuestionId,
  316. Name = sw.Name,
  317. });
  318. return await queryResult.Distinct().ToListAsync();
  319. }
  320. private async Task<List<PracticeQuestionOptionsDto>> GetPracticeQuestionOptions(PracticeQuestionRequest practiceQuestionRequest)
  321. {
  322. var expression = practiceQuestionRequest.GetExpression();
  323. var practiceQuestionTable = _practiceQuestionRepository.Queryable().Where(expression);
  324. var practiceQuestionOptionTable = _practiceQuestionOptionsRepository.Queryable();
  325. var queryResult = practiceQuestionTable.InnerJoin(practiceQuestionOptionTable, (p, o) => p.QuestionId == o.QuestionId && p.Id == o.PracticeQuestionId)
  326. .Select((p, o) => new PracticeQuestionOptionsDto
  327. {
  328. Content = o.Content,
  329. Label = o.Label,
  330. PracticeQuestionId = o.PracticeQuestionId,
  331. QuestionOptionId = o.QuestionOptionId
  332. });
  333. return await queryResult.Distinct().ToListAsync();
  334. }
  335. private SqlSugar.ISugarQueryable<PracticeViewResponse> QueryResult(PracticePagedRequest queryRequest)
  336. {
  337. var expression = queryRequest.GetExpression();
  338. var practiceTable = _repository.Queryable().Where(expression);
  339. var practiceRecordTable = _practiceRecordRepository.Queryable();
  340. var queryResult = practiceTable.InnerJoin(practiceRecordTable, (p, r) => p.Id == r.PracticeId).Select((p, r) => new PracticeViewResponse
  341. {
  342. Id = p.Id,
  343. Code = p.Code,
  344. Count = p.Count,
  345. PracticeTime = r.PracticeTime,
  346. PracticeType = p.PracticeType
  347. });
  348. return queryResult;
  349. }
  350. private async Task<List<ExamPracticeQuestionSourceware>> AddPracticeQuestionSourcewareAsync(List<AddPracticeQuestionDto> practiceQuestionDtos, CancellationToken cancellationToken)
  351. {
  352. var questionSourcewareRepository = new ExamRepository<ExamQuestionSourceware>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  353. var quesitonIds = practiceQuestionDtos.Select(x => x.QuestionId);
  354. var questionSourceware = await questionSourcewareRepository.Queryable().Where(x => quesitonIds.Contains(x.QuestionId)).ToListAsync();
  355. var practiceQuestionSourcewares = new List<ExamPracticeQuestionSourceware>();
  356. practiceQuestionDtos.Where(x => x.QuestionType.CheckSelectType()).ToList().ForEach(x =>
  357. {
  358. var practiceQuestion = base.Entity?.PracticeQuestions.FirstOrDefault(n => n.QuestionId == x.QuestionId) ?? null;
  359. var options = questionSourceware.Where(n => x.QuestionId == n.QuestionId).ToList();
  360. if (options != null)
  361. {
  362. options.ForEach(item =>
  363. {
  364. var practiceQuestionSourceware = _mapper.Map<ExamQuestionSourceware, ExamPracticeQuestionSourceware>(item);
  365. practiceQuestionSourceware.PracticeQuestionId = practiceQuestion?.Id;
  366. practiceQuestionSourceware.ToInsert(_sessionContext);
  367. practiceQuestionSourcewares.Add(practiceQuestionSourceware);
  368. });
  369. }
  370. });
  371. await _practiceQuestionSourcewareRepository.ValidateAddAsync(practiceQuestionSourcewares, cancellationToken);
  372. return practiceQuestionSourcewares;
  373. }
  374. private async Task<List<ExamPracticeQuestionKnowladge>> AddPracticeQuestionKnowladgeAsync(List<AddPracticeQuestionDto> practiceQuestionDtos, CancellationToken cancellationToken)
  375. {
  376. var questionKnowladgeRepository = new ExamRepository<ExamQuestionKnowladge>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  377. var quesitonIds = practiceQuestionDtos.Select(x => x.QuestionId);
  378. var questionKnowladge = await questionKnowladgeRepository.Queryable().Where(x => quesitonIds.Contains(x.QuestionId)).ToListAsync();
  379. var practiceQuestionKnowladges = new List<ExamPracticeQuestionKnowladge>();
  380. practiceQuestionDtos.Where(x => x.QuestionType.CheckSelectType()).ToList().ForEach(x =>
  381. {
  382. var practiceQuestion = base.Entity?.PracticeQuestions.FirstOrDefault(n => n.QuestionId == x.QuestionId) ?? null;
  383. var options = questionKnowladge.Where(n => x.QuestionId == n.QuestionId).ToList();
  384. if (options != null)
  385. {
  386. options.ForEach(item =>
  387. {
  388. var practiceQuestionKnowladge = _mapper.Map<ExamQuestionKnowladge, ExamPracticeQuestionKnowladge>(item);
  389. practiceQuestionKnowladge.PracticeQuestionId = practiceQuestion?.Id;
  390. practiceQuestionKnowladge.ToInsert(_sessionContext);
  391. practiceQuestionKnowladges.Add(practiceQuestionKnowladge);
  392. });
  393. }
  394. });
  395. await _practiceQuestionKnowladgeRepository.ValidateAddAsync(practiceQuestionKnowladges, cancellationToken);
  396. return practiceQuestionKnowladges;
  397. }
  398. private async Task<List<ExamPracticeQuestionOptions>> AddPracticeQuestionOptions(List<AddPracticeQuestionDto> practiceQuestionDtos, CancellationToken cancellationToken)
  399. {
  400. var questionOptionRepository = new ExamRepository<ExamQuestionOptions>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  401. var quesitonIds = practiceQuestionDtos.Select(x => x.QuestionId);
  402. var questionOptions = await questionOptionRepository.Queryable().Where(x => quesitonIds.Contains(x.QuestionId)).ToListAsync();
  403. var practiceQuestionOptions = new List<ExamPracticeQuestionOptions>();
  404. practiceQuestionDtos.Where(x => x.QuestionType.CheckSelectType()).ToList().ForEach(x =>
  405. {
  406. var practiceQuestion = base.Entity?.PracticeQuestions.FirstOrDefault(n=> n.QuestionId == x.QuestionId) ?? null;
  407. var options = questionOptions.Where(n => x.QuestionId == n.QuestionId).ToList();
  408. if (options != null)
  409. {
  410. options.ForEach(item =>
  411. {
  412. var practiceQuestionOption = _mapper.Map<ExamQuestionOptions, ExamPracticeQuestionOptions>(item);
  413. practiceQuestionOption.PracticeQuestionId = practiceQuestion?.Id;
  414. practiceQuestionOption.QuestionOptionId = item.Id;
  415. practiceQuestionOption.ToInsert(_sessionContext);
  416. practiceQuestionOptions.Add(practiceQuestionOption);
  417. });
  418. }
  419. });
  420. await _practiceQuestionOptionsRepository.ValidateAddAsync(practiceQuestionOptions, cancellationToken);
  421. return practiceQuestionOptions;
  422. }
  423. private async Task<List<ExamPracticeQuestion>> AddPracticeQuestions(List<AddPracticeQuestionDto> addPracticeQuestionDtos, CancellationToken cancellationToken)
  424. {
  425. var practiceQuestions = new List<ExamPracticeQuestion>();
  426. var sortIndex = 0;
  427. addPracticeQuestionDtos.ForEach(item =>
  428. {
  429. var practiceQuestion = _mapper.Map<ExamPracticeQuestion>(item);
  430. practiceQuestion.SortIndex = sortIndex;
  431. practiceQuestions.Add(practiceQuestion);
  432. sortIndex++;
  433. });
  434. practiceQuestions.ToInsert(_sessionContext);
  435. await _practiceQuestionRepository.ValidateAddAsync(practiceQuestions, cancellationToken);
  436. return practiceQuestions;
  437. }
  438. private async Task<ExamPracticeRecord> AddPracticeRecord(string practiceId, CancellationToken cancellationToken)
  439. {
  440. var practiceRecordDto = new PracticeRecordDto
  441. {
  442. PracticeId = practiceId,
  443. UserId = _sessionContext.UserId,
  444. PracticeTime = DateTime.Now
  445. };
  446. var practiceRecord = _mapper.Map<ExamPracticeRecord>(practiceRecordDto);
  447. practiceRecord.ToInsert(_sessionContext);
  448. await _practiceRecordRepository.ValidateAddAsync(practiceRecord, cancellationToken);
  449. return practiceRecord;
  450. }
  451. private async Task<List<ExamQuestion>> ExactractQuestion(AddPracticeDto actionRequest)
  452. {
  453. if (actionRequest.PracticeTagDtos == null) return new List<ExamQuestion>();
  454. var tagIds = actionRequest.PracticeTagDtos.Select(x => x.TagId).ToList();
  455. var questionTagRepostiory = new ExamRepository<ExamQuestionTag>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  456. var questionRepository = new ExamRepository<ExamQuestion>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  457. ISugarQueryable<ExamQuestionTag, ExamQuestion> questionTable = GetCheckQuestions(questionTagRepostiory);
  458. // 按照标签获取试题,至少取一道
  459. if (actionRequest.Count < actionRequest.PracticeTagDtos.Count)
  460. {
  461. var queryResult = questionTable.Where((qt, q) => tagIds.Contains(qt.TagId)).Take(actionRequest.Count).Select((qt, q) => q);
  462. return await queryResult.ToListAsync();
  463. }
  464. else
  465. {
  466. var unionQuestions = new List<ISugarQueryable<ExamQuestion>>();
  467. var ids = new List<string>();
  468. // 保证每个标签至少获取一道题
  469. tagIds.ForEach(v =>
  470. {
  471. var unionQuestion = GetCheckQuestions(questionTagRepostiory).Where((qt, q) => qt.TagId == v).Take(1).Select((qt, q) => q);
  472. ids.Add(GetCheckQuestions(questionTagRepostiory).Where((qt, q) => qt.TagId == v).Select(qt => qt.Id).First());
  473. unionQuestions.Add(unionQuestion);
  474. });
  475. var mainQuesiton = GetCheckQuestions(questionTagRepostiory).Where((qt, q) => tagIds.Contains(qt.TagId) && !ids.Contains(qt.Id)).Take(actionRequest.Count - tagIds.Count).Select((qt, q) => q);
  476. unionQuestions.Add(mainQuesiton);
  477. var queryResult = questionRepository.UnionAll(unionQuestions.ToArray());
  478. return await queryResult.ToListAsync();
  479. }
  480. }
  481. private static ISugarQueryable<ExamQuestionTag, ExamQuestion> GetCheckQuestions(ExamRepository<ExamQuestionTag> questionTagRepostiory)
  482. {
  483. return questionTagRepostiory.Queryable().InnerJoin<ExamQuestion>((qt, q) => qt.QuestionId == q.Id).Where((qt, q) => q.QuestionType == Share.Enums.Exams.EQuestionType.Single || q.QuestionType == Share.Enums.Exams.EQuestionType.Multi || q.QuestionType == Share.Enums.Exams.EQuestionType.Judge);
  484. }
  485. private async Task<string> GenerateCode(string codePrefix, int length)
  486. {
  487. var trainPlan = await _repository.Queryable().Where(x => x.CreationTime.Date == DateTime.Now.Date).OrderByDescending(x => x.CreationTime).FirstAsync();
  488. var code = string.Empty;
  489. if (trainPlan != null)
  490. {
  491. code = trainPlan.Code;
  492. }
  493. code = CodeUtility.GenerateCode(codePrefix, length, code);
  494. return code;
  495. }
  496. #endregion
  497. #region protect method
  498. protected override async Task CompleteAdd(ExamPractice entity)
  499. {
  500. await base.AddNav(entity).Include(x => x.PracticeRecords)
  501. .Include(x => x.PracticeQuestions)
  502. .ThenInclude(x => x.PracticeQuestionKnowladges)
  503. .Include(x => x.PracticeQuestions, new InsertNavOptions
  504. {
  505. OneToManyIfExistsNoInsert = true
  506. })
  507. .ThenInclude(x => x.PracticeQuestionOptionses)
  508. .Include(x => x.PracticeQuestions, new InsertNavOptions
  509. {
  510. OneToManyIfExistsNoInsert = true
  511. })
  512. .ThenInclude(x => x.PracticeQuestionSourcewares).ExecuteCommandAsync();
  513. }
  514. public async Task<TagQuestionCountViewResponse> GetTagQuestionCount(TagQuestionCountForPracticeRequest tagQuestionCountForPracticeRequest)
  515. {
  516. var expression = tagQuestionCountForPracticeRequest.GetExpression();
  517. var questionExpression = tagQuestionCountForPracticeRequest.GetQuestionExpression();
  518. var tagQuestionRepository = new ExamRepository<ExamQuestionTag>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  519. var quesitonRepository = new ExamRepository<ExamQuestion>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  520. var tagQuestionTable = tagQuestionRepository.Queryable().Where(expression);
  521. var questionTable = quesitonRepository.Queryable().Where(questionExpression);
  522. var taqQuestions = await tagQuestionTable.LeftJoin(questionTable, (t, q) => t.QuestionId == q.Id)
  523. .Select((t, q) => new TagQuestionCountViewResponse
  524. {
  525. TotalCount = SqlFunc.AggregateCount(t.Id)
  526. })
  527. .ToListAsync();
  528. return taqQuestions.Count() > 0 ? taqQuestions.FirstOrDefault() : new TagQuestionCountViewResponse
  529. {
  530. TotalCount = 0
  531. };
  532. }
  533. #endregion
  534. }
  535. }