using DocumentFormat.OpenXml.Office2010.Excel; using Exam.Infrastructure.Data.Entity; using Exam.Infrastructure.Enums; using Exam.Infrastructure.Extensions; using Exam.Insfrastructure.Service.Service; using Exam.Repository.Sqlsugar.Repositories; using Exam.Share.ViewResponses.Train; using Hotline.Application.Exam.Core.Constants; using Hotline.Application.Exam.Core.Extensions; using Hotline.Application.Exam.Core.Utilities; using Hotline.Application.Exam.Extensions; using Hotline.Application.Exam.Interface.Train; using Hotline.Application.Exam.QueryExtensions.Trains; using Hotline.Exams.Questions; using Hotline.Exams.TestPapers; using Hotline.Exams.Trains; 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.Trains; using Hotline.Repository.SqlSugar.Extensions; using Hotline.Repository.SqlSugar.Interface; using Hotline.Share.Dtos.Questions; using Hotline.Share.Dtos.Trains; using Hotline.Share.Requests.Train; using JiebaNet.Segmenter.Common; using MapsterMapper; using SqlSugar; using XF.Domain.Authentications; using XF.Domain.Dependency; namespace Hotline.Application.Exam.Service.Trains { public class TrainTemplateService : ApiService, ITrainTemplateService, IScopeDependency { private readonly ITrainTemplateRepository _repository; private readonly ITrainKnowladgeRepository _trainKnowladgeRepository; private readonly ITrainPracticeRepository _trainPracticeRepository; private readonly ITrainPracticeOptionsRepository _trainPracticeOptionsRepository; private readonly ITrainPracticeSourcewareRepository _trainPracticeSourcewareRepository; private readonly ITrainPracticeKnowladgeRepository _trainPracticeKnowladgeRepository; private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder; private readonly IServiceProvider _serviceProvider; private readonly ISessionContext _sessionContext; private readonly IMapper _mapper; private AddTrainTemplateDto _addTrainTemplateDto; public TrainTemplateService(ITrainTemplateRepository repository, ITrainKnowladgeRepository trainKnowladgeRepository, ITrainPracticeRepository trainPracticeRepository, ITrainPracticeOptionsRepository trainPracticeOptionsRepository, ITrainPracticeSourcewareRepository trainPracticeSourcewareRepository, ITrainPracticeKnowladgeRepository trainPracticeKnowladgeRepository, IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider, ISessionContext sessionContext, IMapper mapper) : base(repository, mapper) { _repository = repository; this._trainKnowladgeRepository = trainKnowladgeRepository; this._trainPracticeRepository = trainPracticeRepository; this._trainPracticeOptionsRepository = trainPracticeOptionsRepository; this._trainPracticeSourcewareRepository = trainPracticeSourcewareRepository; this._trainPracticeKnowladgeRepository = trainPracticeKnowladgeRepository; this._dataPermissionFilterBuilder = dataPermissionFilterBuilder; this._serviceProvider = serviceProvider; this._sessionContext = sessionContext; this._mapper = mapper; } #region public method public async Task GetAsync(EntityQueryRequest entityQueryRequest) { var trainTemplate = await _repository.GetAsync(entityQueryRequest.Id); var trainTemplateDto = _mapper.Map(trainTemplate); trainTemplateDto.TrainKnowladges = await GetKnowladges(entityQueryRequest); trainTemplateDto.TrainPracticeDtos = await GetTrainPractices(entityQueryRequest); return trainTemplateDto; } public async Task<(int, List)> GetListAsync(TrainTemplatePagedRequest queryRequest) { SqlSugar.ISugarQueryable queryResult = QueryRequest(queryRequest); var total = await queryResult.CountAsync(); var items = await queryResult.ToListAsync(); return (total, items); } public async Task> GetPagedListAsync(TrainTemplatePagedRequest queryRequest) { SqlSugar.ISugarQueryable queryResult = QueryRequest(queryRequest); var total = await queryResult.CountAsync(); var items = await queryResult.ToPageListAsync(queryRequest.PageIndex, queryRequest.PageSize); return new TrainTemplatePageViewResponse { Items = items, Pagination = new Pagination(queryRequest.PageIndex, queryRequest.PageSize, total) }; } public override async Task AddAsync(AddTrainTemplateDto actionRequest, CancellationToken cancellationToken) { base.StartTran(); actionRequest.Code = await GenerateCode(ExamBusiConstants.TrainTemplateCode,3); var id = await base.AddAsync(actionRequest, cancellationToken); ResolveTemplateId(actionRequest, id); base.Entity.TrainKnowladges = await AddTrainKnowladgesAsync(actionRequest, cancellationToken); base.Entity.TrainPractices = await AddTrainPracticesAsync(actionRequest, cancellationToken); var trainPracticeOptions = await AddTrainPracticeOptionsAsync(actionRequest, cancellationToken); var trainPracticeKnowladges = await AddTrainPracticeKnowladgeAsync(actionRequest, cancellationToken); base.Entity.TrainPractices.ForEach(item => { item.TrainPracticeKnowladges = trainPracticeKnowladges.Where(x => item.Id == x.TrainPracticeId).ToList(); }); var trainPracticeSourcewares = await AddTrainPracticeSourcewareAsync(actionRequest, cancellationToken); base.Entity.TrainPractices.ForEach(item => { item.TrainPracticeKnowladges = trainPracticeKnowladges.Where(x => item.Id == x.TrainPracticeId).ToList(); item.TrainPracticeOptionses = trainPracticeOptions.Where(x => item.Id == x.TrainPracticeId).ToList(); item.TrainPracticeSourcewares = trainPracticeSourcewares.Where(x => item.Id == x.TrainPracticeId).ToList(); }); await base.Complete(base.Entity, OperationConstant.Create); return id; } public override async Task UpdateAsync(UpdateTrainTemplateDto actionRequest, CancellationToken cancellationToken) { base.StartTran(); await base.UpdateAsync(actionRequest, cancellationToken); _addTrainTemplateDto = _mapper.Map(actionRequest); base.Entity.TrainKnowladges = await ModifyTrainKnowladgeAsync(actionRequest, cancellationToken); base.Entity.TrainPractices = await ModifyTrainPracticesAsync(actionRequest, cancellationToken); var trainPracticeOptions = await ModifyTrainPracticeOptionsAsync(actionRequest, cancellationToken); var trainPracticeKnowladges = await ModifyTrainPracticeKnowladgeAsync(actionRequest, cancellationToken); var trainPracticeSourcewares = await ModifyTrainPracticeSourcewareAsync(actionRequest, cancellationToken); base.Entity.TrainPractices.ForEach(item => { item.TrainPracticeOptionses = trainPracticeOptions.Where(x => item.Id == x.TrainPracticeId).ToList(); item.TrainPracticeKnowladges = trainPracticeKnowladges.Where(x => item.Id == x.TrainPracticeId).ToList(); item.TrainPracticeSourcewares = trainPracticeSourcewares.Where(x => item.Id == x.TrainPracticeId).ToList(); }); await base.Complete(base.Entity, OperationConstant.Update); } public override async Task DeleteAsync(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await base.DeleteAsync(entityQueryRequest, cancellationToken); var tmpEntityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.TrainTemplateId == entityQueryRequest.Id) .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.TrainTemplateId)) .ToEntityQueryRequest(); await DeleteTrainKnowladgesAsync(tmpEntityQueryRequest, cancellationToken); tmpEntityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.TrainTemplateId == entityQueryRequest.Id) .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.TrainTemplateId)) .ToEntityQueryRequest(); await DeleteTrainPracticeAsync(tmpEntityQueryRequest, cancellationToken); } #endregion #region private method private async Task> GetKnowladges(EntityQueryRequest entityQueryRequest) { var trainKnowladgeTable = _trainKnowladgeRepository.Queryable().Where(x => x.TrainTemplateId == entityQueryRequest.Id); var knowledgeTable = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable(); var queseryResult = trainKnowladgeTable.InnerJoin(knowledgeTable, (t, k) => t.KnowladgeId == k.Id).Select((t, k) => new TrainKnowladgeDto { Id = t.Id, KnowladgeId = t.KnowladgeId, Title = k.Title }); return await queseryResult.ToListAsync(); } private async Task> ModifyTrainPracticeOptionsAsync(UpdateTrainTemplateDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TrainPracticeDtos == null) return null; var questionIds = actionRequest.TrainPracticeDtos.Where(x => x.QuestionType.CheckSelectType()).Select(x => x.QuestionId).ToList(); if (questionIds.IsNotNullOrEmpty()) { var entityQueryRequest = new EntityQueryRequest { Expression = ExpressionableUtility.CreateExpression() .AndIF(questionIds.IsNotNullOrEmpty(), x => questionIds.Contains(x.QuestionId)).ToExpression() }; await DeleteTrainPracticeOptionsAsync(entityQueryRequest, cancellationToken); } return await AddTrainPracticeOptionsAsync(_addTrainTemplateDto, cancellationToken); } private async Task DeleteTrainPracticeOptionsAsync(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _trainPracticeOptionsRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task> AddTrainPracticeSourcewareAsync(AddTrainTemplateDto actionRequest, CancellationToken cancellationToken) { var questionSourcewareRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var quesitonIds = actionRequest.TrainPracticeDtos.Select(x => x.QuestionId); var questionSourceware = await questionSourcewareRepository.Queryable().Where(x => quesitonIds.Contains(x.QuestionId)).ToListAsync(); var trainPracticeSourcewares = new List(); actionRequest.TrainPracticeDtos.Where(x => x.QuestionType.CheckSelectType()).ToList().ForEach(x => { var options = questionSourceware.Where(n => x.QuestionId == n.QuestionId).ToList(); if (options != null) { options.ForEach(item => { var trainPracticeSourceware = _mapper.Map(item); trainPracticeSourceware.ToInsert(_sessionContext); trainPracticeSourcewares.Add(trainPracticeSourceware); }); } }); await _trainPracticeSourcewareRepository.ValidateAddAsync(trainPracticeSourcewares, cancellationToken); return trainPracticeSourcewares; } private async Task> AddTrainPracticeKnowladgeAsync(AddTrainTemplateDto actionRequest, CancellationToken cancellationToken) { var questionKnowladgeRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var quesitonIds = actionRequest.TrainPracticeDtos.Select(x => x.QuestionId); var questionKnowladge = await questionKnowladgeRepository.Queryable().Where(x => quesitonIds.Contains(x.QuestionId)).ToListAsync(); var trainPracticeKnowladges = new List(); actionRequest.TrainPracticeDtos.Where(x => x.QuestionType.CheckSelectType()).ToList().ForEach(x => { var trainPractice = base.Entity?.TrainPractices.FirstOrDefault(n => n.QuestionId == x.QuestionId) ?? null; var options = questionKnowladge.Where(n => x.QuestionId == n.QuestionId).ToList(); if (options != null) { options.ForEach(item => { var trainPracticeKnowladge = _mapper.Map(item); trainPracticeKnowladge.TrainPracticeId = trainPractice?.Id; trainPracticeKnowladge.ToInsert(_sessionContext); trainPracticeKnowladges.Add(trainPracticeKnowladge); }); } }); await _trainPracticeKnowladgeRepository.ValidateAddAsync(trainPracticeKnowladges, cancellationToken); return trainPracticeKnowladges; } private async Task> ModifyTrainPracticeSourcewareAsync(UpdateTrainTemplateDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TrainPracticeDtos == null) return null; var questionIds = actionRequest.TrainPracticeDtos.Where(x => x.QuestionType.CheckSelectType()).Select(x => x.QuestionId).ToList(); if (questionIds.IsNotNullOrEmpty()) { var entityQueryRequest = new EntityQueryRequest { Expression = ExpressionableUtility.CreateExpression() .AndIF(questionIds.IsNotNullOrEmpty(), x => questionIds.Contains(x.QuestionId)).ToExpression() }; await DeleteTrainPracticeSourcewareAsync(entityQueryRequest, cancellationToken); } return await AddTrainPracticeSourcewareAsync(_addTrainTemplateDto, cancellationToken); } private async Task DeleteTrainPracticeSourcewareAsync(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _trainPracticeSourcewareRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task> ModifyTrainPracticeKnowladgeAsync(UpdateTrainTemplateDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TrainPracticeDtos == null) return null; var questionIds = actionRequest.TrainPracticeDtos.Where(x => x.QuestionType.CheckSelectType()).Select(x => x.QuestionId).ToList(); if (questionIds.IsNotNullOrEmpty()) { var entityQueryRequest = new EntityQueryRequest { Expression = ExpressionableUtility.CreateExpression() .AndIF(questionIds.IsNotNullOrEmpty(), x => questionIds.Contains(x.QuestionId)).ToExpression() }; await DeleteTrainPracticeKnowladgeAsync(entityQueryRequest, cancellationToken); } return await AddTrainPracticeKnowladgeAsync(_addTrainTemplateDto, cancellationToken); } private async Task DeleteTrainPracticeKnowladgeAsync(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _trainPracticeKnowladgeRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task> AddTrainPracticeOptionsAsync(AddTrainTemplateDto actionRequest, CancellationToken cancellationToken) { var questionOptionRepository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var quesitonIds = actionRequest.TrainPracticeDtos.Select(x => x.QuestionId); var questionOptions = await questionOptionRepository.Queryable().Where(x => quesitonIds.Contains(x.QuestionId)).ToListAsync(); var trainPracticeOptions = new List(); actionRequest.TrainPracticeDtos.Where(x => x.QuestionType.CheckSelectType()).ToList().ForEach(x => { var trainPractice = base.Entity?.TrainPractices.FirstOrDefault(n => n.QuestionId == x.QuestionId) ?? null; var options = questionOptions.Where(n => x.QuestionId == n.QuestionId).ToList(); if (options != null) { options.ForEach(item => { var trainPracticeOption = _mapper.Map(item); trainPracticeOption.TrainPracticeId = trainPractice?.Id; trainPracticeOption.QuestionOptionId = item.Id; trainPracticeOption.ToInsert(_sessionContext); trainPracticeOptions.Add(trainPracticeOption); }); } }); await _trainPracticeOptionsRepository.ValidateAddAsync(trainPracticeOptions, cancellationToken); return trainPracticeOptions; } private void ResolveTemplateId(AddTrainTemplateDto actionRequest, string id) { if (actionRequest.TrainKnowladges != null) { actionRequest.TrainKnowladges.ForEach(x => x.TrainTemplateId = id); } if (actionRequest.TrainPracticeDtos != null) { actionRequest.TrainPracticeDtos.ForEach(x => x.TrainTemplateId = id); } } private async Task> GetTrainPractices(EntityQueryRequest entityQueryRequest) { var questionTable = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable(); var trainPracticeTable = _trainPracticeRepository.Queryable().Where(x => x.TrainTemplateId == entityQueryRequest.Id); var trainPractices = trainPracticeTable.InnerJoin(questionTable, (t, q) => t.QuestionId == q.Id).Select((t, q) => new TrainPracticeDto { Id = t.Id, QuestionId = t.QuestionId, QuestionType = q.QuestionType, DifficultyLevel = q.DifficultyLevel, Title = q.Title }); return await trainPractices.ToListAsync(); } private SqlSugar.ISugarQueryable QueryRequest(TrainTemplatePagedRequest queryRequest) { var expression = queryRequest.GetExpression(); var queryable = _repository.Queryable().Where(expression); var queryResult = queryable.Select(m => new TrainTemplateViewResponse { Id = m.Id, Code = m.Code, Name = m.Name, IsContainsPractice = m.IsContainsPractice, SortIndex = m.SortIndex, Status = m.Status, CreationTime = m.CreationTime, CreatorName = m.CreatorName, CreatorOrgName = m.CreatorOrgName }); return queryResult; } private async Task> AddTrainPracticesAsync(AddTrainTemplateDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TrainPracticeDtos != null) { actionRequest.TrainPracticeDtos.ResolveOperationStatus(); var trainPracticeDtos = actionRequest.TrainPracticeDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList(); var trainPractices = _mapper.Map>(trainPracticeDtos); //TODO:排序 var sortIndex = 0; trainPractices.ForEach(x => { x.SortIndex = sortIndex + 1; }); trainPractices.ToInsert(_sessionContext); await _trainPracticeRepository.ValidateAddAsync(trainPractices, cancellationToken); return trainPractices; } return null; } private async Task> AddTrainKnowladgesAsync(AddTrainTemplateDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TrainKnowladges != null) { actionRequest.TrainKnowladges.ResolveOperationStatus(); var trainKnowladgeDtos = actionRequest.TrainKnowladges.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList(); var trainKnowladges = _mapper.Map>(trainKnowladgeDtos); trainKnowladges.ToInsert(_sessionContext); await _trainKnowladgeRepository.ValidateAddAsync(trainKnowladges, cancellationToken); return trainKnowladges; } return null; } private async Task> ModifyTrainPracticesAsync(UpdateTrainTemplateDto actionRequest, CancellationToken cancellationToken) { var trainPractices = new List(); trainPractices.AddRangeExt(await AddTrainPracticesAsync(_addTrainTemplateDto, cancellationToken)); trainPractices.AddRangeExt(await UpdateTrainPracticesAsync(actionRequest, cancellationToken)); if (actionRequest.TrainPracticeDtos != null) { var ids = actionRequest.TrainPracticeDtos.Where(x => x.OperationStatus == EEOperationStatus.Delete).Select(x => x.Id).ToList(); if (ids.IsNotNullOrEmpty()) { var entityQueryRequest = new EntityQueryRequest { Expression = ExpressionableUtility.CreateExpression() .AndIF(ids.IsNotEmpty(), x => ids.Contains(x.Id)) .ToExpression() }; await DeleteTrainPracticeAsync(entityQueryRequest, cancellationToken); } } return trainPractices; } private async Task DeleteTrainPracticeAsync(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _trainPracticeRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task> UpdateTrainPracticesAsync(UpdateTrainTemplateDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TrainPracticeDtos == null) return null; actionRequest.TrainPracticeDtos.ResolveOperationStatus(); var trainPracticeDtos = actionRequest.TrainPracticeDtos.Where(x => x.OperationStatus == EEOperationStatus.Update).ToList(); var ids = trainPracticeDtos.Select(x => x.Id); var trainPractices = await _trainPracticeRepository.Queryable().Where(x => ids.Contains(x.Id)).ToListAsync(); trainPractices = _mapper.Map, List>(trainPracticeDtos, trainPractices); trainPractices.ToUpdate(_sessionContext); await _trainPracticeRepository.ValidateUpdateAsync(trainPractices, cancellationToken); return trainPractices; } private async Task> ModifyTrainKnowladgeAsync(UpdateTrainTemplateDto actionRequest, CancellationToken cancellationToken) { var trainKnowladges = new List(); trainKnowladges.AddRangeExt(await AddTrainKnowladgesAsync(_addTrainTemplateDto, cancellationToken)); trainKnowladges.AddRangeExt(await UpdateTrainKnowladgesAsync(actionRequest, cancellationToken)); if (actionRequest.TrainKnowladges != null) { var ids = actionRequest.TrainKnowladges.Where(x => x.OperationStatus == EEOperationStatus.Delete).Select(x => x.Id).ToList(); if (ids.IsNotNullOrEmpty()) { var entityQueryRequest = new EntityQueryRequest { Expression = ExpressionableUtility.CreateExpression() .AndIF(ids.IsNotEmpty(), x => ids.Contains(x.Id)) .ToExpression() }; await DeleteTrainKnowladgesAsync(entityQueryRequest, cancellationToken); } } return trainKnowladges; } private async Task DeleteTrainKnowladgesAsync(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _trainKnowladgeRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task> UpdateTrainKnowladgesAsync(UpdateTrainTemplateDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.TrainKnowladges == null) return null; actionRequest.TrainKnowladges.ResolveOperationStatus(); var trainKnowladgeDtos = actionRequest.TrainKnowladges.Where(x => x.OperationStatus == EEOperationStatus.Update).ToList(); var ids = trainKnowladgeDtos.Select(x => x.Id); var trainKnowladges = await _trainKnowladgeRepository.Queryable().Where(x => ids.Contains(x.Id)).ToListAsync(); trainKnowladges = _mapper.Map, List>(trainKnowladgeDtos, trainKnowladges); trainKnowladges.ToUpdate(_sessionContext); await _trainKnowladgeRepository.ValidateUpdateAsync(trainKnowladges, cancellationToken); return trainKnowladges; } private async Task GenerateCode(string codePrefix, int length) { var trainTemplate = await _repository.Queryable().Where(x => x.CreationTime.Date == DateTime.Now.Date).OrderByDescending(x=>x.CreationTime).FirstAsync(); var code = string.Empty; if (trainTemplate != null) { code = trainTemplate.Code; } code = CodeUtility.GenerateCode(codePrefix,length,code); return code; } #endregion #region protected method protected override async Task CompleteAdd(ExamTrainTemplate entity) { await base.AddNav(entity) .Include(x => x.TrainKnowladges) .Include(x => x.TrainPractices) .ThenInclude(x => x.TrainPracticeKnowladges) .Include(x => x.TrainPractices, new InsertNavOptions { OneToManyIfExistsNoInsert = true }) .ThenInclude(x => x.TrainPracticeOptionses) .Include(x => x.TrainPractices, new InsertNavOptions { OneToManyIfExistsNoInsert = true }) .ThenInclude(x => x.TrainPracticeSourcewares).ExecuteCommandAsync(); } protected override async Task CompleteUpdate(ExamTrainTemplate entity) { await base.UpdateNav(entity) .Include(x => x.TrainKnowladges) .Include(x => x.TrainPractices) .ThenInclude(x => x.TrainPracticeKnowladges) .Include(x => x.TrainPractices, new UpdateNavOptions { OneToManyInsertOrUpdate = true }) .ThenInclude(x => x.TrainPracticeOptionses) .Include(x => x.TrainPractices, new UpdateNavOptions { OneToManyInsertOrUpdate = true }) .ThenInclude(x => x.TrainPracticeSourcewares).ExecuteCommandAsync(); } #endregion } }