TrainRecordService.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. using Exam.Infrastructure.Data.Entity;
  2. using Exam.Infrastructure.Validation.Validation;
  3. using Exam.Insfrastructure.Service.Service;
  4. using Exam.Questions;
  5. using Exam.Repository.Sqlsugar.Repositories;
  6. using Exam.Repository.Sqlsugar.Repositories.Trains;
  7. using Exam.Share.Dtos.Trains;
  8. using Exam.Share.ViewResponses.Train;
  9. using Exam.Trains;
  10. using Hotline.Application.Exam.Core.Extensions;
  11. using Hotline.Application.Exam.QueryExtensions.Trains;
  12. using Hotline.Exams.Sourcewares;
  13. using Hotline.Exams.Trains;
  14. using Hotline.Repository.SqlSugar;
  15. using Hotline.Repository.SqlSugar.DataPermissions;
  16. using Hotline.Repository.SqlSugar.Exam.Interfaces.Trains;
  17. using Hotline.Repository.SqlSugar.Extensions;
  18. using Hotline.Share.Dtos.Questions;
  19. using Hotline.Share.Dtos.Trains;
  20. using Hotline.Share.Requests.Exam;
  21. using Hotline.Share.Requests.Train;
  22. using Hotline.Share.ViewResponses.Trains;
  23. using Hotline.Users;
  24. using MapsterMapper;
  25. using Train.Application.Interface.Train;
  26. using XF.Domain.Authentications;
  27. using XF.Domain.Dependency;
  28. using XF.Domain.Exceptions;
  29. using Hotline.Share.Exams.Extensions;
  30. using NPOI.SS.Formula.Functions;
  31. namespace Hotline.Application.Exam.Service.Trains
  32. {
  33. public class TrainRecordService : ApiService<TrainRecord, AddTrainRecordDto, UpdateTrainRecordDto, HotlineDbContext>, ITrainRecordService, IScopeDependency
  34. {
  35. private readonly ITrainRecordRepository _repository;
  36. private readonly ITrainRecordAnswerRepository _trainRecordAnswerRepository;
  37. private readonly ITrainRecordItemRepository _trainRecordItemRepository;
  38. private readonly ITrainKnowladgeRepository _trainKnowladgeRepository;
  39. private readonly IMapper _mapper;
  40. private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder;
  41. private readonly IServiceProvider _serviceProvider;
  42. private readonly ISessionContext _sessionContext;
  43. public TrainRecordService(ITrainRecordRepository repository,
  44. ITrainRecordAnswerRepository trainRecordAnswerRepository,
  45. ITrainRecordItemRepository trainRecordItemRepository,
  46. ITrainKnowladgeRepository trainKnowladgeRepository,
  47. IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider,
  48. ISessionContext sessionContext,
  49. IMapper mapper) : base(repository, mapper, sessionContext)
  50. {
  51. this._repository = repository;
  52. this._trainRecordAnswerRepository = trainRecordAnswerRepository;
  53. this._trainRecordItemRepository = trainRecordItemRepository;
  54. this._trainKnowladgeRepository = trainKnowladgeRepository;
  55. this._mapper = mapper;
  56. this._dataPermissionFilterBuilder = dataPermissionFilterBuilder;
  57. this._serviceProvider = serviceProvider;
  58. this._sessionContext = sessionContext;
  59. }
  60. #region public method
  61. public async Task CompleteTrainRecordAsync(CompleteTrainRecordDto completeTrainRecordDto, CancellationToken cancellationToken)
  62. {
  63. var trainRecord = _mapper.Map<TrainRecord>(completeTrainRecordDto);
  64. trainRecord.ToUpdate(_sessionContext);
  65. await _repository.ValidateUpdateAsync(trainRecord, cancellationToken);
  66. }
  67. public async Task CompleteTrainKnowladgeAsync(CompleteTrainKnowladgeDto completeTrainPracticeDto, CancellationToken cancellationToken)
  68. {
  69. var trainKnowladge = _mapper.Map<TrainKnowladge>(completeTrainPracticeDto);
  70. trainKnowladge.ToUpdate(_sessionContext);
  71. await _trainKnowladgeRepository.ValidateUpdateAsync(trainKnowladge,cancellationToken);
  72. }
  73. public async Task<TrainRecordDto> GetAsync(EntityQueryRequest entityQueryRequest)
  74. {
  75. var trainRecord = await _repository.GetAsync(entityQueryRequest.Id);
  76. var trainRecordDto = _mapper.Map<TrainRecordDto>(trainRecord);
  77. trainRecordDto.KnowladgeDtos = await GetKnowladges(entityQueryRequest);
  78. trainRecordDto.QuestionDtos = await GetQuestions(entityQueryRequest);
  79. return trainRecordDto;
  80. }
  81. public async Task<(int, List<TrainRecordViewResponse>)> GetListAsync(TrainRecordPagedRequest queryRequest)
  82. {
  83. SqlSugar.ISugarQueryable<TrainRecordViewResponse> queryResult = QueryResult(queryRequest);
  84. var total = await queryResult.CountAsync();
  85. var items = await queryResult.ToListAsync();
  86. return (total, items);
  87. }
  88. public async Task<PageViewResponse<TrainRecordViewResponse>> GetPagedListAsync(TrainRecordPagedRequest queryRequest)
  89. {
  90. SqlSugar.ISugarQueryable<TrainRecordViewResponse> queryResult = QueryResult(queryRequest);
  91. var total = await queryResult.CountAsync();
  92. var items = await queryResult.ToPageListAsync(queryRequest.PageIndex,queryRequest.PageSize);
  93. return new TrainRecordPageViewResponse
  94. {
  95. Items = items,
  96. Pagination = new Pagination(queryRequest.PageIndex,queryRequest.PageSize,total)
  97. };
  98. }
  99. public async Task<TrainPracticeDto> TrainAsync(AddTrainDto addTrainDto, CancellationToken cancellationToken)
  100. {
  101. await AddTrainRecordItem(addTrainDto,cancellationToken);
  102. await AddTrainRecordAnswer(addTrainDto, cancellationToken);
  103. //var trainPracticeOptionsDtos = await GetTrainQuestionOptions(addTrainDto);
  104. return null;
  105. }
  106. public async Task<TrainPracticeDto> GetTrainPracticeAsync(TrainPracticeRequest trainPracticeRequest)
  107. {
  108. var trainPracticeRepostitory = new TrainPracticeRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  109. var trainPractice = await trainPracticeRepostitory.GetAsync(trainPracticeRequest.TrainPracticeId);
  110. if (trainPractice == null) return null;
  111. var trainPracticeDto = _mapper.Map<TrainPracticeDto>(trainPractice);
  112. trainPracticeDto.TrainPracticeOptionsDtos = await GetTrainQuestionOptions(trainPracticeRequest);
  113. trainPracticeDto.TrainPracticeSourcewareDtos = await GetTrainPracticeSourcewares(trainPracticeRequest);
  114. trainPracticeDto.TrainPracticeKnowladgeDtos = await GetTrainPracticeKnowladges(trainPracticeRequest);
  115. return trainPracticeDto;
  116. }
  117. public async Task<TrainResultPagedViewResponse> AnalysisTrainResult(TrainResultReportPagedRequest trainResultReportPagedRequest)
  118. {
  119. trainResultReportPagedRequest.ResoleEndTime();
  120. var expression = trainResultReportPagedRequest.GetExpression();
  121. var templateExpression = trainResultReportPagedRequest.GetTemplateExpression();
  122. var trainTemplateRepostitory = new ExamRepository<TrainTemplate>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  123. var trainPlanRepository = new ExamRepository<TrainPlan>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  124. var trainPlanTemplateRepository = new ExamRepository<TrainPlanTemplate>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  125. var userRepository = new ExamRepository<User>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  126. var trainPlanTable = trainPlanRepository.Queryable().Where(expression);
  127. var trainTemplateTable = trainTemplateRepostitory.Queryable().Where(templateExpression);
  128. var trainPlanTemplateTable = trainPlanTemplateRepository.Queryable();
  129. var trainRecordTable = _repository.Queryable();
  130. var userTable = userRepository.Queryable();
  131. var queryResult = trainRecordTable.InnerJoin(trainPlanTable, (r, p) => r.TrainPlanId == p.Id)
  132. .InnerJoin(trainPlanTemplateTable, (r, p, pt) => p.Id == pt.TrainPlanId)
  133. .InnerJoin(trainTemplateTable, (r, p, pt, t) => pt.TrainTemplateId == t.Id)
  134. .InnerJoin(userTable,(r,p,pt,t,u)=>r.UserId == u.Id)
  135. .Select((r, p, pt, t, u) => new TrainResultViewResponse
  136. {
  137. TrainName = t.Name,
  138. UserName = u.Name,
  139. IsComplete = r.IsComplete,
  140. SortIndex = r.SortIndex,
  141. Status = r.Status
  142. });
  143. var total = await queryResult.CountAsync();
  144. var items = await queryResult.ToPageListAsync(trainResultReportPagedRequest.PageIndex, trainResultReportPagedRequest.PageSize);
  145. return new TrainResultPagedViewResponse
  146. {
  147. Items = items,
  148. Pagination = new Pagination(trainResultReportPagedRequest.PageIndex, trainResultReportPagedRequest.PageSize, total)
  149. };
  150. }
  151. public async Task<TrainResultRateViewResponse> CalcuteAnalysisRate(TrainResultReportPagedRequest trainResultReportPagedRequest)
  152. {
  153. trainResultReportPagedRequest.ResoleEndTime();
  154. var expression = trainResultReportPagedRequest.GetExpression();
  155. var templateExpression = trainResultReportPagedRequest.GetTemplateExpression();
  156. var trainTemplateRepostitory = new ExamRepository<TrainTemplate>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  157. var trainPlanRepository = new ExamRepository<TrainPlan>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  158. var trainPlanTemplateRepository = new ExamRepository<TrainPlanTemplate>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  159. var trainPlanTable = trainPlanRepository.Queryable().Where(expression);
  160. var trainTemplateTable = trainTemplateRepostitory.Queryable().Where(templateExpression);
  161. var trainPlanTemplateTable = trainPlanTemplateRepository.Queryable();
  162. var trainRecordTable = _repository.Queryable();
  163. var queryResult = trainRecordTable.InnerJoin(trainPlanTable, (r, p) => r.TrainPlanId == p.Id)
  164. .InnerJoin(trainPlanTemplateTable, (r, p, pt) => p.Id == pt.TrainPlanId)
  165. .InnerJoin(trainTemplateTable, (r, p, pt, t) => pt.TrainTemplateId == t.Id)
  166. .Select((r, p, pt, t) => new TrainResultViewResponse
  167. {
  168. TrainName = t.Name,
  169. IsComplete = r.IsComplete,
  170. SortIndex = r.SortIndex,
  171. Status = r.Status,
  172. TrainTime = p.TrainEndTime
  173. });
  174. var calcuteRateResult = new TrainResultRateViewResponse
  175. {
  176. Complete = await queryResult.CountAsync(x=>x.IsComplete),
  177. Trainning = await queryResult.CountAsync(x => !x.IsComplete && x.TrainTime > DateTime.Now),
  178. UnComplete = await queryResult.CountAsync(x => !x.IsComplete && x.TrainTime <= DateTime.Now),
  179. };
  180. return calcuteRateResult;
  181. }
  182. #endregion
  183. #region private method
  184. private async Task AddTrainRecordItem(AddTrainDto addTrainDto, CancellationToken cancellationToken)
  185. {
  186. var trainRecordItem = _mapper.Map<TrainRecordItem>(addTrainDto);
  187. trainRecordItem.ToInsert(_sessionContext);
  188. await _trainRecordItemRepository.ValidateAddAsync(trainRecordItem, cancellationToken);
  189. }
  190. private SqlSugar.ISugarQueryable<TrainRecordViewResponse> QueryResult(TrainRecordPagedRequest queryRequest)
  191. {
  192. var trainPlanRepository = new TrainPlanRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  193. var expression = queryRequest.GetExpression();
  194. var trainPlanTable = trainPlanRepository.Queryable().Where(expression);
  195. var trainRecordTable = _repository.Queryable();
  196. var queryResult = trainPlanTable.InnerJoin(trainRecordTable, (p, r) => p.Id == r.TrainPlanId)
  197. .Select((p, r) => new TrainRecordViewResponse
  198. {
  199. Id = r.Id,
  200. TrainCode = p.Code,
  201. TrainName = p.Name,
  202. IsComplete = r.IsComplete,
  203. Status = r.Status,
  204. SortIndex = r.SortIndex,
  205. TrainEndTime = p.TrainEndTime,
  206. TrainStartTime = p.TrainStartTime
  207. });
  208. return queryResult;
  209. }
  210. private async Task<List<SimpleQuestionDto>> GetQuestions(EntityQueryRequest entityQueryRequest)
  211. {
  212. SqlSugar.ISugarQueryable<SimpleQuestionDto> queryable = QueryQuestions(entityQueryRequest);
  213. return await queryable.ToListAsync();
  214. }
  215. private SqlSugar.ISugarQueryable<SimpleQuestionDto> QueryQuestions(EntityQueryRequest entityQueryRequest)
  216. {
  217. var trainPlanRepository = new ExamRepository<TrainPlan>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  218. var trainPracticeRepository = new ExamRepository<TrainPractice>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  219. var trainPlanTemplateRepository = new ExamRepository<TrainPlanTemplate>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  220. var trainRecordTable = _repository.Queryable().Where(x => x.Id == entityQueryRequest.Id);
  221. var trainPlanTable = trainPlanRepository.Queryable();
  222. var trainPracticeTable = trainPracticeRepository.Queryable();
  223. var trainPlanTemplateTable = trainPlanTemplateRepository.Queryable();
  224. var queryable = trainRecordTable.InnerJoin(trainPlanTable, (r, p) => r.TrainPlanId == p.Id)
  225. .InnerJoin(trainPlanTemplateTable, (r, p, tpt) => p.Id == tpt.TrainPlanId)
  226. .InnerJoin(trainPracticeTable, (r, p, tpt, tp) => tpt.Id == tp.TrainTemplateId)
  227. .Select((r, p, tpt, tp) => new SimpleQuestionDto
  228. {
  229. Title = tp.Title,
  230. Id = tp.Id
  231. });
  232. return queryable;
  233. }
  234. private async Task<List<SimpleKnowladgeDto>> GetKnowladges(EntityQueryRequest entityQueryRequest)
  235. {
  236. var questionTable = QueryQuestions(entityQueryRequest);
  237. var questionSourcewareRepository = new ExamRepository<PracticeQuestionSourceware>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  238. var sourcewareRepository = new ExamRepository<KnowledgeBase.Knowledge>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  239. var questionSourcewareTable = questionSourcewareRepository.Queryable();
  240. var sourcewareTable = sourcewareRepository.Queryable();
  241. var queryable = questionTable.InnerJoin(questionSourcewareTable, (r, p) => r.Id == p.QuestionId)
  242. .InnerJoin(sourcewareTable, (r, p, sw) => p.SourcewareId == sw.Id)
  243. .Select((r, p, sw) => new SimpleKnowladgeDto
  244. {
  245. Title = sw.Title,
  246. Id = sw.Id
  247. });
  248. return await queryable.ToListAsync();
  249. }
  250. private async Task AddTrainRecordAnswer(AddTrainDto addTrainRecordDto, CancellationToken cancellationToken)
  251. {
  252. if (addTrainRecordDto.AddTrainRecordOptionDtos == null && addTrainRecordDto.AddTrainRecordAnswerDto == null) return;
  253. var trainRecordAnswers = new List<TrainRecordAnswer>();
  254. addTrainRecordDto.AddTrainRecordOptionDtos?.ForEach(item =>
  255. {
  256. trainRecordAnswers.Add(_mapper.Map<TrainRecordAnswer>(item));
  257. });
  258. if (addTrainRecordDto.AddTrainRecordAnswerDto != null)
  259. {
  260. trainRecordAnswers.Add(_mapper.Map<TrainRecordAnswer>(addTrainRecordDto.AddTrainRecordAnswerDto));
  261. }
  262. trainRecordAnswers.ToInsert(_sessionContext);
  263. await _trainRecordAnswerRepository.ValidateAddAsync(trainRecordAnswers,cancellationToken);
  264. }
  265. private async Task<TrainPracticeDto> GetTrainQuestionOptions(AddTrainDto addTrainDto)
  266. {
  267. var trainPracticeOptionsRepository = new ExamRepository<TrainPracticeOptions>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  268. var trainPracticeRepository = new ExamRepository<TrainPractice>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  269. // TODO: 获取未答题的第一道题
  270. var trainPractice = await trainPracticeRepository.Queryable()
  271. .Where(x => x.TrainTemplateId == addTrainDto.TrainTemplateId && x.Id!= addTrainDto.TrainPracticeId).OrderBy(x=>x.SortIndex).FirstAsync();
  272. var trainPracticeOptions = await trainPracticeOptionsRepository.Queryable().Where(x => x.TrainPracticeId == trainPractice.Id).ToListAsync();
  273. var trainPracticeOptionsDtos = new List<SimpleTrainPracticeOptionsDto>();
  274. trainPracticeOptions.ForEach(x =>
  275. {
  276. trainPracticeOptionsDtos.Add(_mapper.Map<SimpleTrainPracticeOptionsDto>(x));
  277. });
  278. var trainPracticeDto = _mapper.Map<TrainPracticeDto>(trainPractice);
  279. trainPracticeDto.TrainPracticeOptionsDtos = trainPracticeOptionsDtos;
  280. return trainPracticeDto;
  281. }
  282. private async Task<List<SimpleTrainPracticeOptionsDto>> GetTrainQuestionOptions(TrainPracticeRequest trainPracticeRequest)
  283. {
  284. var trainPracticeRepository = new ExamRepository<TrainPracticeOptions>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  285. var trainRecordAnswerRepository = new ExamRepository<TrainRecordAnswer>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  286. // TODO: 获取未阅卷的第一道题
  287. var trainPracticeOptions = trainPracticeRepository.Queryable().Where(x => x.TrainPracticeId == trainPracticeRequest.TrainPracticeId);
  288. var trainRecordOptions = await trainRecordAnswerRepository.Queryable()
  289. .InnerJoin<TrainRecord>((t,x)=>t.TrainRecordId == x.Id)
  290. .InnerJoin<TrainPlanTemplate>((t,x,p)=> x.TrainPlanId == p.TrainPlanId)
  291. .InnerJoin<TrainPractice>((t,x,p,tp)=> x.Id == tp.TrainTemplateId)
  292. .Where((t, x, p, tp) => tp.Id == trainPracticeRequest.TrainPracticeId)
  293. .Select((t, x, p, tp) => t)
  294. .ToListAsync();
  295. var trainPracticeOptionsDtos = new List<SimpleTrainPracticeOptionsDto>();
  296. trainPracticeOptions.ForEach(x =>
  297. {
  298. var trainPracticeOptionsDto = _mapper.Map<SimpleTrainPracticeOptionsDto>(x);
  299. trainPracticeOptionsDto.IsSelected = trainRecordOptions.Any(m => m.QuestionOptionId == x.QuestionOptionId);
  300. trainPracticeOptionsDtos.Add(trainPracticeOptionsDto);
  301. });
  302. return trainPracticeOptionsDtos;
  303. }
  304. private async Task<List<TrainPracticeKnowladgeDto>> GetTrainPracticeKnowladges(TrainPracticeRequest trainPracticeRequest)
  305. {
  306. var trainPracticeKnowladgeRepository = new ExamRepository<TrainPracticeKnowladge>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  307. var knowledgeRepository = new ExamRepository<KnowledgeBase.Knowledge>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  308. var trainPracticeRepostitory = new ExamRepository<TrainPractice>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  309. var expression = trainPracticeRequest.GetExpression();
  310. var trainPracticeTable = trainPracticeRepostitory.Queryable().Where(expression);
  311. var trainPracticeKnowladgeTable = trainPracticeKnowladgeRepository.Queryable();
  312. var knowledgeTable = knowledgeRepository.Queryable();
  313. var queryResult = trainPracticeTable.InnerJoin(trainPracticeKnowladgeTable, (t, tk) => t.QuestionId == tk.QuestionId)
  314. .InnerJoin(knowledgeTable, (t, tk, k) => tk.KnowladgeId == k.Id)
  315. .Select((t, tk, k) => new TrainPracticeKnowladgeDto
  316. {
  317. KnowladgeId = tk.KnowladgeId,
  318. QuestionId = tk.QuestionId,
  319. Title = k.Title
  320. });
  321. return await queryResult.ToListAsync();
  322. }
  323. private async Task<List<TrainPracticeSourcewareDto>> GetTrainPracticeSourcewares(TrainPracticeRequest trainPracticeRequest)
  324. {
  325. var trainPracticeSourcewareRepository = new ExamRepository<TrainPracticeSourceware>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  326. var sourcewareRepository = new ExamRepository<Sourceware>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  327. var trainPracticeRepostitory = new ExamRepository<TrainPractice>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  328. var expression = trainPracticeRequest.GetExpression();
  329. var trainPracticeTable = trainPracticeRepostitory.Queryable().Where(expression);
  330. var trainPracticeSourcewareTable = trainPracticeSourcewareRepository.Queryable();
  331. var sourcewareTable = sourcewareRepository.Queryable();
  332. var queryResult = trainPracticeTable.InnerJoin(trainPracticeSourcewareTable, (t, ts) => t.QuestionId == ts.QuestionId)
  333. .InnerJoin(sourcewareTable, (t, ts, sw) => ts.SourcewareId == sw.Id)
  334. .Select((t, ts, sw) => new TrainPracticeSourcewareDto
  335. {
  336. SourcewareId = ts.SourcewareId,
  337. QuestionId = ts.QuestionId,
  338. Name = sw.Name,
  339. });
  340. return await queryResult.ToListAsync();
  341. }
  342. #endregion
  343. }
  344. }