ExamManageService.cs 30 KB

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