ExamManageService.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. using Exam.Infrastructure.Data.Entity;
  2. using Exam.Infrastructure.Enums;
  3. using Exam.Infrastructure.Extensions;
  4. using Exam.Share;
  5. using Exam.Share.ViewResponses.Exam;
  6. using Hotline.Application.Exam.Interface.ExamManages;
  7. using Hotline.Repository.SqlSugar;
  8. using Hotline.Repository.SqlSugar.DataPermissions;
  9. using Hotline.Repository.SqlSugar.Exam.Interfaces.ExamManages;
  10. using Hotline.Share.Requests.Exam;
  11. using MapsterMapper;
  12. using SqlSugar;
  13. using XF.Domain.Dependency;
  14. using XF.Domain.Entities;
  15. using Hotline.Application.Exam.QueryExtensions.ExamManages;
  16. using XF.Domain.Exceptions;
  17. using Hotline.Application.Exam.Extensions;
  18. using XF.Domain.Authentications;
  19. using Hotline.Repository.SqlSugar.Exam.Core.Constants;
  20. using Hotline.Exams.TestPapers;
  21. using Hotline.Application.Exam.Proxy;
  22. using Hotline.Repository.SqlSugar.Exam.Interfaces.TestPapers;
  23. using Hotline.Repository.SqlSugar.Exam.Interfaces.Questions;
  24. using Hotline.Users;
  25. using Hotline.Application.Exam.Core.Extensions;
  26. using Hotline.Application.Exam.Core.Utilities;
  27. using Hotline.Exams.ExamManages;
  28. using Hotline.Exams.Questions;
  29. using Hotline.Repository.SqlSugar.Exam.Interfaces.Exams;
  30. using Hotline.Repository.SqlSugar.Exam.Repositories;
  31. using ExamErrorMessage = Hotline.Exams.Validate.ExamErrorMessage;
  32. using ExamQuestion = Hotline.Exams.Questions.ExamQuestion;
  33. using Hotline.Repository.SqlSugar.Exam.Service;
  34. using Hotline.Repository.SqlSugar.Exam.Extensions;
  35. namespace Hotline.Application.Exam.Service.ExamManages
  36. {
  37. public class ExamManageService : ApiService<ExamManage, AddExamManageDto, UpdateExamManageDto, HotlineDbContext>, IExamManageService, IScopeDependency
  38. {
  39. private readonly IExamManageRepository _repository;
  40. private readonly IExamQuestionScoreRepository _examQuestionScoreRepository;
  41. private readonly IUserExamRepository _userExamRepository;
  42. private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder;
  43. private readonly ITestPaperRepository _testPaperRepository;
  44. private readonly ITestPaperItemRepository _testPaperItemRepository;
  45. private readonly ITestPaperItemAnswerRepository _testPaperItemAnswerRepository;
  46. private readonly ITestPaperItemOptionsRepository _testPaperItemOptionsRepository;
  47. private readonly ITestPaperItemSourcewareRepository _testPaperItemSourcewareRepository;
  48. private readonly ITestPaperItemKnowladgeRepository _testPaperItemKnowladgeRepository;
  49. private readonly IExamQuestionRepository _examQuestionRepository;
  50. private readonly IExamQuestionAnswerRepository _examQuestionAnswerRepository;
  51. private readonly IExamQuestionOptionsRepository _examQuestionOptionsRepository;
  52. private readonly IExamQuestionSourcewareRepository _examQuestionSourcewareRepository;
  53. private readonly IExamQuestionKnowladgeRepository _examQuestionKnowladgeRepository;
  54. private readonly IServiceProvider _serviceProvider;
  55. private readonly IMapper _mapper;
  56. private readonly ISessionContext _sessionContext;
  57. private TestPaperProxy _testPaperProxy;
  58. private ExamManageProxy _examManageProxy;
  59. private AddExamManageDto _addExamManageDto;
  60. public ExamManageService(IExamManageRepository repository,
  61. IExamQuestionScoreRepository examQuestionScoreRepository,
  62. IUserExamRepository userExamRepository,
  63. ITestPaperRepository testPaperRepository,
  64. ITestPaperItemRepository testPaperItemRepository,
  65. ITestPaperItemAnswerRepository testPaperItemAnswerRepository,
  66. ITestPaperItemOptionsRepository testPaperItemOptionsRepository,
  67. ITestPaperItemSourcewareRepository testPaperItemSourcewareRepository,
  68. ITestPaperItemKnowladgeRepository testPaperItemKnowladgeRepository,
  69. IExamQuestionRepository examQuestionRepository,
  70. IExamQuestionAnswerRepository examQuestionAnswerRepository,
  71. IExamQuestionOptionsRepository examQuestionOptionsRepository,
  72. IExamQuestionSourcewareRepository examQuestionSourcewareRepository,
  73. IExamQuestionKnowladgeRepository examQuestionKnowladgeRepository,
  74. IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider,
  75. IMapper mapper, ISessionContext sessionContext) : base(repository, mapper, sessionContext)
  76. {
  77. this._repository = repository;
  78. this._examQuestionScoreRepository = examQuestionScoreRepository;
  79. this._userExamRepository = userExamRepository;
  80. _dataPermissionFilterBuilder = dataPermissionFilterBuilder;
  81. this._testPaperRepository = testPaperRepository;
  82. this._testPaperItemRepository = testPaperItemRepository;
  83. this._testPaperItemAnswerRepository = testPaperItemAnswerRepository;
  84. this._testPaperItemOptionsRepository = testPaperItemOptionsRepository;
  85. this._testPaperItemSourcewareRepository = testPaperItemSourcewareRepository;
  86. this._testPaperItemKnowladgeRepository = testPaperItemKnowladgeRepository;
  87. this._examQuestionRepository = examQuestionRepository;
  88. this._examQuestionAnswerRepository = examQuestionAnswerRepository;
  89. this._examQuestionOptionsRepository = examQuestionOptionsRepository;
  90. this._examQuestionSourcewareRepository = examQuestionSourcewareRepository;
  91. this._examQuestionKnowladgeRepository = examQuestionKnowladgeRepository;
  92. _serviceProvider = serviceProvider;
  93. this._mapper = mapper;
  94. this._sessionContext = sessionContext;
  95. }
  96. #region public method
  97. public async Task<ExamManageDto> GetAsync(EntityQueryRequest entityQueryRequest)
  98. {
  99. var entity = await _repository.GetAsync(entityQueryRequest.Id);
  100. if (entity == null) return null;
  101. var questionDto = _mapper.Map<ExamManageDto>(entity);
  102. if (questionDto != null)
  103. {
  104. questionDto.ExamQuestionScoreDtos = await GetExamQuestionScores(entityQueryRequest, entity);
  105. if (entity.Mode == Share.Enums.Exams.EMethod.Random)
  106. {
  107. questionDto.TestPaperId = entity.ExtractRuleId;
  108. }
  109. questionDto.UserExamDtos = await GetUserExams(entityQueryRequest);
  110. }
  111. return questionDto;
  112. }
  113. public async Task<(int, List<ExamManageViewResponse>)> GetListAsync(ExamManagePagedRequest queryRequest)
  114. {
  115. ISugarQueryable<ExamManageViewResponse> queryable = Queryable(queryRequest);
  116. var result = await queryable.ToListAsync();
  117. var total = await queryable.CountAsync();
  118. return (total, result);
  119. }
  120. public async Task<PageViewResponse<ExamManageViewResponse>> GetPagedListAsync(ExamManagePagedRequest queryRequest)
  121. {
  122. ISugarQueryable<ExamManageViewResponse> queryable = Queryable(queryRequest);
  123. var list = await queryable.ToPageListAsync(queryRequest.PageIndex, queryRequest.PageSize);
  124. var total = await queryable.CountAsync();
  125. var result = new ExamManagePageViewResponse
  126. {
  127. Items = list,
  128. Pagination = new Pagination(queryRequest.PageIndex, queryRequest.PageSize, total)
  129. };
  130. return result;
  131. }
  132. public override async Task<string> AddAsync(AddExamManageDto actionRequest, CancellationToken cancellationToken)
  133. {
  134. CalcuteTotalScore(actionRequest);
  135. base.StartTran();
  136. var id = await base.AddAsync(actionRequest, cancellationToken);
  137. ResolveQuestionId(actionRequest, id);
  138. ResolveRandomExtractRuleId(actionRequest);
  139. base.Entity.ExamQuestionScores = await AddExamQuestionScores(actionRequest, cancellationToken);
  140. base.Entity.UserExams = await AddUserExam(actionRequest, cancellationToken);
  141. await base.Complete(base.Entity, OperationConstant.Create);
  142. await GenerateExamQuestion(new GenerateExamTestPaperRequest
  143. {
  144. TestPaperId = actionRequest.Mode == Share.Enums.Exams.EMethod.Unified ? actionRequest.TestPaperId : null,
  145. ExtractRuleId = actionRequest.Mode == Share.Enums.Exams.EMethod.Random ? actionRequest.TestPaperId : null,
  146. ExamManageId = id
  147. }, cancellationToken);
  148. return id;
  149. }
  150. private void ResolveRandomExtractRuleId(AddExamManageDto actionRequest)
  151. {
  152. if (actionRequest.Mode == Share.Enums.Exams.EMethod.Random)
  153. {
  154. base.Entity.ExtractRuleId = actionRequest.TestPaperId;
  155. base.Entity.TestPaperId = string.Empty;
  156. }
  157. }
  158. public override async Task UpdateAsync(UpdateExamManageDto actionRequest, CancellationToken cancellationToken)
  159. {
  160. CalcuteTotalScore(actionRequest);
  161. base.StartTran();
  162. await base.UpdateAsync(actionRequest, cancellationToken);
  163. ResolveQuestionId(actionRequest, actionRequest.Id);
  164. ResolveRandomExtractRuleId(actionRequest);
  165. MapAddUpdateExamManage(actionRequest);
  166. base.Entity.ExamQuestionScores = await ModifyExamQuestionScores(actionRequest, cancellationToken);
  167. base.Entity.UserExams = await ModifyUserExam(actionRequest, cancellationToken);
  168. await base.Complete(base.Entity, OperationConstant.Update);
  169. await GenerateExamQuestion(new GenerateExamTestPaperRequest {
  170. TestPaperId = actionRequest.Mode == Share.Enums.Exams.EMethod.Unified? actionRequest.TestPaperId:null,
  171. ExtractRuleId = actionRequest.Mode == Share.Enums.Exams.EMethod.Random ? actionRequest.TestPaperId : null,
  172. ExamManageId = actionRequest.Id
  173. }, cancellationToken);
  174. }
  175. private void MapAddUpdateExamManage(UpdateExamManageDto actionRequest)
  176. {
  177. _addExamManageDto = _mapper.Map<AddExamManageDto>(actionRequest);
  178. _addExamManageDto.UserExamDtos = new List<AddUserExamDto>();
  179. _addExamManageDto.ExamQuestionScoreDtos = new List<AddExamQuestionScoreDto>();
  180. actionRequest.UserExamDtos.ForEach(x =>
  181. {
  182. x.OperationStatus = x.Id != null ? EEOperationStatus.Update : EEOperationStatus.Add;
  183. if(x.OperationStatus== EEOperationStatus.Add)
  184. {
  185. _addExamManageDto.UserExamDtos.Add(_mapper.Map<AddUserExamDto>(x));
  186. }
  187. });
  188. actionRequest.ExamQuestionScoreDtos.ForEach(x =>
  189. {
  190. x.OperationStatus = x.Id != null ? EEOperationStatus.Update : EEOperationStatus.Add;
  191. if (x.OperationStatus == EEOperationStatus.Add)
  192. {
  193. _addExamManageDto.ExamQuestionScoreDtos.Add(_mapper.Map<AddExamQuestionScoreDto>(x));
  194. }
  195. });
  196. }
  197. public override async Task DeleteAsync(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken)
  198. {
  199. await base.DeleteAsync(entityQueryRequest, cancellationToken);
  200. var tmpEntityQueryRequest = ExpressionableUtility.CreateExpression<ExamQuestionScoreBak>()
  201. .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.ExamManageId == entityQueryRequest.Id)
  202. .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.ExamManageId))
  203. .ToEntityQueryRequest<ExamQuestionScoreBak>();
  204. await DeleteExamQuestionScores(tmpEntityQueryRequest, cancellationToken);
  205. tmpEntityQueryRequest = ExpressionableUtility.CreateExpression<ExamUserExam>()
  206. .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.ExamId == entityQueryRequest.Id)
  207. .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.ExamId))
  208. .ToEntityQueryRequest<ExamUserExam>();
  209. await DeleteUserExam(tmpEntityQueryRequest, cancellationToken);
  210. }
  211. public async Task GenerateTestPaper(GenerateExamTestPaperRequest generateExamTestPaperRequest, CancellationToken cancellationToken)
  212. {
  213. var expression = generateExamTestPaperRequest.GetExpression();
  214. var examManage = await _repository.GetAsync(expression);
  215. if (examManage != null)
  216. {
  217. var tagQuestionCounts = await GetTagQuestions(examManage);
  218. var questions = await GetQuestions(tagQuestionCounts);
  219. _testPaperProxy = new TestPaperProxy(_testPaperRepository,
  220. _testPaperItemRepository,
  221. _testPaperItemAnswerRepository,
  222. _testPaperItemOptionsRepository,
  223. _testPaperItemSourcewareRepository,
  224. _testPaperItemKnowladgeRepository,
  225. _dataPermissionFilterBuilder,
  226. _serviceProvider,
  227. _mapper,
  228. _sessionContext
  229. );
  230. await _testPaperProxy.DeleteTestPaperItems(generateExamTestPaperRequest.TestPaperId, cancellationToken);
  231. await _testPaperProxy.GenerateQuestion(questions, generateExamTestPaperRequest.TestPaperId, cancellationToken);
  232. }
  233. }
  234. public async Task GenerateExamQuestion(GenerateExamTestPaperRequest generateExamTestPaperRequest, CancellationToken cancellationToken)
  235. {
  236. var expression = generateExamTestPaperRequest.GetExpression();
  237. var examManages = await _repository.Queryable().Where(expression).ToListAsync();
  238. var examManage = examManages.FirstOrDefault();
  239. if (examManage != null)
  240. {
  241. var questions = new List<ExamQuestion>();
  242. if (examManage.Mode == Share.Enums.Exams.EMethod.Random)
  243. {
  244. var tagQuestionCounts = await GetTagQuestions(examManage);
  245. questions = await GetQuestions(tagQuestionCounts);
  246. }
  247. else
  248. {
  249. questions = await GetQuestions(examManage);
  250. }
  251. _examManageProxy = new ExamManageProxy(_repository,
  252. _examQuestionRepository,
  253. _examQuestionAnswerRepository,
  254. _examQuestionOptionsRepository,
  255. _examQuestionSourcewareRepository,
  256. _examQuestionKnowladgeRepository,
  257. _dataPermissionFilterBuilder,
  258. _serviceProvider,
  259. _mapper,
  260. _sessionContext
  261. );
  262. await _examManageProxy.DeleteExamQuestions(generateExamTestPaperRequest.ExamManageId, cancellationToken);
  263. await _examManageProxy.GenerateQuestion(questions, generateExamTestPaperRequest.ExamManageId, cancellationToken);
  264. }
  265. }
  266. private async Task<List<ExamQuestion>> GetQuestions(ExamManage examManage)
  267. {
  268. var questionRepository = new ExamRepository<ExamQuestion>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  269. var questionTable = questionRepository.Queryable();
  270. var testPaperItemTable = _testPaperItemRepository.Queryable().Where(x => x.TestPaperId == examManage.TestPaperId);
  271. var questions = questionTable.InnerJoin(testPaperItemTable, (q, t) => q.Id == t.QuestionId)
  272. .Select((q, t) => q);
  273. return await questions.ToListAsync();
  274. }
  275. private async Task<List<ExamTagQuestion>> GetTagQuestions(ExamManage examManage)
  276. {
  277. var extractRuleRepository = new ExamRepository<ExamExtractRule>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  278. var ruleTagRepository = new ExamRepository<ExamRuleTag>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  279. var tagQuestionRepository = new ExamRepository<ExamTagQuestion>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  280. var extractRuleTable = extractRuleRepository.Queryable().Where(x=>x.Id == examManage.ExtractRuleId && x.RuleType == examManage.ExamType);
  281. var ruleTagTable = ruleTagRepository.Queryable();
  282. var tagQuestionTable = tagQuestionRepository.Queryable();
  283. var tagQuestions = await tagQuestionTable
  284. .InnerJoin(ruleTagTable, (q, rt) => q.TagId == rt.TagId)
  285. .InnerJoin(extractRuleTable, (q, rt, x) => rt.RuleId == x.Id)
  286. .Select((q, rt, x) => q).ToListAsync();
  287. return tagQuestions;
  288. }
  289. #endregion
  290. #region private method
  291. private void ResolveQuestionId(AddExamManageDto actionRequest, string id)
  292. {
  293. actionRequest.UserExamDtos.ForEach(x => x.ExamId = id);
  294. actionRequest.ExamQuestionScoreDtos.ForEach(x => x.ExamManageId = id);
  295. }
  296. private void ResolveQuestionId(UpdateExamManageDto actionRequest, string id)
  297. {
  298. actionRequest.UserExamDtos.ForEach(x => x.ExamId = id);
  299. actionRequest.ExamQuestionScoreDtos.ForEach(x => x.ExamManageId = id);
  300. }
  301. private async Task<List<ExamQuestionScoreBak>> AddExamQuestionScores(AddExamManageDto actionRequest, CancellationToken cancellationToken)
  302. {
  303. if (actionRequest.ExamQuestionScoreDtos == null) return null;
  304. actionRequest.ExamQuestionScoreDtos.ResolveOperationStatus();
  305. var examQuestionScoreDtos = actionRequest.ExamQuestionScoreDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList();
  306. var examQuestionScores = _mapper.Map<List<ExamQuestionScoreBak>>(examQuestionScoreDtos);
  307. examQuestionScores.ToInsert(_sessionContext);
  308. await _examQuestionScoreRepository.ValidateAddAsync(examQuestionScores, cancellationToken);
  309. return examQuestionScores;
  310. }
  311. private async Task<List<ExamUserExam>> AddUserExam(AddExamManageDto actionRequest, CancellationToken cancellationToken)
  312. {
  313. if (actionRequest.UserExamDtos == null) return null;
  314. actionRequest.UserExamDtos.ResolveOperationStatus();
  315. var userExamDtos = actionRequest.UserExamDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList();
  316. var userExams = new List<ExamUserExam>();
  317. //_mapper.Map<List<UserExam>>(userExamDtos);
  318. userExamDtos.ForEach(x =>
  319. {
  320. userExams.Add(_mapper.Map<ExamUserExam>(x));
  321. });
  322. userExams.ToInsert(_sessionContext);
  323. await _userExamRepository.ValidateAddAsync(userExams, cancellationToken);
  324. return userExams;
  325. }
  326. private async Task<List<ExamUserExam>> UpdateUserExam(UpdateExamManageDto actionRequest, List<ExamUserExam> all, CancellationToken cancellationToken)
  327. {
  328. if (actionRequest.UserExamDtos == null) return null;
  329. var userExamDtos = actionRequest.UserExamDtos.Where(x => x.OperationStatus == EEOperationStatus.Update).ToList();
  330. var ids = userExamDtos.Select(x => x.Id);
  331. var userExams = all.Where(x => ids.Contains(x.Id)).ToList();
  332. //userExams = _mapper.Map<List<UpdateUserExamDto>, List<UserExam>>(userExamDtos, userExams);
  333. userExams.ForEach(item =>
  334. {
  335. var userExamDto = userExamDtos.FirstOrDefault(x => x.Id == item.Id);
  336. if (userExamDto != null)
  337. _mapper.Map<UpdateUserExamDto, ExamUserExam>(userExamDto, item);
  338. });
  339. userExams.ToUpdate(_sessionContext);
  340. await _userExamRepository.ValidateUpdateAsync(userExams, cancellationToken);
  341. return userExams;
  342. }
  343. private async Task<List<ExamQuestionScoreBak>> UpdateExamQuestionScores(UpdateExamManageDto actionRequest, List<ExamQuestionScoreBak> all, CancellationToken cancellationToken)
  344. {
  345. if (actionRequest.ExamQuestionScoreDtos == null) return null;
  346. var examQuestionScoreDtos = actionRequest.ExamQuestionScoreDtos.Where(x => x.OperationStatus == EEOperationStatus.Update).ToList();
  347. var ids = examQuestionScoreDtos.Select(x => x.Id);
  348. var examQuestionScores = all.Where(x => ids.Contains(x.Id)).ToList();
  349. //examQuestionScores = _mapper.Map<List<UpdateExamQuestionScoreDto>, List<ExamQuestionScore>>(examQuestionScoreDtos, examQuestionScores);
  350. examQuestionScores.ForEach(item =>
  351. {
  352. var examQuestionScoreDto = examQuestionScoreDtos.FirstOrDefault(x => x.Id == item.Id);
  353. if (examQuestionScoreDto != null)
  354. item = _mapper.Map<UpdateExamQuestionScoreDto, ExamQuestionScoreBak>(examQuestionScoreDto, item);
  355. });
  356. examQuestionScores.ToUpdate(_sessionContext);
  357. await _examQuestionScoreRepository.ValidateUpdateAsync(examQuestionScores, cancellationToken);
  358. return examQuestionScores;
  359. }
  360. private async Task DeleteUserExam(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken)
  361. {
  362. await _userExamRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken);
  363. }
  364. private async Task DeleteExamQuestionScores(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken)
  365. {
  366. await _examQuestionScoreRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken);
  367. }
  368. private async Task<List<ExamUserExam>> ModifyUserExam(UpdateExamManageDto actionRequest, CancellationToken cancellationToken)
  369. {
  370. if (actionRequest.UserExamDtos == null) return null;
  371. var all = await _userExamRepository.Queryable().Where(x => x.ExamId == actionRequest.Id).ToListAsync();
  372. actionRequest.UserExamDtos.ResolveOperationStatus(all);
  373. var userExams = new List<ExamUserExam>();
  374. userExams.AddRangeExt(await AddUserExam(_addExamManageDto, cancellationToken));
  375. userExams.AddRangeExt(await UpdateUserExam(actionRequest, all, cancellationToken));
  376. var questionOptionsDtos = actionRequest.UserExamDtos.Where(x => x.OperationStatus == EEOperationStatus.Delete);
  377. var ids = questionOptionsDtos.Select(m => m.Id);
  378. EntityQueryRequest entityQueryRequest = ResovleDelete<ExamUserExam>(ids);
  379. await DeleteUserExam(entityQueryRequest, cancellationToken);
  380. return userExams;
  381. }
  382. private async Task<List<ExamQuestionScoreBak>> ModifyExamQuestionScores(UpdateExamManageDto actionRequest, CancellationToken cancellationToken)
  383. {
  384. if (actionRequest.ExamQuestionScoreDtos == null) return null;
  385. var all = await _examQuestionScoreRepository.Queryable().Where(x => x.ExamManageId == actionRequest.Id).ToListAsync();
  386. var examQuestionScores = new List<ExamQuestionScoreBak>();
  387. examQuestionScores.AddRangeExt(await AddExamQuestionScores(_addExamManageDto, cancellationToken));
  388. examQuestionScores.AddRangeExt(await UpdateExamQuestionScores(actionRequest, all, cancellationToken));
  389. var examQuestionScoreDtos = actionRequest.ExamQuestionScoreDtos.Where(x => x.OperationStatus == EEOperationStatus.Delete);
  390. var ids = examQuestionScoreDtos.Select(m => m.Id);
  391. EntityQueryRequest entityQueryRequest = ResovleDelete<ExamQuestionScoreBak>(ids);
  392. await DeleteExamQuestionScores(entityQueryRequest, cancellationToken);
  393. return examQuestionScores;
  394. }
  395. private EntityQueryRequest ResovleDelete<T>(IEnumerable<string> ids) where T : class, IEntity<string>, new()
  396. {
  397. Expressionable<T> expressionable = ExpressionableUtility.CreateExpression<T>();
  398. expressionable.AndIF(ids.Any(), x => ids.Contains(x.Id));
  399. var entityQueryRequest = new EntityQueryRequest
  400. {
  401. Expression = ids.Any() ? expressionable.ToExpression() : null
  402. };
  403. return entityQueryRequest;
  404. }
  405. private async Task<List<UserExamDto>> GetUserExams(EntityQueryRequest entityQueryRequest)
  406. {
  407. var userRepository = new ExamRepository<User>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  408. var userExams = _userExamRepository.Queryable().Where(x => x.ExamId == entityQueryRequest.Id);
  409. var userTable = userRepository.Queryable();
  410. var userExamDtos = userExams.InnerJoin(userTable,(e,u)=>e.UserId == u.Id).Select((e, u) => new UserExamDto
  411. {
  412. Id = e.Id,
  413. Name = u.Name,
  414. ExamId = e.ExamId,
  415. UserId = e.UserId,
  416. FullOrgName = u.FullOrgName
  417. });
  418. return await userExamDtos.ToListAsync();
  419. }
  420. private async Task<List<ExamQuestionScoreDto>> GetExamQuestionScores(EntityQueryRequest entityQueryRequest,ExamManage examManage)
  421. {
  422. var examQuestionScores = _examQuestionScoreRepository.Queryable().Where(x => x.ExamManageId == entityQueryRequest.Id);
  423. var examQuestionScoreDtos = examQuestionScores.Select(q => new ExamQuestionScoreDto
  424. {
  425. Id = q.Id,
  426. QuestionType = q.QuestionType,
  427. ExamManageId = q.ExamManageId,
  428. Score = q.Score
  429. });
  430. if(examManage.Mode == Share.Enums.Exams.EMethod.Random)
  431. {
  432. var tagQuestionRepository = new ExamRepository<ExamTagQuestion>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  433. var tagQuestionTable = tagQuestionRepository.Queryable().Where(x => x.RuleId == examManage.ExtractRuleId);
  434. var result = examQuestionScoreDtos.InnerJoin(tagQuestionTable, (e, t) => e.QuestionType == t.QuestionType).Select((e, t) => new ExamQuestionScoreDto
  435. {
  436. Id = e.Id,
  437. QuestionType = e.QuestionType,
  438. ExamManageId = e.ExamManageId,
  439. Score = e.Score,
  440. Count = t.Count
  441. }).Distinct();
  442. return await result.ToListAsync();
  443. }
  444. else
  445. {
  446. var testPaperItemRepository = new ExamRepository<ExamTestPaperItem>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  447. var testPaperItemTable = testPaperItemRepository.Queryable().Where(x => x.TestPaperId == examManage.TestPaperId);
  448. var result = examQuestionScoreDtos.InnerJoin(testPaperItemTable, (e, t) => e.QuestionType == t.QuestionType)
  449. .GroupBy((e, t) => new
  450. {
  451. Id = e.Id,
  452. QuestionType = e.QuestionType,
  453. ExamManageId = e.ExamManageId,
  454. Score = e.Score,
  455. })
  456. .Select((e, t) => new ExamQuestionScoreDto
  457. {
  458. Id = e.Id,
  459. QuestionType = e.QuestionType,
  460. ExamManageId = e.ExamManageId,
  461. Score = e.Score,
  462. Count = SqlFunc.AggregateCount(t.Id)
  463. });
  464. return await result.ToListAsync();
  465. }
  466. }
  467. private void CalcuteTotalScore(AddExamManageDto actionRequest)
  468. {
  469. if (actionRequest.ExamQuestionScoreDtos == null) return;
  470. var examQuestionScoreDtos = actionRequest.ExamQuestionScoreDtos.Where(x => x.OperationStatus != EEOperationStatus.Delete);
  471. var totalScore = examQuestionScoreDtos.Sum(x => x.Count * x.Score);
  472. if (totalScore != actionRequest.TotalScore)
  473. {
  474. throw new UserFriendlyException(ExamErrorMessage.ServiceError, string.Format(ExamErrorMessage.IsNotEqual, "试题分数总和", typeof(AddExamManageDto).GetDescription(nameof(AddExamManageDto.TotalScore))));
  475. }
  476. }
  477. private ISugarQueryable<ExamManageViewResponse> Queryable(ExamManagePagedRequest queryRequest)
  478. {
  479. var expression = queryRequest.GetExpression();
  480. var questionTable = _repository.Queryable().Where(expression);
  481. var queryable = questionTable.Select(e => new ExamManageViewResponse
  482. {
  483. Id = e.Id,
  484. Code = e.Code,
  485. Count = e.Count,
  486. CutoffScore = e.CutoffScore,
  487. EndTime = e.EndTime,
  488. ExamStatus = e.ExamStatus,
  489. ExamType = e.ExamType,
  490. Mode = e.Mode,
  491. Name = e.Name,
  492. Remark = e.Name,
  493. SortIndex = e.SortIndex,
  494. StartTime = e.StartTime,
  495. TimeSpan = e.TimeSpan,
  496. TotalScore = e.TotalScore,
  497. });
  498. return queryable;
  499. }
  500. private async Task<List<ExamQuestion>> GetQuestions(List<ExamTagQuestion> tagQuestionCounts)
  501. {
  502. var questionRepository = new ExamRepository<ExamQuestion>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  503. var questionTagRepository = new ExamRepository<ExamQuestionTag>(_uow, _dataPermissionFilterBuilder, _serviceProvider);
  504. var questionTable = questionRepository.Queryable();
  505. var questionTagTable = questionTagRepository.Queryable();
  506. if (tagQuestionCounts != null && tagQuestionCounts.Any())
  507. {
  508. var questionQuerables = new List<ISugarQueryable<ExamQuestion>>();
  509. tagQuestionCounts.ForEach(item =>
  510. {
  511. ISugarQueryable<ExamQuestion> queryable = questionRepository.Queryable().InnerJoin(questionTagTable, (q, t) => q.Id == t.QuestionId)
  512. .Where((q, t) => q.QuestionType == item.QuestionType && t.TagId == item.TagId).Take(item.Count).Select((q, t) => q);
  513. questionQuerables.Add(queryable);
  514. });
  515. var queryResult = questionRepository.UnionAll(questionQuerables.ToArray());
  516. return await queryResult.ToListAsync();
  517. }
  518. else
  519. {
  520. return null;
  521. }
  522. }
  523. #endregion
  524. }
  525. }