using Abp.Application.Services; using Abp.Application.Services.Dto; using Abp.Auditing; using Abp.Authorization; using Abp.Domain.Entities; using Abp.Domain.Repositories; using Abp.Extensions; using Abp.Linq; using Abp.Linq.Extensions; using Abp.Runtime.Caching; using Abp.UI; using Microsoft.AspNetCore.Identity; using System.Data.Common; using System.Linq.Dynamic.Core; using System.Linq.Expressions; using VberZero.AppService.Base.Dto; using VberZero.DomainService.AppGuids; using VberZero.DomainService.Attaches; using VberZero.DomainService.AutoCompletes; using VberZero.DomainService.States; using VberZero.IdentityFramework; using VberZero.Session; using VberZero.Tools; using VberZero.Tools.Lambda; namespace VberZero.AppService.Base; public abstract class VzCrudAppServiceBase : ApplicationService, IVzCrudAppService where TEntity : class, IEntity where TEntityDto : IVzEntityDto where TUpdateInput : IVzEntityDto where TGetInput : IVzEntityDto where TDeleteInput : IVzEntityDto { protected readonly IRepository Repository; protected VzCrudAppServiceBase(IRepository repository, string keyFiledName = null) { KeyFiledName = keyFiledName; AsyncQueryableExecuter = NullAsyncQueryableExecuter.Instance; LocalizationSourceName = VzConsts.LocalizationSourceName; Repository = repository; AttachManager = NullAttachManager.Instance; StatesManager = NullSysStatesManager.Instance; AppGuidManager = NullAppGuidManager.Instance; QueryAcManager = NullAutoCompleteQueryManager.Instance; AbpSession = NullVzSession.Instance; } #region 字段、属性 public new IVzSession AbpSession { get; set; } public IAttachManager AttachManager { get; set; } public ISysStatesManager StatesManager { get; set; } public IAppGuidManager AppGuidManager { get; set; } public IAutoCompleteQueryManager QueryAcManager { get; set; } public ICacheManager CacheManager { get; set; } public IAsyncQueryableExecuter AsyncQueryableExecuter { get; set; } /// /// 自定义唯一字段名称(主键) /// protected string KeyFiledName { get; set; } /// /// 是否自动生成自定义字段(GUID) /// protected virtual bool KeyIsAuto { get; set; } = true; /// /// 自定义唯一字段存在提示信息 /// protected virtual string KeyExistMessage { get; set; } protected virtual string ExistMessage => string.IsNullOrEmpty(KeyExistMessage) ? L("KeyExistMessage") : KeyExistMessage; /// /// 自定义唯一字段不存在提示信息 /// protected virtual string KeyNotExistMessage { get; set; } protected virtual string NotExistMessage => string.IsNullOrEmpty(KeyNotExistMessage) ? L("KeyNotExistMessage") : KeyNotExistMessage; protected virtual string GetPermissionName { get; set; } protected virtual string GetAllPermissionName { get; set; } protected virtual string CreatePermissionName { get; set; } protected virtual string UpdatePermissionName { get; set; } protected virtual string DeletePermissionName { get; set; } #endregion 字段、属性 #region CURD #region Query #region GetEntity/Dto /// /// 查询实体Dto /// /// /// [DisableAuditing] public virtual async Task GetDto(TGetInput input) { var entity = await GetEntity(input); return MapToEntityDto(entity); } /// /// 查询实体Dto /// /// /// [DisableAuditing] public virtual async Task GetDtoById(TPrimaryKey id) { var entity = await GetEntityById(id); return MapToEntityDto(entity); } /// /// 查询实体Dto(需指明自定义字段) /// /// /// [DisableAuditing] public virtual async Task GetDtoByNo(string no) { var entity = await GetEntityByNo(no); return MapToEntityDto(entity); } /// /// 查询实体 /// /// /// [DisableAuditing] public virtual async Task GetEntity(TGetInput input) { var entity = await GetEntityById(input.Id); return entity; } /// /// 查询实体 /// /// /// [DisableAuditing] public virtual async Task GetEntityById(TPrimaryKey id) { var exp = LambdaHelper.CreatePrimaryKeyExp(id); if (exp == null) { CheckErrors(string.Format(L("NoEntity"), id)); } return await Repository.FirstOrDefaultAsync(exp); } /// /// 查询实体(需指明自定义字段) /// /// /// [DisableAuditing] public virtual async Task GetEntityByNo(string no) { //CheckGetPermission(); if (string.IsNullOrEmpty(KeyFiledName)) { ThrowError("NoKeyFieldName"); } //LambdaObject obj = new LambdaObject() //{ // FieldType = LambdaFieldType.S, // FieldName = KeyFiledName, // FieldValue = no, // ExpType = LambdaExpType.Equal //}; //var exp = obj.GetExp(); var exp = LambdaHelper.CreateFieldExp(KeyFiledName, no); return exp == null ? null : await Repository.FirstOrDefaultAsync(exp); } #endregion GetEntity/Dto /// /// 分页查询 /// /// /// [DisableAuditing] public virtual async Task> GetAll(TGetAllInput input) { CheckGetAllPermission(); var query = CreateFilteredQuery(input); var totalCount = await AsyncQueryableExecuter.CountAsync(query); query = ApplySorting(query, input); query = ApplyPaging(query, input); var entities = await AsyncQueryableExecuter.ToListAsync(query); return new PagedResultDto(totalCount, entities.Select(MapToEntityDto).ToList()); } /// /// 排序 /// /// The query. /// The input. protected virtual IQueryable ApplySorting(IQueryable query, TGetAllInput input) { return _ApplySorting(query, input); } /// /// 排序 /// /// The query. /// The input. protected IQueryable _ApplySorting(IQueryable query, TGetAllInput input) { //Try to sort query if available if (input is ISortedResultRequest sortInput) { return sortInput.Sorting.IsNullOrWhiteSpace() ? SelfSorting(query, input) : query.OrderBy(sortInput.Sorting); } if (input is ILimitedResultRequest) { return query.OrderBy("Id DESC"); } //No sorting return query; } /// /// 默认自定义排序 /// /// /// /// /// protected virtual IQueryable SelfSorting(IQueryable query, TGetAllInput input) { return query is IQueryable queryable ? (IQueryable)queryable.OrderByDescending(a => a.Id) : query; } /// /// 分页 /// /// The query. /// The input. protected virtual IQueryable ApplyPaging(IQueryable query, TGetAllInput input) { return _ApplyPaging(query, input); } /// /// 分页 /// /// The query. /// The input. protected IQueryable _ApplyPaging(IQueryable query, TGetAllInput input) { //Try to use paging if available if (input is IPagedResultRequest pagedInput) { return query.PageBy(pagedInput); } //Try to limit query result if available if (input is ILimitedResultRequest limitedInput) { return query.Take(limitedInput.MaxResultCount); } //No paging return query; } /// /// 根据给定的 创建 过滤查询. /// /// /// Including protected virtual IQueryable CreateFilteredQuery(TGetAllInput input, params Expression>[] propertySelectors) { var query = propertySelectors?.Length > 0 ? Repository.GetAllIncluding(propertySelectors) : Repository.GetAll(); query = ApplyFilter(query, input); return query; } /// /// 过滤查询条件 /// /// /// /// /// protected virtual IQueryable ApplyFilter(IQueryable query, TGetAllInput input) { var pagedInput = input as IVzPagedRequestDto; if (pagedInput == null) { return query; } if (!string.IsNullOrEmpty(pagedInput.KeyWords)) { query = pagedInput.KeyField.IsNullOrEmpty() ? KeyWordFilter(query, pagedInput.KeyWords) : KeyWordFilter(query, pagedInput); } query = SearchListFilter(query, pagedInput); return query; } /// /// 过滤查询条件 /// /// /// /// /// 附带条件 /// protected virtual IQueryable ApplyFilter(IQueryable query, TGetAllInput input, params Expression>[] whereExpressions) { if (whereExpressions != null) { foreach (var exp in whereExpressions) { query = query.Where(exp); } } query = ApplyFilter(query, input); return query; } /// /// 关键字查询 /// /// /// /// /// protected virtual IQueryable KeyWordFilter(IQueryable query, string pagedInput) { return query; } /// /// 关键字查询 /// /// /// /// /// protected virtual IQueryable KeyWordFilter(IQueryable query, IVzPagedRequestDto pagedInput) { if (!string.IsNullOrEmpty(pagedInput.KeyWords) && !string.IsNullOrEmpty(pagedInput.KeyField) && pagedInput.KeyField.ToLower() != "keyword") { object keyWords = pagedInput.KeyWords; LambdaObject obj = new LambdaObject() { FieldType = (LambdaFieldType)pagedInput.FieldType, FieldName = pagedInput.KeyField, FieldValue = keyWords, ExpType = (LambdaExpType)pagedInput.ExpType }; var exp = obj.GetExp(); query = exp != null ? query.Where(exp) : query; } return query; } /// /// 多个条件查询 /// /// /// /// /// protected IQueryable SearchListFilter(IQueryable query, IVzPagedRequestDto pagedInput) { if (pagedInput.SearchList is { Count: > 0 }) { query = SelfFilter(query, pagedInput.SearchList); var objList = new List(); foreach (var o in pagedInput.SearchList) { if (o.HasUse || string.IsNullOrEmpty(o.KeyWords)) continue; object keyWords = o.KeyWords; objList.Add(new LambdaObject { FieldType = (LambdaFieldType)o.FieldType, FieldName = o.KeyField, FieldValue = keyWords, ExpType = (LambdaExpType)o.ExpType }); } var exp = objList.GetExp(); query = exp != null ? query.Where(exp) : query; } return query; } /// /// 特殊条件时,自定义查询 (使用完该字段查询条件时,应该从list里清除) /// /// /// /// protected virtual IQueryable SelfFilter(IQueryable query, List list) { return query; } #endregion Query /// /// 添加 /// /// /// public virtual async Task Create(TCreateInput input) { CheckCreatePermission(); await CreateEntity(input); } /// /// 添加 /// /// /// /// protected async Task CreateEntity(TCreateInput input, bool isCheck = true) { if (!KeyFiledName.IsNullOrEmpty()) { var fieldValue = input.GetFiledValue(KeyFiledName); if (KeyIsAuto && fieldValue.IsNullOrEmpty()) { input.SetFiledValue(KeyFiledName, Guid.NewGuid().ToString("N")); } else { if (isCheck) { var exp = LambdaHelper.CreateFieldExp(KeyFiledName, fieldValue); if (exp != null && await Repository.FirstOrDefaultAsync(exp) != null) { CheckErrors(ExistMessage); } } } } var entity = MapToEntity(input); await Repository.InsertAsync(entity); await CurrentUnitOfWork.SaveChangesAsync(); return MapToEntityDto(entity); } /// /// 修改 /// /// /// public virtual async Task Update(TUpdateInput input) { CheckUpdatePermission(); await UpdateEntity(input); } /// /// 修改 /// /// /// /// protected async Task UpdateEntity(TUpdateInput input, TEntity entity = null) { entity = entity ?? await GetEntityById(input.Id); if (entity == null) { CheckErrors(NotExistMessage); } MapToEntity(input, entity); await CurrentUnitOfWork.SaveChangesAsync(); return MapToEntityDto(entity); } /// /// 删除 /// /// /// public virtual Task Delete(TDeleteInput input) { CheckDeletePermission(); return DeleteEntity(input); } /// /// 删除 /// /// /// /// protected async Task DeleteEntity(TDeleteInput input, bool isCheckNull = true) { if (isCheckNull && !string.IsNullOrEmpty(KeyFiledName)) { LambdaObject obj = new LambdaObject() { FieldType = LambdaFieldType.S, FieldName = KeyFiledName, FieldValue = input.GetFiledValue(KeyFiledName), ExpType = LambdaExpType.Equal }; var exp = obj.GetExp(); if (exp != null && await Repository.FirstOrDefaultAsync(exp) == null) { CheckErrors(NotExistMessage); } } try { await Repository.DeleteAsync(input.Id); await CurrentUnitOfWork.SaveChangesAsync(); } catch (DbException) { ThrowError("CanNotCascadeDeleteMessage"); } catch (Exception e) { CheckErrors(e.Message); } } #endregion CURD #region MAP protected virtual TEntityDto MapToEntityDto(TEntity entity) { return ObjectMapper.Map(entity); } protected virtual TEntity MapToEntity(TCreateInput createInput) { return ObjectMapper.Map(createInput); } protected virtual void MapToEntity(TUpdateInput updateInput, TEntity entity) { ObjectMapper.Map(updateInput, entity); } protected virtual TOut VzMap(object obj) { return ObjectMapper.Map(obj); } protected virtual TOut VzMap(TIn obj) { return ObjectMapper.Map(obj); } #endregion MAP #region CHECK protected virtual int CheckGuid(int? guid) { if (guid == null || guid == 0) { ThrowError("GetGuidNoError"); return 0; } return (int)guid; } protected virtual void CheckErrors(string error) { throw new UserFriendlyException(error); } protected virtual void CheckErrors(IdentityResult identityResult) { identityResult.CheckErrors(LocalizationManager); } /// /// 抛出错误 /// /// /// 是否要本地化 protected virtual void ThrowError(string err, bool isLocalization = true) { CheckErrors(isLocalization ? L(err) : err); } protected virtual void CheckPermission(string permissionName) { if (!string.IsNullOrEmpty(permissionName)) { PermissionChecker.Authorize(permissionName); } } protected virtual void CheckGetPermission() { CheckPermission(GetPermissionName); } protected virtual void CheckGetAllPermission() { CheckPermission(GetAllPermissionName); } protected virtual void CheckCreatePermission() { CheckPermission(CreatePermissionName); } protected virtual void CheckUpdatePermission() { CheckPermission(UpdatePermissionName); } protected virtual void CheckDeletePermission() { CheckPermission(DeletePermissionName); } #endregion CHECK } #region AppServiceBase public abstract class VzCrudAppServiceBase : VzCrudAppServiceBase where TEntity : class, IEntity where TEntityDto : IVzEntityDto { protected VzCrudAppServiceBase(IRepository repository, string keyFiledName = null) : base(repository) { KeyFiledName = keyFiledName; } } public abstract class VzCrudAppServiceBase : VzCrudAppServiceBase where TEntity : class, IEntity where TEntityDto : IVzEntityDto { protected VzCrudAppServiceBase(IRepository repository, string keyFiledName = null) : base(repository) { KeyFiledName = keyFiledName; } } public abstract class VzCrudAppServiceBase : VzCrudAppServiceBase where TEntity : class, IEntity where TEntityDto : IVzEntityDto { protected VzCrudAppServiceBase(IRepository repository, string keyFiledName = null) : base(repository) { KeyFiledName = keyFiledName; } } public abstract class VzCrudAppServiceBase : VzCrudAppServiceBase where TGetAllInput : IPagedAndSortedResultRequest where TEntity : class, IEntity where TEntityDto : IVzEntityDto where TCreateInput : IVzEntityDto { protected VzCrudAppServiceBase(IRepository repository, string keyFiledName = null) : base(repository) { KeyFiledName = keyFiledName; } } public abstract class VzCrudAppServiceBase : VzCrudAppServiceBase> where TEntity : class, IEntity where TEntityDto : IVzEntityDto where TUpdateInput : IVzEntityDto { protected VzCrudAppServiceBase(IRepository repository, string keyFiledName = null) : base(repository) { KeyFiledName = keyFiledName; } } public abstract class VzCrudAppServiceBase : VzCrudAppServiceBase> where TEntity : class, IEntity where TEntityDto : IVzEntityDto where TUpdateInput : IVzEntityDto where TGetInput : IVzEntityDto { protected VzCrudAppServiceBase(IRepository repository, string keyFiledName = null) : base(repository) { KeyFiledName = keyFiledName; } } #endregion AppServiceBase