using DocumentFormat.OpenXml.Office2010.Excel; using Exam.Infrastructure.Data.Entity; using Exam.Infrastructure.Data.Interface; using Exam.Infrastructure.Enums; using Exam.Infrastructure.Extensions; using Exam.Repository.Sqlsugar; using Exam.Share.ViewResponses.TestPaper; using Hotline.Application.Exam.Core.Extensions; using Hotline.Application.Exam.Extensions; using Hotline.Application.Exam.Proxy; using Hotline.Application.Exam.QueryExtensions.TestPapers; using Hotline.Exams.TestPapers; using Hotline.Repository.SqlSugar; using Hotline.Repository.SqlSugar.DataPermissions; using Hotline.Repository.SqlSugar.Exam.Core.Constants; using Hotline.Repository.SqlSugar.Exam.Interfaces.Questions; using Hotline.Repository.SqlSugar.Exam.Interfaces.TestPapers; using Hotline.Repository.SqlSugar.Exam.Repositories.TestPapers; using Hotline.Share.Dtos.Questions; using Hotline.Share.Dtos.TestPapers; using Hotline.Share.Dtos.Trains; using Hotline.Share.Requests.Exam; using Hotline.Share.Requests.TestPaper; using Hotline.Share.Tools; using Hotline.Share.ViewResponses.Exam; using Hotline.Share.ViewResponses.Questions; using JiebaNet.Segmenter.Common; using MapsterMapper; using Microsoft.Extensions.DependencyInjection; using NPOI.SS.Formula.Functions; using SqlSugar; using System.Collections.Immutable; using Hotline.Application.Exam.Core.Utilities; using Hotline.Application.Exam.Interface.TestPapers; using Hotline.Exams.ExamManages; using Hotline.Exams.Questions; using Hotline.Repository.SqlSugar.Exam.Repositories; using XF.Domain.Authentications; using XF.Domain.Dependency; using XF.Domain.Repository; using ExamQuestion = Hotline.Exams.Questions.ExamQuestion; using ExamQuestionAnswer = Hotline.Exams.Questions.ExamQuestionAnswer; using ExamQuestionKnowladge = Hotline.Exams.Questions.ExamQuestionKnowladge; using ExamQuestionOptions = Hotline.Exams.Questions.ExamQuestionOptions; using ExamQuestionSourceware = Hotline.Exams.Questions.ExamQuestionSourceware; using Hotline.Repository.SqlSugar.Exam.Service; using Hotline.Repository.SqlSugar.Exam.Extensions; namespace Hotline.Application.Exam.Service.TestPapers { public class TestPaperService : ApiService, ITestPaperService, IScopeDependency { private readonly ITestPaperRepository _repository; private readonly ITestPaperItemRepository _testPaperItemRepository; private readonly ITestPaperRuleRepository _testPaperRuleRepository; private readonly ITestPaperRuleTagRepository _testPaperRuleTagRepository; private readonly ITestPaperItemAnswerRepository _testPaperItemAnswerRepository; private readonly ITestPaperItemOptionsRepository _testPaperItemOptionsRepository; private readonly ITestPaperItemSourcewareRepository _testPaperItemSourcewareRepository; private readonly ITestPaperItemKnowladgeRepository _testPaperItemKnowladgeRepository; private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder; private readonly IServiceProvider _serviceProvider; private readonly ISessionContext _sessionContext; private readonly IMapper _mapper; private TestPaperProxy _testPaperProxy; private AddTestPaperDto _addTestPaperDto; public TestPaperService(ITestPaperRepository repository, ITestPaperRuleRepository testPaperRuleRepository, ITestPaperRuleTagRepository testPaperRuleTagRepository, ITestPaperItemRepository testPaperItemRepository, ITestPaperItemAnswerRepository testPaperItemAnswerRepository, ITestPaperItemOptionsRepository testPaperItemOptionsRepository, ITestPaperItemSourcewareRepository testPaperItemSourcewareRepository, ITestPaperItemKnowladgeRepository testPaperItemKnowladgeRepository, IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider, ISessionContext sessionContext, IMapper mapper) : base(repository, mapper, sessionContext) { _repository = repository; _testPaperItemRepository = testPaperItemRepository; _testPaperRuleRepository = testPaperRuleRepository; _testPaperRuleTagRepository = testPaperRuleTagRepository; this._testPaperItemAnswerRepository = testPaperItemAnswerRepository; this._testPaperItemOptionsRepository = testPaperItemOptionsRepository; this._testPaperItemSourcewareRepository = testPaperItemSourcewareRepository; this._testPaperItemKnowladgeRepository = testPaperItemKnowladgeRepository; _dataPermissionFilterBuilder = dataPermissionFilterBuilder; _serviceProvider = serviceProvider; this._sessionContext = sessionContext; _mapper = mapper; } #region public method public async Task GetAsync(EntityQueryRequest entityQueryRequest) { var entity = await _repository.GetAsync(entityQueryRequest.Id); var testPaperDto = _mapper.Map(entity); testPaperDto.TestPaperItemDtos = await GetTestPaperItemDtos(entityQueryRequest); testPaperDto.TestPaperRuleDtos = await GetTestPaperRuleDtos(entityQueryRequest); return testPaperDto; } public async Task<(int, List)> GetListAsync(TestPaperPagedRequest queryRequest) { queryRequest.Status = queryRequest.Status ?? Share.Enums.Exams.EPublicStatus.Valid; ISugarQueryable queryable = QueryResult(queryRequest); var result = await queryable.ToListAsync(); var total = await queryable.CountAsync(); return (total, result); } public async Task> GetPagedListAsync(TestPaperPagedRequest queryRequest) { ISugarQueryable queryable = QueryResult(queryRequest); var list = await queryable.ToPageListAsync(queryRequest.PageIndex, queryRequest.PageSize); var total = await queryable.CountAsync(); var result = new TestPaperPageViewResponse { Items = list, Pagination = new Pagination(queryRequest.PageIndex, queryRequest.PageSize, total) }; return result; } /// /// 新增试卷 /// /// /// /// public override async Task AddAsync(AddTestPaperDto actionRequest, CancellationToken cancellationToken) { base.StartTran(); var id = await base.AddAsync(actionRequest, cancellationToken); ResolveTestPaperId(actionRequest, id); base.Entity.TestPaperItems = await AddTestPaperItems(actionRequest, cancellationToken); var testPaperItemAnswers = await AddTestPaperItemAnswer(actionRequest, cancellationToken); var testPaperItemOptions = await AddTestPaperItemOptions(actionRequest, cancellationToken); var testPaperItemKnowlagdes = await AddTestPaperItemKnowladgeAsync(actionRequest, cancellationToken); var testPaperItemSourcewares = await AddTestPaperItemSourcewareAsync(actionRequest, cancellationToken); base.Entity.TestPaperItems.ForEach(item => { item.TestPaperItemSourcewares = testPaperItemSourcewares.Where(x => item.Id == x.TestPaperItemId).ToList(); item.TestPaperItemAnswers = testPaperItemAnswers.Where(x => item.Id == x.TestPaperItemId).ToList(); item.TestPaperItemKnowlagdes = testPaperItemKnowlagdes.Where(x => item.Id == x.TestPaperItemId).ToList(); item.TestPaperItemOptionses = testPaperItemOptions.Where(x => item.Id == x.TestPaperItemId).ToList(); }); //base.Entity.TestPaperRules = await AddTestPaperRules(actionRequest, cancellationToken); //var testPaperRuleTags = await AddTestPaperRuleTags(actionRequest, cancellationToken); //base.Entity.TestPaperRules?.ForEach(item => //{ // item.TestPaperRuleTags = testPaperRuleTags.Where(m => item.Id == m.TestPaperRuleId).ToList(); //}); await base.Complete(base.Entity, OperationConstant.Create); //await GenerateTestPaper(new GenerateTestPaperRequest { TestPaperId = id }, cancellationToken); return id; } /// /// 修改试卷 /// /// /// /// public override async Task UpdateAsync(UpdateTestPaperDto actionRequest, CancellationToken cancellationToken) { base.StartTran(); await base.UpdateAsync(actionRequest, cancellationToken); ResolveTestPaperId(actionRequest, actionRequest.Id); _addTestPaperDto = _mapper.Map(actionRequest); base.Entity.TestPaperItems = await ModifyTestPaperItems(actionRequest, cancellationToken); var testPaperItemAnswers = await ModifyTestPaperItemAnswer(actionRequest, cancellationToken); var testPaperItemOptions = await ModifyTestPaperItemOptions(actionRequest, cancellationToken); var testPaperItemKnowlagdes = await ModifyTestPaperItemKnowladgeAsync(actionRequest, cancellationToken); var testPaperItemSourcewares = await ModifyTestPaperItemSourcewareAsync(actionRequest, cancellationToken); base.Entity.TestPaperItems.ForEach(item => { item.TestPaperItemAnswers = testPaperItemAnswers.Where(x => item.Id == x.TestPaperItemId).ToList(); item.TestPaperItemSourcewares = testPaperItemSourcewares.Where(x => item.Id == x.TestPaperItemId).ToList(); item.TestPaperItemKnowlagdes = testPaperItemKnowlagdes.Where(x => item.Id == x.TestPaperItemId).ToList(); item.TestPaperItemOptionses = testPaperItemOptions.Where(x => item.Id == x.TestPaperItemId).ToList(); }); await base.Complete(base.Entity, OperationConstant.Update); //await GenerateTestPaper(new GenerateTestPaperRequest { TestPaperId = actionRequest.Id }, cancellationToken); } /// /// 删除试卷 /// /// /// /// public override async Task DeleteAsync(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { var testPaperRuleTags = await GetTestPaperRuleTags(entityQueryRequest); await base.DeleteAsync(entityQueryRequest, cancellationToken); var tempEntityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.TestPaperId == entityQueryRequest.Id) .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.TestPaperId)).ToEntityQueryRequest(); await DeleteTestPaperItems(tempEntityQueryRequest, cancellationToken); tempEntityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.TestPaperId == entityQueryRequest.Id) .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.TestPaperId)).ToEntityQueryRequest(); await DeleteTestPaperRules(tempEntityQueryRequest, cancellationToken); var ids = testPaperRuleTags.Select(x => x.Id).ToList(); tempEntityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(ids.IsNotNull(), x => ids.Contains(x.Id)).ToEntityQueryRequest(); await DeleteTestPaperRuleTags(tempEntityQueryRequest, cancellationToken); } /// /// 获取试卷试题数量 /// /// /// public async Task> GetTestPaperQuestionCount(TestPaperQuestionCountRequest testPaperQuestionCountRequest) { var testPaperQuestionCountViewResponses = new List(); if (testPaperQuestionCountRequest.TestPaperId.IsNotNullOrEmpty()) { testPaperQuestionCountViewResponses = await CalcuteManualQuestionCount(testPaperQuestionCountRequest); } else if(testPaperQuestionCountRequest.ExtractRuleId.IsNotNullOrEmpty()) { testPaperQuestionCountViewResponses = await CalcuteRandomQuestionCount(testPaperQuestionCountRequest); } return testPaperQuestionCountViewResponses; } /// /// 根据规则获取试题 /// /// /// /// public async Task> GetQuestionDtos(TestPaperQuestionRequest testPaperQuestionRequest) { var questions = await GetQuestions(testPaperQuestionRequest); return questions; } /// /// 组卷 /// /// /// /// public async Task GenerateTestPaper(GenerateTestPaperRequest generateTestPaperRequest, CancellationToken cancellationToken) { var testPaper = await _repository.GetAsync(x => x.Id == generateTestPaperRequest.TestPaperId); if (testPaper != null) { //随机组卷 if (testPaper.Mode == Share.Enums.Exams.EExamMode.Random) { var questions = await GetQuestions(generateTestPaperRequest); _testPaperProxy = new TestPaperProxy(_repository, _testPaperItemRepository, _testPaperItemAnswerRepository, _testPaperItemOptionsRepository, _testPaperItemSourcewareRepository, _testPaperItemKnowladgeRepository, _dataPermissionFilterBuilder, _serviceProvider, _mapper, _sessionContext); //删除已经生成的试卷试题 await _testPaperProxy.DeleteTestPaperItems(generateTestPaperRequest.TestPaperId, cancellationToken); await _testPaperProxy.GenerateQuestion(questions, generateTestPaperRequest.TestPaperId, cancellationToken); } } } private async Task> GetQuestions(TestPaperQuestionRequest testPaperQuestionRequest) { var questionRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var questionTagRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var expression = testPaperQuestionRequest.GetExpression(); var questionExpression = testPaperQuestionRequest.GetQuestionExpression(); var questionTagTable = questionTagRepository.Queryable().Where(expression); var questionTable = questionRepository.Queryable().Where(questionExpression); var questions = await questionTable.LeftJoin(questionTagTable, (q, qt) => q.Id == qt.QuestionId) .Select((q, qt) => q).Take(testPaperQuestionRequest.Count).OrderBy(q => SqlFunc.GetRandom()).ToListAsync(); var questionDtos = new List(); questions.ForEach(item => { var questionDto = _mapper.Map(item); if (questionDto != null) { questionDtos.Add(questionDto); } }); return questionDtos; } private async Task> GetQuestions(GenerateTestPaperRequest generateTestPaperRequest) { var questionRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var questionTagRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var testPaperRuleTable = _testPaperRuleRepository.Queryable().Where(x => x.TestPaperId == generateTestPaperRequest.TestPaperId); var testPaperTagTable = _testPaperRuleTagRepository.Queryable(); var questionTagTable = questionTagRepository.Queryable(); var questionTable = questionRepository.Queryable(); var count = await testPaperRuleTable.Select(x => x.Count).FirstAsync(); var questions = await questionTable.LeftJoin(questionTagTable, (q, qt) => q.Id == qt.QuestionId) .LeftJoin(testPaperTagTable, (q, qt, tt) => qt.TagId == tt.TagId) .LeftJoin(testPaperRuleTable, (q, qt, tt, tpr) => tt.TestPaperRuleId == tpr.Id) .Where((q, qt, tt, tpr) => q.QuestionType == tpr.QuestionType) .Select((q, qt, tt, tpr) => q).Take(count).OrderBy(q => SqlFunc.GetRandom()).ToListAsync(); return questions; } /// /// 获取标签试题数 /// /// /// /// public async Task GetTagQuestionCount(TagQuestionCountRequest tagQuestionCountRequest) { var expression = tagQuestionCountRequest.GetExpression(); var questionExpression = tagQuestionCountRequest.GetQuestionExpression(); var tagQuestionRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var quesitonRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var tagQuestionTable = tagQuestionRepository.Queryable().Where(expression); var questionTable = quesitonRepository.Queryable().Where(questionExpression); var taqQuestions = await tagQuestionTable.InnerJoin(questionTable, (t, q) => t.QuestionId == q.Id).GroupBy((t, q) => q.Id) .Select((t, q) =>q.Id) .ToListAsync(); var result = new TagQuestionCountViewResponse { TotalCount = taqQuestions != null ? taqQuestions.Count() : 0 }; return result; } #endregion #region private method /// /// 获取查询结果 /// /// /// private ISugarQueryable QueryResult(TestPaperPagedRequest queryRequest) { var expression = queryRequest.GetExpression(); var query = _repository.Queryable().Where(expression); var querable = query.OrderBy(o => o.SortIndex).Select(m => new TestPaperViewResponse { Name = m.Name, ExamType = m.ExamType, Mode = m.Mode, Code = m.Code, Id = m.Id, Status = m.Status, SortIndex = m.SortIndex, Remark = m.Remark, }); return querable; } private async Task> ModifyTestPaperItemOptions(UpdateTestPaperDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TestPaperItemDtos == null) return null; var questionIds = actionRequest.TestPaperItemDtos.Where(x => x.QuestionType.CheckSelectType()).Select(x => x.QuestionId).ToList(); var entityQueryRequest = new EntityQueryRequest { Expression = ExpressionableUtility.CreateExpression() .AndIF(questionIds.IsNotNullOrEmpty(), x => questionIds.Contains(x.QuestionId)).ToExpression() }; await DeleteTestPaperItemOptions(entityQueryRequest, cancellationToken); return await AddTestPaperItemOptions(_addTestPaperDto, cancellationToken); } private async Task DeleteTestPaperItemOptions(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _testPaperItemOptionsRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task> ModifyTestPaperItemAnswer(UpdateTestPaperDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TestPaperItemDtos == null) return null; var questionIds = actionRequest.TestPaperItemDtos.Where(x => !x.QuestionType.CheckSelectType()).Select(x => x.QuestionId).ToList(); var entityQueryRequest = new EntityQueryRequest { Expression = ExpressionableUtility.CreateExpression() .AndIF(questionIds.IsNotNullOrEmpty(), x => questionIds.Contains(x.QuestionId)).ToExpression() }; await DeleteTestPaperItemAnswer(entityQueryRequest, cancellationToken); return await AddTestPaperItemAnswer(_addTestPaperDto, cancellationToken); } private async Task DeleteTestPaperItemAnswer(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _testPaperItemAnswerRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task> AddTestPaperRules(AddTestPaperDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TestPaperRuleDtos == null) return null; if (actionRequest.Mode == Share.Enums.Exams.EExamMode.Manual) return null; actionRequest.TestPaperRuleDtos.ResolveOperationStatus(); var testPaperRuleDtos = actionRequest.TestPaperRuleDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList(); var testPaperRules = _mapper.Map>(testPaperRuleDtos); testPaperRules.ToInsert(_sessionContext); await _testPaperRuleRepository.ValidateAddAsync(testPaperRules, cancellationToken); return testPaperRules; } private async Task> AddTestPaperItems(AddTestPaperDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TestPaperItemDtos == null) return null; actionRequest.TestPaperItemDtos.ResolveOperationStatus(); var testPaperItemDtos = actionRequest.TestPaperItemDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList(); var testPaperItems = _mapper.Map>(testPaperItemDtos); //试题排序,为后续考试顺序出题做准备 var index = 0; testPaperItems.ForEach(x => { x.SortIndex = ++index; }); testPaperItems.ToInsert(_sessionContext); await _testPaperItemRepository.ValidateAddAsync(testPaperItems, cancellationToken); return testPaperItems; } private async Task> AddTestPaperRuleTags(AddTestPaperDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TestPaperRuleDtos == null) return null; actionRequest.TestPaperRuleDtos.ResolveOperationStatus(); var testPaperRuleDtos = actionRequest.TestPaperRuleDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList(); var testPaperRuleTagDtos = new List(); testPaperRuleDtos.ForEach(item => { var testPaperRuleId = string.Empty; if (base.Entity != null) { //var testPaperRule = base.Entity.TestPaperRules.FirstOrDefault(x => x.TestPaperId == item.TestPaperId //&& x.QuestionType == item.QuestionType && x.Count == item.Count && x.DifficultyLevel == item.DifficultyLevel); //testPaperRuleId = testPaperRule?.Id; } item.TestPaperRuleTagDtos.ForEach(x => { x.TestPaperRuleId = testPaperRuleId; }); testPaperRuleTagDtos.AddRange(item.TestPaperRuleTagDtos); }); testPaperRuleTagDtos.ResolveOperationStatus(); var testPaperRuleTags = _mapper.Map>(testPaperRuleTagDtos); testPaperRuleTags.ToInsert(_sessionContext); await _testPaperRuleTagRepository.ValidateAddAsync(testPaperRuleTags, cancellationToken); return testPaperRuleTags; } private async Task> ModifyTestPaperRules(UpdateTestPaperDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TestPaperRuleDtos == null) return null; if (actionRequest.Mode == Share.Enums.Exams.EExamMode.Manual) return null; var all = await _testPaperRuleRepository.Queryable().Where(x => x.TestPaperId == actionRequest.Id).ToListAsync(); actionRequest.TestPaperRuleDtos.ResolveOperationStatus(all); var testPaperRules = new List(); testPaperRules.AddRangeExt(await AddTestPaperRules(actionRequest, cancellationToken)); testPaperRules.AddRangeExt(await UpdateTestPaperRules(actionRequest,all, cancellationToken)); var entityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(actionRequest.Id.IsNotNullOrEmpty(), x => x.TestPaperId == actionRequest.Id).ToEntityQueryRequest(); await DeleteTestPaperRules(entityQueryRequest, cancellationToken); return testPaperRules; } private async Task DeleteTestPaperRules(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _testPaperRuleRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task> UpdateTestPaperRules(UpdateTestPaperDto actionRequest,List all, CancellationToken cancellationToken) { if (actionRequest.TestPaperRuleDtos == null) return null; var testPaperRuleDtos = actionRequest.TestPaperRuleDtos.Where(x => x.OperationStatus == EEOperationStatus.Update).ToList(); var ids = testPaperRuleDtos.Select(x => x.Id); var testPaperRules = all.Where(x => ids.Contains(x.TestPaperId)).ToList(); var entities = new List(); foreach (var testPaperRuleDto in testPaperRuleDtos) { var entity = testPaperRules.FirstOrDefault(x => x.Id == testPaperRuleDto.Id); entity = _mapper.Map(testPaperRuleDto, entity); entity.TestPaperId = actionRequest.Id; } entities.ToUpdate(_sessionContext); await _testPaperRuleRepository.ValidateUpdateAsync(entities, cancellationToken); return entities; } private async Task> ModifyTestPaperRuleTags(UpdateTestPaperDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TestPaperRuleDtos == null) return null; var ruleIds = actionRequest.TestPaperRuleDtos.Select(x => x.Id); var all = await _testPaperRuleTagRepository.Queryable().Where(x => ruleIds.Contains(x.TestPaperRuleId)).ToListAsync(); actionRequest.TestPaperRuleDtos.ResolveOperationStatus(all); var testPaperRuleTags = new List(); testPaperRuleTags.AddRangeExt(await AddTestPaperRuleTags(actionRequest, cancellationToken)); testPaperRuleTags.AddRangeExt(await UpdateTestPaperRuleTags(actionRequest, all, cancellationToken)); var ids = actionRequest.TestPaperRuleDtos.Where(x => x.OperationStatus == EEOperationStatus.Delete).Select(x => x.Id).ToList(); var entityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(ids.IsNullOrEmpty(), x => ids.Contains(x.TestPaperRuleId)).ToEntityQueryRequest(); await DeleteTestPaperRuleTags(entityQueryRequest, cancellationToken); return testPaperRuleTags; } private async Task DeleteTestPaperRuleTags(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _testPaperRuleTagRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task> UpdateTestPaperRuleTags(UpdateTestPaperDto actionRequest,List all, CancellationToken cancellationToken) { if (actionRequest.TestPaperRuleDtos == null) return null; var ruleIds = actionRequest.TestPaperRuleDtos.Where(x => x.OperationStatus == EEOperationStatus.Update).Select(x => x.Id).ToList(); var testPaperRuleTags = all.Where(x => ruleIds.Contains(x.TestPaperRuleId)).ToList(); var entities = new List(); foreach (var testPaperRuleTagDto in actionRequest.TestPaperRuleDtos.SelectMany(x=>x.TestPaperRuleTagDtos)) { var entity = testPaperRuleTags.FirstOrDefault(x => x.Id == testPaperRuleTagDto.Id); entity = _mapper.Map(testPaperRuleTagDto,entity); } entities.ToUpdate(_sessionContext); await _testPaperRuleTagRepository.ValidateUpdateAsync(entities, cancellationToken); return entities; } private async Task> ModifyTestPaperItems(UpdateTestPaperDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TestPaperItemDtos == null) return null; var all = await _testPaperItemRepository.Queryable().Where(x => x.TestPaperId == actionRequest.Id).ToListAsync(); actionRequest.TestPaperItemDtos.ResolveOperationStatus(all); var testPaperItems = new List(); testPaperItems.AddRangeExt(await AddTestPaperItems(_addTestPaperDto, cancellationToken)); testPaperItems.AddRangeExt(await UpdateTestPaperItems(actionRequest,all, cancellationToken)); var entityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(actionRequest.Id.IsNotNullOrEmpty(), x => x.TestPaperId == actionRequest.Id).ToEntityQueryRequest(); await DeleteTestPaperItems(entityQueryRequest, cancellationToken); return testPaperItems; } private async Task DeleteTestPaperItems(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _testPaperItemRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task> UpdateTestPaperItems(UpdateTestPaperDto actionRequest,List all, CancellationToken cancellationToken) { if (actionRequest.TestPaperItemDtos == null) return null; var testPaperItemDtos = actionRequest.TestPaperItemDtos.Where(x => x.OperationStatus == EEOperationStatus.Update).ToList(); var ids = testPaperItemDtos.Select(x => x.Id); var testPaperItems = all.Where(x => ids.Contains(x.TestPaperId)).ToList(); var entities = new List(); foreach (var testPaperItemDto in testPaperItemDtos) { var entity = testPaperItems.FirstOrDefault(x => x.Id == testPaperItemDto.Id); entity = _mapper.Map(testPaperItemDto, entity); entity.TestPaperId = actionRequest.Id; } entities.ToUpdate(_sessionContext); await _testPaperItemRepository.ValidateUpdateAsync(entities, cancellationToken); return entities; } /// /// 获取试卷规则 /// /// /// /// private async Task> GetTestPaperRuleDtos(EntityQueryRequest entityQueryRequest) { var testPaperRuleTable = _testPaperRuleRepository.Queryable().Where(x => x.TestPaperId == entityQueryRequest.Id); var testPaperRuleTags = await GetTestPaperRuleTags(entityQueryRequest); var queryable = testPaperRuleTable.Select(t => new TestPaperRuleDto { Id = t.Id, TestPaperId = t.TestPaperId, Count = t.Count, DifficultyLevel = t.DifficultyLevel, SortIndex = t.SortIndex, QuestionType = t.QuestionType, }); var testPaperRuleTagDtos = _mapper.Map>(testPaperRuleTags); var testPaperRuleList = await queryable.ToListAsync(); testPaperRuleList.ForEach(x => x.TestPaperRuleTagDtos = testPaperRuleTagDtos.Where(n => n.TestPaperRuleId == x.Id).ToList()); return testPaperRuleList; } private async Task> GetTestPaperItemDtos(EntityQueryRequest entityQueryRequest) { var testPaperRuleTable = _testPaperItemRepository.Queryable().Where(x => x.TestPaperId == entityQueryRequest.Id); var queryable = testPaperRuleTable.Select(t => new TestPaperItemDto { Id = t.Id, QuestionId = t.QuestionId, DifficultyLevel = t.DifficultyLevel, Title = t.Title, TestPaperId = t.TestPaperId, QuestionType = t.QuestionType }); return await queryable.ToListAsync(); } private void ResolveTestPaperId(AddTestPaperDto actionRequest, string id) { actionRequest.TestPaperRuleDtos?.ForEach(x => { x.TestPaperId = id; }); actionRequest.TestPaperItemDtos?.ForEach(x => x.TestPaperId = id); } private void ResolveTestPaperId(UpdateTestPaperDto actionRequest, string id) { actionRequest.TestPaperRuleDtos?.ForEach(x => { x.TestPaperId = id; }); actionRequest.TestPaperItemDtos?.ForEach(x => x.TestPaperId = id); } private async Task> GetTestPaperRuleTags(EntityQueryRequest entityQueryRequest) { var expression = entityQueryRequest.GetTestPaperRuleExpression(); var testPageRuleTable = _testPaperRuleRepository.Queryable().Where(expression); var testPageRuleTagTable = _testPaperRuleTagRepository.Queryable(); var query = testPageRuleTagTable.InnerJoin(testPageRuleTable, (t, r) => t.TestPaperRuleId == r.Id).Select((t, r) => t); return await query.ToListAsync(); } private async Task> CalcuteRandomQuestionCount(TestPaperQuestionCountRequest testPaperQuestionCountRequest) { var testPaperQuestionCountViewResponses = new List(); var extractRuleRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var ruleTagRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var tagQuestionRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var expression = testPaperQuestionCountRequest.GetExpression(); var exatractTable = extractRuleRepository.Queryable().Where(expression); var ruleTagTable = ruleTagRepository.Queryable(); var tagQuestionTable = tagQuestionRepository.Queryable(); var testPaperRules = await exatractTable.InnerJoin(ruleTagTable,(e,rt)=>e.Id == rt.RuleId) .InnerJoin(tagQuestionTable,(e,rt,tq)=>rt.RuleId == tq.RuleId && rt.TagId == tq.TagId) .GroupBy((e, rt, tq)=> tq.QuestionType) .Select((e,rt,tq)=> new ExamTagQuestion { QuestionType = tq.QuestionType, Count = SqlFunc.AggregateSum(tq.Count) }) .ToListAsync(); if (testPaperRules != null) { testPaperRules.ForEach(x => testPaperQuestionCountViewResponses.Add(new TestPaperQuestionCountViewResponse { QuestionType = x.QuestionType, Count = x.Count })); } return testPaperQuestionCountViewResponses; } private async Task> CalcuteManualQuestionCount(TestPaperQuestionCountRequest testPaperQuestionCountRequest) { var testPaperQuestionCountViewResponses = new List(); var expression = testPaperQuestionCountRequest.GetTestPaperItemsExpression(); var testPaperItemTable = _testPaperItemRepository.Queryable().Where(expression); testPaperQuestionCountViewResponses = await testPaperItemTable.GroupBy(t=>t.QuestionType).Select(t => new TestPaperQuestionCountViewResponse { QuestionType = t.QuestionType, Count = SqlFunc.AggregateCount(t.Id) }).ToListAsync(); return testPaperQuestionCountViewResponses; } private async Task> AddTestPaperItemOptions(AddTestPaperDto actionRequest, CancellationToken cancellationToken) { var questionOptionRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var quesitonIds = actionRequest.TestPaperItemDtos.Select(x => x.QuestionId); var questionOptions = await questionOptionRepository.Queryable().Where(x => quesitonIds.Contains(x.QuestionId)).ToListAsync(); var testPaperItemOptions = new List(); actionRequest.TestPaperItemDtos.Where(x => x.QuestionType.CheckSelectType()).ToList().ForEach(x => { var testPaperItem = base.Entity?.TestPaperItems.FirstOrDefault(n => n.QuestionId == x.QuestionId) ?? null; var options = questionOptions.Where(n => x.QuestionId == n.QuestionId).ToList(); if (options != null) { options.ForEach(item => { var testPaperItemOption = _mapper.Map(item); testPaperItemOption.TestPaperItemId = testPaperItem?.Id; testPaperItemOption.QuestionOptionId = item.Id; testPaperItemOption.ToInsert(_sessionContext); testPaperItemOptions.Add(testPaperItemOption); }); } }); await _testPaperItemOptionsRepository.ValidateAddAsync(testPaperItemOptions, cancellationToken); return testPaperItemOptions; } private async Task> AddTestPaperItemAnswer(AddTestPaperDto actionRequest, CancellationToken cancellationToken) { var questionOptionRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var quesitonIds = actionRequest.TestPaperItemDtos?.Select(x => x.QuestionId); var questionAnswer = await questionOptionRepository.Queryable().Where(x => quesitonIds.Contains(x.QuestionId)).ToListAsync(); var testPaperItemAnswers = new List(); actionRequest.TestPaperItemDtos.Where(x => !x.QuestionType.CheckSelectType()).ToList().ForEach(x => { var testPaperItem = base.Entity?.TestPaperItems.FirstOrDefault(n => n.QuestionId == x.QuestionId) ?? null; var options = questionAnswer.Where(n => x.QuestionId == n.QuestionId).ToList(); options.ForEach(item => { var testPaperItemAnswer = _mapper.Map(item); testPaperItemAnswer.TestPaperItemId = testPaperItem?.Id; testPaperItemAnswer.QuestionAnswerId = item.Id; testPaperItemAnswer.ToInsert(_sessionContext); testPaperItemAnswers.Add(testPaperItemAnswer); }); }); await _testPaperItemAnswerRepository.ValidateAddAsync(testPaperItemAnswers, cancellationToken); return testPaperItemAnswers; } private async Task> AddTestPaperItemSourcewareAsync(AddTestPaperDto actionRequest, CancellationToken cancellationToken) { var questionSourcewareRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var quesitonIds = actionRequest.TestPaperItemDtos.Select(x => x.QuestionId); var questionSourceware = await questionSourcewareRepository.Queryable().Where(x => quesitonIds.Contains(x.QuestionId)).ToListAsync(); var testPaperItemSourcewares = new List(); actionRequest.TestPaperItemDtos.Where(x => x.QuestionType.CheckSelectType()).ToList().ForEach(x => { var testPaperItem = base.Entity?.TestPaperItems.FirstOrDefault(n => n.QuestionId == x.QuestionId) ?? null; var options = questionSourceware.Where(n => x.QuestionId == n.QuestionId).ToList(); if (options != null) { options.ForEach(item => { var testPaperItemSourceware = _mapper.Map(item); testPaperItemSourceware.TestPaperItemId = testPaperItem?.Id; testPaperItemSourceware.ToInsert(_sessionContext); testPaperItemSourcewares.Add(testPaperItemSourceware); }); } }); await _testPaperItemSourcewareRepository.ValidateAddAsync(testPaperItemSourcewares, cancellationToken); return testPaperItemSourcewares; } private async Task> AddTestPaperItemKnowladgeAsync(AddTestPaperDto actionRequest, CancellationToken cancellationToken) { var questionKnowladgeRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var quesitonIds = actionRequest.TestPaperItemDtos.Select(x => x.QuestionId); var questionKnowladge = await questionKnowladgeRepository.Queryable().Where(x => quesitonIds.Contains(x.QuestionId)).ToListAsync(); var testPaperItemKnowladges = new List(); actionRequest.TestPaperItemDtos.Where(x => x.QuestionType.CheckSelectType()).ToList().ForEach(x => { var testPaperItem = base.Entity?.TestPaperItems.FirstOrDefault(n => n.QuestionId == x.QuestionId) ?? null; var options = questionKnowladge.Where(n => x.QuestionId == n.QuestionId).ToList(); if (options != null) { options.ForEach(item => { var testPaperItemKnowladge = _mapper.Map(item); testPaperItemKnowladge.TestPaperItemId = testPaperItem?.Id; testPaperItemKnowladge.ToInsert(_sessionContext); testPaperItemKnowladges.Add(testPaperItemKnowladge); }); } }); await _testPaperItemKnowladgeRepository.ValidateAddAsync(testPaperItemKnowladges, cancellationToken); return testPaperItemKnowladges; } private async Task> ModifyTestPaperItemSourcewareAsync(UpdateTestPaperDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TestPaperItemDtos == null) return null; var questionIds = actionRequest.TestPaperItemDtos.Where(x => x.QuestionType.CheckSelectType()).Select(x => x.QuestionId).ToList(); var entityQueryRequest = new EntityQueryRequest { Expression = ExpressionableUtility.CreateExpression() .AndIF(questionIds.IsNotNullOrEmpty(), x => questionIds.Contains(x.QuestionId)).ToExpression() }; await DeleteTestPaperItemSourcewareAsync(entityQueryRequest, cancellationToken); return await AddTestPaperItemSourcewareAsync(_addTestPaperDto, cancellationToken); } private async Task DeleteTestPaperItemSourcewareAsync(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _testPaperItemSourcewareRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task> ModifyTestPaperItemKnowladgeAsync(UpdateTestPaperDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TestPaperItemDtos == null) return null; var questionIds = actionRequest.TestPaperItemDtos.Where(x => x.QuestionType.CheckSelectType()).Select(x => x.QuestionId).ToList(); var entityQueryRequest = new EntityQueryRequest { Expression = ExpressionableUtility.CreateExpression() .AndIF(questionIds.IsNotNullOrEmpty(), x => questionIds.Contains(x.QuestionId)).ToExpression() }; await DeleteTestPaperItemKnowladgeAsync(entityQueryRequest, cancellationToken); return await AddTestPaperItemKnowladgeAsync(_addTestPaperDto, cancellationToken); } private async Task DeleteTestPaperItemKnowladgeAsync(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _testPaperItemKnowladgeRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } #endregion #region protected method protected override async Task CompleteAdd(ExamTestPaper entity) { await base.AddNav(entity) //.Include(x => x.TestPaperRules) //.ThenInclude(x => x.TestPaperRuleTags) .Include(x => x.TestPaperItems) .ThenInclude(x => x.TestPaperItemAnswers) .Include(x => x.TestPaperItems, new InsertNavOptions { OneToManyIfExistsNoInsert = true }) .ThenInclude(x => x.TestPaperItemOptionses) .Include(x => x.TestPaperItems, new InsertNavOptions { OneToManyIfExistsNoInsert = true }) .ThenInclude(x => x.TestPaperItemKnowlagdes) .Include(x => x.TestPaperItems, new InsertNavOptions { OneToManyIfExistsNoInsert = true }) .ThenInclude(x => x.TestPaperItemSourcewares).ExecuteCommandAsync(); } protected override async Task CompleteUpdate(ExamTestPaper entity) { await base.UpdateNav(entity) //.Include(x => x.TestPaperRules) //.ThenInclude(x => x.TestPaperRuleTags) .Include(x => x.TestPaperItems) .ThenInclude(x => x.TestPaperItemAnswers) .Include(x => x.TestPaperItems, new UpdateNavOptions { OneToManyInsertOrUpdate = true }) .ThenInclude(x => x.TestPaperItemOptionses) .Include(x => x.TestPaperItems, new UpdateNavOptions { OneToManyInsertOrUpdate = true }) .ThenInclude(x => x.TestPaperItemKnowlagdes) .Include(x => x.TestPaperItems, new UpdateNavOptions { OneToManyInsertOrUpdate = true }) .ThenInclude(x => x.TestPaperItemSourcewares).ExecuteCommandAsync(); } #endregion } }