diff --git a/IRaCIS.Core.Application/Service/Management/UserService.cs b/IRaCIS.Core.Application/Service/Management/UserService.cs index 18f2b49b6..8d7eb6c87 100644 --- a/IRaCIS.Core.Application/Service/Management/UserService.cs +++ b/IRaCIS.Core.Application/Service/Management/UserService.cs @@ -247,7 +247,7 @@ namespace IRaCIS.Application.Services } } - var list = await _userRepository.Where(t => t.EMail == email).Select(t => new UserAccountDto() { UserId = t.Id, UserName = t.UserName, UserRealName = t.LastName + " / " + t.FirstName,UserType = t.UserTypeRole.UserTypeShortName}).ToListAsync(); + var list = await _userRepository.Where(t => t.EMail == email).Select(t => new UserAccountDto() { UserId = t.Id, UserName = t.UserName, UserRealName = t.LastName + " / " + t.FirstName, UserType = t.UserTypeRole.UserTypeShortName }).ToListAsync(); @@ -291,40 +291,45 @@ namespace IRaCIS.Application.Services /// /// [HttpPost] + [UnitOfWork] public async Task ModifyPassword(EditPasswordCommand editPwModel) { - if (!string.IsNullOrEmpty(editPwModel.NewUserName)) - { - if (await _userRepository.AnyAsync(t => t.UserName == editPwModel.NewUserName && t.Id != _userInfo.Id)) - { - return ResponseOutput.NotOk("UserId already exists"); - } - var success = await _userRepository.UpdateFromQueryAsync(t => t.Id == _userInfo.Id, u => new User() - { - UserName = editPwModel.NewUserName, - }); - - } //验证旧密码OK var dbUser = await _userRepository.FirstOrDefaultAsync(t => t.Id == _userInfo.Id && t.Password == editPwModel.OldPassWord); if (dbUser != null) { - if (dbUser.Password == editPwModel.OldPassWord) + if (dbUser.Password == editPwModel.NewPassWord) { return ResponseOutput.NotOk("password not change"); } + if (!string.IsNullOrEmpty(editPwModel.NewUserName)) + { + if (await _userRepository.AnyAsync(t => t.UserName == editPwModel.NewUserName && t.Id != _userInfo.Id)) + { + return ResponseOutput.NotOk("UserId already exists"); + } + + await _userRepository.UpdateFromQueryAsync(t => t.Id == _userInfo.Id, u => new User() + { + UserName = editPwModel.NewUserName, + }); + + } + var success = await _userRepository.UpdateFromQueryAsync(t => t.Id == _userInfo.Id, u => new User() { Password = editPwModel.NewPassWord, IsFirstAdd = false }); + + return ResponseOutput.Result(success); } diff --git a/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs b/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs index 74ae723a1..1c99bbfe6 100644 --- a/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs +++ b/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs @@ -11,16 +11,17 @@ namespace IRaCIS.Core.Infra.EFCore { public interface ICommandRepository: ICommandRepository where TEntity : Entity { - //Task InsertDictionaryAsync(TFrom from, params EntityVerifyExp[] verify); Task InsertOrUpdateAsync(TFrom from, bool autoSave = false, params EntityVerifyExp[] verify); - Task InsertFromDTOAsync(TFrom from, bool autoSave = false, params EntityVerifyExp[] verify); - Task UpdateFromDTOAsync(TFrom from, bool autoSave = false, bool ignoreDtoNullProperty = true, params EntityVerifyExp[] verify); + TEntity UpdatePartialFields(TEntity entity, string[] propertyNames, bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify); + + //TEntity UpdatePartialFields(Guid id, Expression> updateFactory, bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify); + } public interface ICommandRepository where TEntity : class diff --git a/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs b/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs index 162b7c4d0..6366550ad 100644 --- a/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs +++ b/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs @@ -30,10 +30,6 @@ namespace IRaCIS.Core.Infra.EFCore public Repository(IRaCISDBContext dbContext, IMapper mapper) { - //if (typeof(TEntity) = typeof(DataInspection)) - //{ - - //} _dbContext = dbContext; _mapper = mapper; } @@ -101,22 +97,52 @@ namespace IRaCIS.Core.Infra.EFCore } else { - return await UpdateFromDTOAsync(from, autoSave,false, verify); + return await UpdateFromDTOAsync(from, autoSave, false, verify); } } + + private async Task EntityVerifyAsync(bool isAdd, EntityVerifyExp[] verify, Guid? entitydId = null) + { + + if (isAdd) + { + foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyUpdate && t.IsVerify)) + { + if (await _dbSet.IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) + { + throw new BusinessValidationFailedException(verifyItem.VerifyMsg); + } + } + } + else + { + foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyAdd && t.IsVerify)) + { + if (verifyItem.verifyType == VerifyEnum.OnlyUpdate) + { + if (await _dbSet.IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) + { + throw new BusinessValidationFailedException(verifyItem.VerifyMsg); + } + } + else if (verifyItem.verifyType == VerifyEnum.Both) + { + if (await _dbSet.IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp.And(t => t.Id != entitydId)).ConfigureAwait(false)) + { + throw new BusinessValidationFailedException(verifyItem.VerifyMsg); + } + } + } + } + } + public async Task InsertFromDTOAsync(TFrom from, bool autoSave = false, params EntityVerifyExp[] verify) { var entity = _mapper.Map(from); - foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyUpdate && t.IsVerify)) - { - if (await _dbSet.IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) - { - throw new BusinessValidationFailedException(verifyItem.VerifyMsg); - } - } + await EntityVerifyAsync(true, verify); await _dbSet.AddAsync(entity).ConfigureAwait(false); @@ -135,23 +161,7 @@ namespace IRaCIS.Core.Infra.EFCore var entity = _mapper.Map(from); - foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyAdd && t.IsVerify)) - { - if (verifyItem.verifyType == VerifyEnum.OnlyUpdate) - { - if (await _dbSet.IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) - { - throw new BusinessValidationFailedException(verifyItem.VerifyMsg); - } - } - else if (verifyItem.verifyType == VerifyEnum.Both) - { - if (await _dbSet.IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp.And(t => t.Id != entity.Id)).ConfigureAwait(false)) - { - throw new BusinessValidationFailedException(verifyItem.VerifyMsg); - } - } - } + await EntityVerifyAsync(false, verify, entity.Id); var dbEntity = await _dbSet.IgnoreQueryFilters().FirstOrDefaultAsync(t => t.Id == entity.Id).ConfigureAwait(false); @@ -190,6 +200,108 @@ namespace IRaCIS.Core.Infra.EFCore } + //public TEntity UpdatePartialFields(Guid id, Expression> updateFactory, bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify) + //{ + // EntityVerifyAsync(false, verify, id).RunSynchronously(); + + // var entity = updateFactory.Compile().Invoke(new TEntity() { Id = id }); + + // var entityEntry = _dbContext.Entry(entity); + // entityEntry.State = EntityState.Detached; + + //} + + /// + /// 部分字段更新 (只更新传递的字段名) + /// + /// + /// 更新的字段数组 + /// + /// + /// + /// + public TEntity UpdatePartialFields(TEntity entity, string[] propertyNames, + bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify) + { + EntityVerifyAsync(false, verify, entity.Id).RunSynchronously(); + + var entityEntry = _dbContext.Entry(entity); + entityEntry.State = EntityState.Detached; + + + foreach (var propertyName in propertyNames) + { + _dbContext.Entry(entity).Property(propertyName).IsModified = true; + } + + // 忽略空值 + IgnoreNullValues(ref entity, ignoreEntityNullProperty); + + return entityEntry.Entity; + } + + /// + /// 更新 排除某些字段的更新 + /// + /// + /// + /// + /// + /// + /// + public TEntity UpdateExcludeFields(TEntity entity, string[] propertyNames, bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify) + { + + EntityVerifyAsync(false, verify, entity.Id).RunSynchronously(); + + var entityEntry = _dbContext.Entry(entity); + entityEntry.State = EntityState.Modified; + + + foreach (var propertyName in propertyNames) + { + _dbContext.Entry(entity).Property(propertyName).IsModified = false; + } + + // 忽略空值 + IgnoreNullValues(ref entity, ignoreEntityNullProperty); + + return entityEntry.Entity; + } + + /// + /// 忽略空值属性 + /// + /// + /// + private void IgnoreNullValues(ref TEntity entity, bool? ignoreNullValues = null) + { + var isIgnore = ignoreNullValues; + if (isIgnore == false) return; + + // 获取所有的属性 + var properties = _dbSet.EntityType.GetProperties(); + if (properties == null) return; + + foreach (var propety in properties) + { + var entityProperty = _dbContext.Entry(entity).Property(propety.Name); + var propertyValue = entityProperty?.CurrentValue; + var propertyType = entityProperty?.Metadata?.PropertyInfo?.PropertyType; + + // 判断是否是无效的值,比如为 null,默认时间,以及空 Guid 值 + var isInvalid = propertyValue == null + || (propertyType == typeof(DateTime) && propertyValue?.ToString() == new DateTime().ToString()) + || (propertyType == typeof(DateTimeOffset) && propertyValue?.ToString() == new DateTimeOffset().ToString()) + || (propertyType == typeof(Guid) && propertyValue?.ToString() == Guid.Empty.ToString()); + + if (isInvalid && entityProperty != null) + { + entityProperty.IsModified = false; + } + } + } + public async Task SaveChangesAsync(CancellationToken cancellationToken = default) { @@ -271,6 +383,8 @@ namespace IRaCIS.Core.Infra.EFCore } } + + public async Task UpdateManyAsync(IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default) { _dbSet.UpdateRange(entities); @@ -285,6 +399,9 @@ namespace IRaCIS.Core.Infra.EFCore } } + + + public async Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) { _dbSet.Remove(entity);