PracticeService.cs 33 KB

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