PracticeService.cs 28 KB

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