using Exam.Infrastructure.Data.Entity; using Exam.Infrastructure.Validation.Validation; using Exam.Insfrastructure.Service.Service; using Exam.Questions; using Exam.Repository.Sqlsugar.Repositories; using Exam.Repository.Sqlsugar.Repositories.Trains; using Exam.Share.Dtos.Trains; using Exam.Share.ViewResponses.Train; using Exam.Trains; using Hotline.Application.Exam.Core.Extensions; using Hotline.Application.Exam.QueryExtensions.Trains; using Hotline.Exams.Sourcewares; using Hotline.Exams.Trains; using Hotline.Repository.SqlSugar; using Hotline.Repository.SqlSugar.DataPermissions; using Hotline.Repository.SqlSugar.Exam.Interfaces.Trains; using Hotline.Repository.SqlSugar.Extensions; using Hotline.Share.Dtos.Questions; using Hotline.Share.Dtos.Trains; using Hotline.Share.Requests.Exam; using Hotline.Share.Requests.Train; using Hotline.Share.ViewResponses.Trains; using Hotline.Users; using MapsterMapper; using Train.Application.Interface.Train; using XF.Domain.Authentications; using XF.Domain.Dependency; using XF.Domain.Exceptions; using Hotline.Share.Exams.Extensions; using NPOI.SS.Formula.Functions; namespace Hotline.Application.Exam.Service.Trains { public class TrainRecordService : ApiService, ITrainRecordService, IScopeDependency { private readonly ITrainRecordRepository _repository; private readonly ITrainRecordAnswerRepository _trainRecordAnswerRepository; private readonly ITrainRecordItemRepository _trainRecordItemRepository; private readonly ITrainKnowladgeRepository _trainKnowladgeRepository; private readonly IMapper _mapper; private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder; private readonly IServiceProvider _serviceProvider; private readonly ISessionContext _sessionContext; public TrainRecordService(ITrainRecordRepository repository, ITrainRecordAnswerRepository trainRecordAnswerRepository, ITrainRecordItemRepository trainRecordItemRepository, ITrainKnowladgeRepository trainKnowladgeRepository, IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider, ISessionContext sessionContext, IMapper mapper) : base(repository, mapper, sessionContext) { this._repository = repository; this._trainRecordAnswerRepository = trainRecordAnswerRepository; this._trainRecordItemRepository = trainRecordItemRepository; this._trainKnowladgeRepository = trainKnowladgeRepository; this._mapper = mapper; this._dataPermissionFilterBuilder = dataPermissionFilterBuilder; this._serviceProvider = serviceProvider; this._sessionContext = sessionContext; } #region public method public async Task CompleteTrainRecordAsync(CompleteTrainRecordDto completeTrainRecordDto, CancellationToken cancellationToken) { var trainRecord = _mapper.Map(completeTrainRecordDto); trainRecord.ToUpdate(_sessionContext); await _repository.ValidateUpdateAsync(trainRecord, cancellationToken); } public async Task CompleteTrainKnowladgeAsync(CompleteTrainKnowladgeDto completeTrainPracticeDto, CancellationToken cancellationToken) { var trainKnowladge = _mapper.Map(completeTrainPracticeDto); trainKnowladge.ToUpdate(_sessionContext); await _trainKnowladgeRepository.ValidateUpdateAsync(trainKnowladge,cancellationToken); } public async Task GetAsync(EntityQueryRequest entityQueryRequest) { var trainRecord = await _repository.GetAsync(entityQueryRequest.Id); var trainRecordDto = _mapper.Map(trainRecord); trainRecordDto.KnowladgeDtos = await GetKnowladges(entityQueryRequest); trainRecordDto.QuestionDtos = await GetQuestions(entityQueryRequest); return trainRecordDto; } public async Task<(int, List)> GetListAsync(TrainRecordPagedRequest queryRequest) { SqlSugar.ISugarQueryable queryResult = QueryResult(queryRequest); var total = await queryResult.CountAsync(); var items = await queryResult.ToListAsync(); return (total, items); } public async Task> GetPagedListAsync(TrainRecordPagedRequest queryRequest) { SqlSugar.ISugarQueryable queryResult = QueryResult(queryRequest); var total = await queryResult.CountAsync(); var items = await queryResult.ToPageListAsync(queryRequest.PageIndex,queryRequest.PageSize); return new TrainRecordPageViewResponse { Items = items, Pagination = new Pagination(queryRequest.PageIndex,queryRequest.PageSize,total) }; } public async Task TrainAsync(AddTrainDto addTrainDto, CancellationToken cancellationToken) { await AddTrainRecordItem(addTrainDto,cancellationToken); await AddTrainRecordAnswer(addTrainDto, cancellationToken); //var trainPracticeOptionsDtos = await GetTrainQuestionOptions(addTrainDto); return null; } public async Task GetTrainPracticeAsync(TrainPracticeRequest trainPracticeRequest) { var trainPracticeRepostitory = new TrainPracticeRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainPractice = await trainPracticeRepostitory.GetAsync(trainPracticeRequest.TrainPracticeId); if (trainPractice == null) return null; var trainPracticeDto = _mapper.Map(trainPractice); trainPracticeDto.TrainPracticeOptionsDtos = await GetTrainQuestionOptions(trainPracticeRequest); trainPracticeDto.TrainPracticeSourcewareDtos = await GetTrainPracticeSourcewares(trainPracticeRequest); trainPracticeDto.TrainPracticeKnowladgeDtos = await GetTrainPracticeKnowladges(trainPracticeRequest); return trainPracticeDto; } public async Task AnalysisTrainResult(TrainResultReportPagedRequest trainResultReportPagedRequest) { trainResultReportPagedRequest.ResoleEndTime(); var expression = trainResultReportPagedRequest.GetExpression(); var templateExpression = trainResultReportPagedRequest.GetTemplateExpression(); var trainTemplateRepostitory = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainPlanRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainPlanTemplateRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var userRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainPlanTable = trainPlanRepository.Queryable().Where(expression); var trainTemplateTable = trainTemplateRepostitory.Queryable().Where(templateExpression); var trainPlanTemplateTable = trainPlanTemplateRepository.Queryable(); var trainRecordTable = _repository.Queryable(); var userTable = userRepository.Queryable(); var queryResult = trainRecordTable.InnerJoin(trainPlanTable, (r, p) => r.TrainPlanId == p.Id) .InnerJoin(trainPlanTemplateTable, (r, p, pt) => p.Id == pt.TrainPlanId) .InnerJoin(trainTemplateTable, (r, p, pt, t) => pt.TrainTemplateId == t.Id) .InnerJoin(userTable,(r,p,pt,t,u)=>r.UserId == u.Id) .Select((r, p, pt, t, u) => new TrainResultViewResponse { TrainName = t.Name, UserName = u.Name, IsComplete = r.IsComplete, SortIndex = r.SortIndex, Status = r.Status }); var total = await queryResult.CountAsync(); var items = await queryResult.ToPageListAsync(trainResultReportPagedRequest.PageIndex, trainResultReportPagedRequest.PageSize); return new TrainResultPagedViewResponse { Items = items, Pagination = new Pagination(trainResultReportPagedRequest.PageIndex, trainResultReportPagedRequest.PageSize, total) }; } public async Task CalcuteAnalysisRate(TrainResultReportPagedRequest trainResultReportPagedRequest) { trainResultReportPagedRequest.ResoleEndTime(); var expression = trainResultReportPagedRequest.GetExpression(); var templateExpression = trainResultReportPagedRequest.GetTemplateExpression(); var trainTemplateRepostitory = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainPlanRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainPlanTemplateRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainPlanTable = trainPlanRepository.Queryable().Where(expression); var trainTemplateTable = trainTemplateRepostitory.Queryable().Where(templateExpression); var trainPlanTemplateTable = trainPlanTemplateRepository.Queryable(); var trainRecordTable = _repository.Queryable(); var queryResult = trainRecordTable.InnerJoin(trainPlanTable, (r, p) => r.TrainPlanId == p.Id) .InnerJoin(trainPlanTemplateTable, (r, p, pt) => p.Id == pt.TrainPlanId) .InnerJoin(trainTemplateTable, (r, p, pt, t) => pt.TrainTemplateId == t.Id) .Select((r, p, pt, t) => new TrainResultViewResponse { TrainName = t.Name, IsComplete = r.IsComplete, SortIndex = r.SortIndex, Status = r.Status, TrainTime = p.TrainEndTime }); var calcuteRateResult = new TrainResultRateViewResponse { Complete = await queryResult.CountAsync(x=>x.IsComplete), Trainning = await queryResult.CountAsync(x => !x.IsComplete && x.TrainTime > DateTime.Now), UnComplete = await queryResult.CountAsync(x => !x.IsComplete && x.TrainTime <= DateTime.Now), }; return calcuteRateResult; } #endregion #region private method private async Task AddTrainRecordItem(AddTrainDto addTrainDto, CancellationToken cancellationToken) { var trainRecordItem = _mapper.Map(addTrainDto); trainRecordItem.ToInsert(_sessionContext); await _trainRecordItemRepository.ValidateAddAsync(trainRecordItem, cancellationToken); } private SqlSugar.ISugarQueryable QueryResult(TrainRecordPagedRequest queryRequest) { var trainPlanRepository = new TrainPlanRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var expression = queryRequest.GetExpression(); var trainPlanTable = trainPlanRepository.Queryable().Where(expression); var trainRecordTable = _repository.Queryable(); var queryResult = trainPlanTable.InnerJoin(trainRecordTable, (p, r) => p.Id == r.TrainPlanId) .Select((p, r) => new TrainRecordViewResponse { Id = r.Id, TrainCode = p.Code, TrainName = p.Name, IsComplete = r.IsComplete, Status = r.Status, SortIndex = r.SortIndex, TrainEndTime = p.TrainEndTime, TrainStartTime = p.TrainStartTime }); return queryResult; } private async Task> GetQuestions(EntityQueryRequest entityQueryRequest) { SqlSugar.ISugarQueryable queryable = QueryQuestions(entityQueryRequest); return await queryable.ToListAsync(); } private SqlSugar.ISugarQueryable QueryQuestions(EntityQueryRequest entityQueryRequest) { var trainPlanRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainPracticeRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainPlanTemplateRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainRecordTable = _repository.Queryable().Where(x => x.Id == entityQueryRequest.Id); var trainPlanTable = trainPlanRepository.Queryable(); var trainPracticeTable = trainPracticeRepository.Queryable(); var trainPlanTemplateTable = trainPlanTemplateRepository.Queryable(); var queryable = trainRecordTable.InnerJoin(trainPlanTable, (r, p) => r.TrainPlanId == p.Id) .InnerJoin(trainPlanTemplateTable, (r, p, tpt) => p.Id == tpt.TrainPlanId) .InnerJoin(trainPracticeTable, (r, p, tpt, tp) => tpt.Id == tp.TrainTemplateId) .Select((r, p, tpt, tp) => new SimpleQuestionDto { Title = tp.Title, Id = tp.Id }); return queryable; } private async Task> GetKnowladges(EntityQueryRequest entityQueryRequest) { var questionTable = QueryQuestions(entityQueryRequest); var questionSourcewareRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var sourcewareRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var questionSourcewareTable = questionSourcewareRepository.Queryable(); var sourcewareTable = sourcewareRepository.Queryable(); var queryable = questionTable.InnerJoin(questionSourcewareTable, (r, p) => r.Id == p.QuestionId) .InnerJoin(sourcewareTable, (r, p, sw) => p.SourcewareId == sw.Id) .Select((r, p, sw) => new SimpleKnowladgeDto { Title = sw.Title, Id = sw.Id }); return await queryable.ToListAsync(); } private async Task AddTrainRecordAnswer(AddTrainDto addTrainRecordDto, CancellationToken cancellationToken) { if (addTrainRecordDto.AddTrainRecordOptionDtos == null && addTrainRecordDto.AddTrainRecordAnswerDto == null) return; var trainRecordAnswers = new List(); addTrainRecordDto.AddTrainRecordOptionDtos?.ForEach(item => { trainRecordAnswers.Add(_mapper.Map(item)); }); if (addTrainRecordDto.AddTrainRecordAnswerDto != null) { trainRecordAnswers.Add(_mapper.Map(addTrainRecordDto.AddTrainRecordAnswerDto)); } trainRecordAnswers.ToInsert(_sessionContext); await _trainRecordAnswerRepository.ValidateAddAsync(trainRecordAnswers,cancellationToken); } private async Task GetTrainQuestionOptions(AddTrainDto addTrainDto) { var trainPracticeOptionsRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainPracticeRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); // TODO: 获取未答题的第一道题 var trainPractice = await trainPracticeRepository.Queryable() .Where(x => x.TrainTemplateId == addTrainDto.TrainTemplateId && x.Id!= addTrainDto.TrainPracticeId).OrderBy(x=>x.SortIndex).FirstAsync(); var trainPracticeOptions = await trainPracticeOptionsRepository.Queryable().Where(x => x.TrainPracticeId == trainPractice.Id).ToListAsync(); var trainPracticeOptionsDtos = new List(); trainPracticeOptions.ForEach(x => { trainPracticeOptionsDtos.Add(_mapper.Map(x)); }); var trainPracticeDto = _mapper.Map(trainPractice); trainPracticeDto.TrainPracticeOptionsDtos = trainPracticeOptionsDtos; return trainPracticeDto; } private async Task> GetTrainQuestionOptions(TrainPracticeRequest trainPracticeRequest) { var trainPracticeRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainRecordAnswerRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); // TODO: 获取未阅卷的第一道题 var trainPracticeOptions = trainPracticeRepository.Queryable().Where(x => x.TrainPracticeId == trainPracticeRequest.TrainPracticeId); var trainRecordOptions = await trainRecordAnswerRepository.Queryable() .InnerJoin((t,x)=>t.TrainRecordId == x.Id) .InnerJoin((t,x,p)=> x.TrainPlanId == p.TrainPlanId) .InnerJoin((t,x,p,tp)=> x.Id == tp.TrainTemplateId) .Where((t, x, p, tp) => tp.Id == trainPracticeRequest.TrainPracticeId) .Select((t, x, p, tp) => t) .ToListAsync(); var trainPracticeOptionsDtos = new List(); trainPracticeOptions.ForEach(x => { var trainPracticeOptionsDto = _mapper.Map(x); trainPracticeOptionsDto.IsSelected = trainRecordOptions.Any(m => m.QuestionOptionId == x.QuestionOptionId); trainPracticeOptionsDtos.Add(trainPracticeOptionsDto); }); return trainPracticeOptionsDtos; } private async Task> GetTrainPracticeKnowladges(TrainPracticeRequest trainPracticeRequest) { var trainPracticeKnowladgeRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var knowledgeRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainPracticeRepostitory = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var expression = trainPracticeRequest.GetExpression(); var trainPracticeTable = trainPracticeRepostitory.Queryable().Where(expression); var trainPracticeKnowladgeTable = trainPracticeKnowladgeRepository.Queryable(); var knowledgeTable = knowledgeRepository.Queryable(); var queryResult = trainPracticeTable.InnerJoin(trainPracticeKnowladgeTable, (t, tk) => t.QuestionId == tk.QuestionId) .InnerJoin(knowledgeTable, (t, tk, k) => tk.KnowladgeId == k.Id) .Select((t, tk, k) => new TrainPracticeKnowladgeDto { KnowladgeId = tk.KnowladgeId, QuestionId = tk.QuestionId, Title = k.Title }); return await queryResult.ToListAsync(); } private async Task> GetTrainPracticeSourcewares(TrainPracticeRequest trainPracticeRequest) { var trainPracticeSourcewareRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var sourcewareRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var trainPracticeRepostitory = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var expression = trainPracticeRequest.GetExpression(); var trainPracticeTable = trainPracticeRepostitory.Queryable().Where(expression); var trainPracticeSourcewareTable = trainPracticeSourcewareRepository.Queryable(); var sourcewareTable = sourcewareRepository.Queryable(); var queryResult = trainPracticeTable.InnerJoin(trainPracticeSourcewareTable, (t, ts) => t.QuestionId == ts.QuestionId) .InnerJoin(sourcewareTable, (t, ts, sw) => ts.SourcewareId == sw.Id) .Select((t, ts, sw) => new TrainPracticeSourcewareDto { SourcewareId = ts.SourcewareId, QuestionId = ts.QuestionId, Name = sw.Name, }); return await queryResult.ToListAsync(); } #endregion } }