diff --git a/README.md b/README.md index 3912ff6f..2537318f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

Yi框架

+

Yi框架

一套以用户体验出发的.Net8 Web开源框架

支持Abp.vNext 版本原生版本、Furion版本,前端后台接入Ruoyi Vue3.0

集大成者,终究轮子

diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/Microsoft/Extensions/DependencyInjection/SwaggerAddExtensions.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/Microsoft/Extensions/DependencyInjection/SwaggerAddExtensions.cs index 8afd6878..dc7c5b99 100644 --- a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/Microsoft/Extensions/DependencyInjection/SwaggerAddExtensions.cs +++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/Microsoft/Extensions/DependencyInjection/SwaggerAddExtensions.cs @@ -1,7 +1,11 @@ -using System.Diagnostics; +using System.ComponentModel; +using System.Diagnostics; +using System.Text; +using System.Xml.Linq; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using Volo.Abp.AspNetCore.Mvc; @@ -75,12 +79,59 @@ namespace Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection { [scheme] = new string[0] }); + + + options.SchemaFilter(); } ); - + return services; } } + + + /// + /// Swagger文档枚举字段显示枚举属性和枚举值,以及枚举描述 + /// + public class EnumSchemaFilter : ISchemaFilter + { + /// + /// 实现接口 + /// + /// + /// + + public void Apply(OpenApiSchema model, SchemaFilterContext context) + { + if (context.Type.IsEnum) + { + model.Enum.Clear(); + model.Type = "string"; + model.Format = null; + + + StringBuilder stringBuilder = new StringBuilder(); + Enum.GetNames(context.Type) + .ToList() + .ForEach(name => + { + Enum e = (Enum)Enum.Parse(context.Type, name); + var descrptionOrNull = GetEnumDescription(e); + model.Enum.Add(new OpenApiString(name)); + stringBuilder.Append($"【枚举:{name}{(descrptionOrNull is null ? string.Empty : $"({descrptionOrNull})")}={Convert.ToInt64(Enum.Parse(context.Type, name))}】
"); + }); + model.Description= stringBuilder.ToString(); + } + } + + private static string? GetEnumDescription(Enum value) + { + var fieldInfo = value.GetType().GetField(value.ToString()); + var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); + return attributes.Length > 0 ? attributes[0].Description : null; + } + + } } diff --git a/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application/Yi.Framework.Ddd.Application.csproj b/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application/Yi.Framework.Ddd.Application.csproj index 4ea79313..3915da9e 100644 --- a/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application/Yi.Framework.Ddd.Application.csproj +++ b/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application/Yi.Framework.Ddd.Application.csproj @@ -2,6 +2,9 @@ + + + diff --git a/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application/YiCrudAppService.cs b/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application/YiCrudAppService.cs index 946d7984..4a7f56dc 100644 --- a/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application/YiCrudAppService.cs +++ b/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application/YiCrudAppService.cs @@ -3,11 +3,14 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using MiniExcelLibs; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; +using Volo.Abp.Validation; namespace Yi.Framework.Ddd.Application { @@ -86,7 +89,7 @@ namespace Yi.Framework.Ddd.Application /// /// [RemoteService(isEnabled: true)] - public async Task DeleteAsync(IEnumerable id) + public virtual async Task DeleteAsync(IEnumerable id) { await Repository.DeleteManyAsync(id); } @@ -95,5 +98,34 @@ namespace Yi.Framework.Ddd.Application { return base.DeleteAsync(id); } + + + + + public virtual async Task GetExportExcelAsync(TGetListInput input) + { + if (input is IPagedResultRequest paged) + { + paged.SkipCount = 0; + paged.MaxResultCount = LimitedResultRequestDto.MaxMaxResultCount; + } + + var output = await this.GetListAsync(input); + var dirPath = $"/wwwroot/temp"; + var filePath = $"{dirPath}/{Guid.NewGuid()}.xlsx"; + if (!Directory.Exists(dirPath)) + { + Directory.CreateDirectory(dirPath); + } + + MiniExcel.SaveAs(filePath, output.Items); + return new FileStreamResult(File.OpenRead(filePath), "application/vnd.ms-excel"); + } + + public virtual async Task PostImportExcelAsync() + { + + + } } } diff --git a/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application/YiFrameworkDddApplicationModule.cs b/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application/YiFrameworkDddApplicationModule.cs index 46b83722..e2781601 100644 --- a/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application/YiFrameworkDddApplicationModule.cs +++ b/Yi.Abp.Net8/framework/Yi.Framework.Ddd.Application/YiFrameworkDddApplicationModule.cs @@ -1,4 +1,6 @@ -using Volo.Abp.Application; +using Volo.Abp; +using Volo.Abp.Application; +using Volo.Abp.Application.Dtos; using Volo.Abp.Modularity; using Yi.Framework.Ddd.Application.Contracts; @@ -8,6 +10,11 @@ namespace Yi.Framework.Ddd.Application typeof(YiFrameworkDddApplicationContractsModule))] public class YiFrameworkDddApplicationModule : AbpModule { - + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + //分页限制 + LimitedResultRequestDto.DefaultMaxResultCount = 10; + LimitedResultRequestDto.MaxMaxResultCount = 10000; + } } } diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Repositories/SqlSugarObjectRepository.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Repositories/SqlSugarObjectRepository.cs new file mode 100644 index 00000000..2bc8ed41 --- /dev/null +++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Repositories/SqlSugarObjectRepository.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; +using SqlSugar; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Linq; +using Yi.Framework.SqlSugarCore.Abstractions; + +namespace Yi.Framework.SqlSugarCore.Repositories +{ + public class SqlSugarObjectRepository : IRepository where TEntity : class, IEntity + { + public ISqlSugarClient _Db => GetDbContextAsync().Result; + private ISugarDbContextProvider _sugarDbContextProvider; + /// + /// 获取DB + /// + /// + public virtual async Task GetDbContextAsync() + { + + var db = (await _sugarDbContextProvider.GetDbContextAsync()).SqlSugarClient; + //await Console.Out.WriteLineAsync("获取的id:" + db.ContextID); + return db; + } + + public IAsyncQueryableExecuter AsyncExecuter => throw new NotImplementedException(); + + public bool? IsChangeTrackingEnabled => throw new NotImplementedException(); + + public Task DeleteAsync(Expression> predicate, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task DeleteDirectAsync(Expression> predicate, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task DeleteManyAsync(IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task FindAsync(Expression> predicate, bool includeDetails = true, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task GetAsync(Expression> predicate, bool includeDetails = true, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task GetCountAsync(CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task> GetListAsync(Expression> predicate, bool includeDetails = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task> GetPagedListAsync(int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task> GetQueryableAsync() + { + throw new NotImplementedException(); + } + + public async Task InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) + { + await (await GetDbContextAsync()).InsertableByObject(entity).ExecuteCommandAsync(); + return entity; + } + + public Task InsertManyAsync(IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task UpdateManyAsync(IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public IQueryable WithDetails() + { + throw new NotImplementedException(); + } + + public IQueryable WithDetails(params Expression>[] propertySelectors) + { + throw new NotImplementedException(); + } + + public Task> WithDetailsAsync() + { + throw new NotImplementedException(); + } + + public Task> WithDetailsAsync(params Expression>[] propertySelectors) + { + throw new NotImplementedException(); + } + } + + public class SqlSugarObjectRepository : SqlSugarObjectRepository, IRepository where TEntity : class, IEntity + { + public Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task DeleteManyAsync(IEnumerable ids, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + } +} diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Uow/SqlSugarTransactionApi.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Uow/SqlSugarTransactionApi.cs index f7e5eb17..0a9a0c43 100644 --- a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Uow/SqlSugarTransactionApi.cs +++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Uow/SqlSugarTransactionApi.cs @@ -10,7 +10,12 @@ namespace Yi.Framework.SqlSugarCore.Uow public SqlSugarTransactionApi(ISqlSugarDbContext sqlsugarDbContext) { _sqlsugarDbContext = sqlsugarDbContext; + } + public ISqlSugarDbContext GetDbContext() + { + + return _sqlsugarDbContext; } public async Task CommitAsync(CancellationToken cancellationToken = default) diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Uow/UnitOfWorkSqlsugarDbContextProvider.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Uow/UnitOfWorkSqlsugarDbContextProvider.cs index 4910c1a0..3cd8c58c 100644 --- a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Uow/UnitOfWorkSqlsugarDbContextProvider.cs +++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/Uow/UnitOfWorkSqlsugarDbContextProvider.cs @@ -82,17 +82,17 @@ namespace Yi.Framework.SqlSugarCore.Uow protected virtual async Task CreateDbContextAsync(IUnitOfWork unitOfWork) { - return unitOfWork.Options.IsTransactional - ? await CreateDbContextWithTransactionAsync(unitOfWork) - : unitOfWork.ServiceProvider.GetRequiredService(); + return unitOfWork.ServiceProvider.GetRequiredService(); + //return unitOfWork.Options.IsTransactional + // ? await CreateDbContextWithTransactionAsync(unitOfWork) + // : unitOfWork.ServiceProvider.GetRequiredService(); } protected virtual async Task CreateDbContextWithTransactionAsync(IUnitOfWork unitOfWork) { - var transactionApiKey = $"Sqlsugar_Default".ToString(); - - var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as SqlSugarDatabaseApi; - if (activeTransaction == null) - { + var transactionApiKey = $"Sqlsugar_Default"+Guid.NewGuid().ToString(); + var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as SqlSugarTransactionApi; + //if (activeTransaction==null|| activeTransaction.Equals(default(SqlSugarTransactionApi))) + //{ var dbContext = unitOfWork.ServiceProvider.GetRequiredService(); var transaction = new SqlSugarTransactionApi( @@ -105,14 +105,15 @@ namespace Yi.Framework.SqlSugarCore.Uow // Console.WriteLine(dbContext.SqlSugarClient.ContextID); await dbContext.SqlSugarClient.Ado.BeginTranAsync(); return dbContext; - } - else - { - // await Console.Out.WriteLineAsync("继续老的事务"); - // Console.WriteLine(activeTransaction.DbContext.SqlSugarClient); - await activeTransaction.DbContext.SqlSugarClient.Ado.BeginTranAsync(); - return (TDbContext)activeTransaction.DbContext; - } + //} + //else + //{ + // var db= activeTransaction.GetDbContext().SqlSugarClient; + // // await Console.Out.WriteLineAsync("继续老的事务"); + // // Console.WriteLine(activeTransaction.DbContext.SqlSugarClient); + // await activeTransaction.GetDbContext().SqlSugarClient.Ado.BeginTranAsync(); + // return (TDbContext)activeTransaction.GetDbContext(); + //} } diff --git a/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/Entities/AuditLogEntity.cs b/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/Entities/AuditLogEntity.cs new file mode 100644 index 00000000..3d8e8c8c --- /dev/null +++ b/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/Entities/AuditLogEntity.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.AuditLogging; + +namespace Yi.AuditLogging.SqlSugarCore.Entities +{ + public class AuditLogEntity : AuditLog + { + public AuditLogEntity() { } + } +} diff --git a/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/SqlSugarCoreAuditLogRepository.cs b/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/SqlSugarCoreAuditLogRepository.cs index c15151f7..1d8122d0 100644 --- a/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/SqlSugarCoreAuditLogRepository.cs +++ b/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/SqlSugarCoreAuditLogRepository.cs @@ -1,266 +1,348 @@ -//using System.Linq.Dynamic.Core; -//using System.Net; -//using Volo.Abp.Auditing; -//using Volo.Abp.Domain.Entities; -//using Yi.Framework.SqlSugarCore.Abstractions; -//using Yi.Framework.SqlSugarCore.Repositories; +using System.Linq.Dynamic.Core; +using System.Linq.Expressions; +using System.Net; +using Mapster; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Repositories; +using Yi.AuditLogging.SqlSugarCore.Entities; +using Yi.Framework.SqlSugarCore.Repositories; -//namespace Volo.Abp.AuditLogging.EntityFrameworkCore; +namespace Volo.Abp.AuditLogging.EntityFrameworkCore; -//public class SqlSugarCoreAuditLogRepository : SqlSugarRepository, IAuditLogRepository -//{ -// public SqlSugarCoreAuditLogRepository(ISugarDbContextProvider sugarDbContextProvider) : base(sugarDbContextProvider) -// { -// } +public class SqlSugarCoreAuditLogRepository : SqlSugarObjectRepository,IAuditLogRepository +{ + public virtual async Task> GetListAsync( + string sorting = null, + int maxResultCount = 50, + int skipCount = 0, + DateTime? startTime = null, + DateTime? endTime = null, + string httpMethod = null, + string url = null, + Guid? userId = null, + string userName = null, + string applicationName = null, + string clientIpAddress = null, + string correlationId = null, + int? maxExecutionDuration = null, + int? minExecutionDuration = null, + bool? hasException = null, + HttpStatusCode? httpStatusCode = null, + bool includeDetails = false, + CancellationToken cancellationToken = default) + { + var query = await GetListQueryAsync( + startTime, + endTime, + httpMethod, + url, + userId, + userName, + applicationName, + clientIpAddress, + correlationId, + maxExecutionDuration, + minExecutionDuration, + hasException, + httpStatusCode, + includeDetails + ); -// public virtual async Task> GetListAsync( -// string sorting = null, -// int maxResultCount = 50, -// int skipCount = 0, -// DateTime? startTime = null, -// DateTime? endTime = null, -// string httpMethod = null, -// string url = null, -// Guid? userId = null, -// string userName = null, -// string applicationName = null, -// string clientIpAddress = null, -// string correlationId = null, -// int? maxExecutionDuration = null, -// int? minExecutionDuration = null, -// bool? hasException = null, -// HttpStatusCode? httpStatusCode = null, -// bool includeDetails = false, -// CancellationToken cancellationToken = default) -// { -// var query = await GetListQueryAsync( -// startTime, -// endTime, -// httpMethod, -// url, -// userId, -// userName, -// applicationName, -// clientIpAddress, -// correlationId, -// maxExecutionDuration, -// minExecutionDuration, -// hasException, -// httpStatusCode, -// includeDetails -// ); + var auditLogs = await query + .OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(AuditLog.ExecutionTime) + " DESC") : sorting) + .ToPageListAsync(skipCount, maxResultCount, cancellationToken); -// var auditLogs = await query -// .OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(AuditLog.ExecutionTime) + " DESC") : sorting) -// .PageBy(skipCount, maxResultCount) -// .ToListAsync(GetCancellationToken(cancellationToken)); + return auditLogs.Adapt>(); + } -// return auditLogs; -// } + public virtual async Task GetCountAsync( + DateTime? startTime = null, + DateTime? endTime = null, + string httpMethod = null, + string url = null, + Guid? userId = null, + string userName = null, + string applicationName = null, + string clientIpAddress = null, + string correlationId = null, + int? maxExecutionDuration = null, + int? minExecutionDuration = null, + bool? hasException = null, + HttpStatusCode? httpStatusCode = null, + CancellationToken cancellationToken = default) + { + var query = await GetListQueryAsync( + startTime, + endTime, + httpMethod, + url, + userId, + userName, + applicationName, + clientIpAddress, + correlationId, + maxExecutionDuration, + minExecutionDuration, + hasException, + httpStatusCode + ); -// public virtual async Task GetCountAsync( -// DateTime? startTime = null, -// DateTime? endTime = null, -// string httpMethod = null, -// string url = null, -// Guid? userId = null, -// string userName = null, -// string applicationName = null, -// string clientIpAddress = null, -// string correlationId = null, -// int? maxExecutionDuration = null, -// int? minExecutionDuration = null, -// bool? hasException = null, -// HttpStatusCode? httpStatusCode = null, -// CancellationToken cancellationToken = default) -// { -// var query = await GetListQueryAsync( -// startTime, -// endTime, -// httpMethod, -// url, -// userId, -// userName, -// applicationName, -// clientIpAddress, -// correlationId, -// maxExecutionDuration, -// minExecutionDuration, -// hasException, -// httpStatusCode -// ); + var totalCount = await query.CountAsync(cancellationToken); -// var totalCount = await query.LongCountAsync(GetCancellationToken(cancellationToken)); + return totalCount; + } -// return totalCount; -// } + protected virtual async Task> GetListQueryAsync( + DateTime? startTime = null, + DateTime? endTime = null, + string httpMethod = null, + string url = null, + Guid? userId = null, + string userName = null, + string applicationName = null, + string clientIpAddress = null, + string correlationId = null, + int? maxExecutionDuration = null, + int? minExecutionDuration = null, + bool? hasException = null, + HttpStatusCode? httpStatusCode = null, + bool includeDetails = false) + { + var nHttpStatusCode = (int?)httpStatusCode; + return (await GetDbContextAsync()).Queryable() + .WhereIF(startTime.HasValue, auditLog => auditLog.ExecutionTime >= startTime) + .WhereIF(endTime.HasValue, auditLog => auditLog.ExecutionTime <= endTime) + .WhereIF(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions != "") + .WhereIF(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null || auditLog.Exceptions == "") + .WhereIF(httpMethod != null, auditLog => auditLog.HttpMethod == httpMethod) + .WhereIF(url != null, auditLog => auditLog.Url != null && auditLog.Url.Contains(url)) + .WhereIF(userId != null, auditLog => auditLog.UserId == userId) + .WhereIF(userName != null, auditLog => auditLog.UserName == userName) + .WhereIF(applicationName != null, auditLog => auditLog.ApplicationName == applicationName) + .WhereIF(clientIpAddress != null, auditLog => auditLog.ClientIpAddress != null && auditLog.ClientIpAddress == clientIpAddress) + .WhereIF(correlationId != null, auditLog => auditLog.CorrelationId == correlationId) + .WhereIF(httpStatusCode != null && httpStatusCode > 0, auditLog => auditLog.HttpStatusCode == nHttpStatusCode) + .WhereIF(maxExecutionDuration != null && maxExecutionDuration.Value > 0, auditLog => auditLog.ExecutionDuration <= maxExecutionDuration) + .WhereIF(minExecutionDuration != null && minExecutionDuration.Value > 0, auditLog => auditLog.ExecutionDuration >= minExecutionDuration); + } -// protected virtual async Task> GetListQueryAsync( -// DateTime? startTime = null, -// DateTime? endTime = null, -// string httpMethod = null, -// string url = null, -// Guid? userId = null, -// string userName = null, -// string applicationName = null, -// string clientIpAddress = null, -// string correlationId = null, -// int? maxExecutionDuration = null, -// int? minExecutionDuration = null, -// bool? hasException = null, -// HttpStatusCode? httpStatusCode = null, -// bool includeDetails = false) -// { -// var nHttpStatusCode = (int?)httpStatusCode; -// return (await GetDbSetAsync()).AsNoTracking() -// .IncludeDetails(includeDetails) -// .WhereIf(startTime.HasValue, auditLog => auditLog.ExecutionTime >= startTime) -// .WhereIf(endTime.HasValue, auditLog => auditLog.ExecutionTime <= endTime) -// .WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions != "") -// .WhereIf(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null || auditLog.Exceptions == "") -// .WhereIf(httpMethod != null, auditLog => auditLog.HttpMethod == httpMethod) -// .WhereIf(url != null, auditLog => auditLog.Url != null && auditLog.Url.Contains(url)) -// .WhereIf(userId != null, auditLog => auditLog.UserId == userId) -// .WhereIf(userName != null, auditLog => auditLog.UserName == userName) -// .WhereIf(applicationName != null, auditLog => auditLog.ApplicationName == applicationName) -// .WhereIf(clientIpAddress != null, auditLog => auditLog.ClientIpAddress != null && auditLog.ClientIpAddress == clientIpAddress) -// .WhereIf(correlationId != null, auditLog => auditLog.CorrelationId == correlationId) -// .WhereIf(httpStatusCode != null && httpStatusCode > 0, auditLog => auditLog.HttpStatusCode == nHttpStatusCode) -// .WhereIf(maxExecutionDuration != null && maxExecutionDuration.Value > 0, auditLog => auditLog.ExecutionDuration <= maxExecutionDuration) -// .WhereIf(minExecutionDuration != null && minExecutionDuration.Value > 0, auditLog => auditLog.ExecutionDuration >= minExecutionDuration); -// } + public virtual async Task> GetAverageExecutionDurationPerDayAsync( + DateTime startDate, + DateTime endDate, + CancellationToken cancellationToken = default) + { + var result = await (await GetDbContextAsync()).Queryable() + .Where(a => a.ExecutionTime < endDate.AddDays(1) && a.ExecutionTime > startDate) + .OrderBy(t => t.ExecutionTime) + .GroupBy(t => new { t.ExecutionTime.Date }) + .Select(g => new { Day =SqlFunc.AggregateMin(g.ExecutionTime), avgExecutionTime = SqlFunc.AggregateAvg( g.ExecutionDuration) }) + .ToListAsync(cancellationToken); -// public virtual async Task> GetAverageExecutionDurationPerDayAsync( -// DateTime startDate, -// DateTime endDate, -// CancellationToken cancellationToken = default) -// { -// var result = await (await GetDbSetAsync()).AsNoTracking() -// .Where(a => a.ExecutionTime < endDate.AddDays(1) && a.ExecutionTime > startDate) -// .OrderBy(t => t.ExecutionTime) -// .GroupBy(t => new { t.ExecutionTime.Date }) -// .Select(g => new { Day = g.Min(t => t.ExecutionTime), avgExecutionTime = g.Average(t => t.ExecutionDuration) }) -// .ToListAsync(GetCancellationToken(cancellationToken)); + return result.ToDictionary(element => element.Day.ClearTime(), element => (double)element.avgExecutionTime); + } -// return result.ToDictionary(element => element.Day.ClearTime(), element => element.avgExecutionTime); -// } + public virtual async Task GetEntityChange( + Guid entityChangeId, + CancellationToken cancellationToken = default) + { + var entityChange = await (await GetDbContextAsync()).Queryable() + .Where(x => x.Id == entityChangeId) + .OrderBy(x => x.Id) + .FirstAsync(cancellationToken); -// [Obsolete("Use WithDetailsAsync method.")] -// public override IQueryable WithDetails() -// { -// return GetQueryable().IncludeDetails(); -// } + if (entityChange == null) + { + throw new EntityNotFoundException(typeof(EntityChange)); + } -// public override async Task> WithDetailsAsync() -// { -// return (await GetQueryableAsync()).IncludeDetails(); -// } + return entityChange; + } -// public virtual async Task GetEntityChange( -// Guid entityChangeId, -// CancellationToken cancellationToken = default) -// { -// var entityChange = await (await GetDbContextAsync()).Set() -// .AsNoTracking() -// .IncludeDetails() -// .Where(x => x.Id == entityChangeId) -// .OrderBy(x => x.Id) -// .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); + public virtual async Task> GetEntityChangeListAsync( + string sorting = null, + int maxResultCount = 50, + int skipCount = 0, + Guid? auditLogId = null, + DateTime? startTime = null, + DateTime? endTime = null, + EntityChangeType? changeType = null, + string entityId = null, + string entityTypeFullName = null, + bool includeDetails = false, + CancellationToken cancellationToken = default) + { + var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, includeDetails); -// if (entityChange == null) -// { -// throw new EntityNotFoundException(typeof(EntityChange)); -// } + return await query.OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(EntityChange.ChangeTime) + " DESC") : sorting) + .ToPageListAsync(skipCount, maxResultCount, cancellationToken); + } -// return entityChange; -// } + public virtual async Task GetEntityChangeCountAsync( + Guid? auditLogId = null, + DateTime? startTime = null, + DateTime? endTime = null, + EntityChangeType? changeType = null, + string entityId = null, + string entityTypeFullName = null, + CancellationToken cancellationToken = default) + { + var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName); -// public virtual async Task> GetEntityChangeListAsync( -// string sorting = null, -// int maxResultCount = 50, -// int skipCount = 0, -// Guid? auditLogId = null, -// DateTime? startTime = null, -// DateTime? endTime = null, -// EntityChangeType? changeType = null, -// string entityId = null, -// string entityTypeFullName = null, -// bool includeDetails = false, -// CancellationToken cancellationToken = default) -// { -// var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, includeDetails); + var totalCount = await query.CountAsync(cancellationToken); -// return await query.OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(EntityChange.ChangeTime) + " DESC") : sorting) -// .PageBy(skipCount, maxResultCount) -// .ToListAsync(GetCancellationToken(cancellationToken)); -// } + return totalCount; + } -// public virtual async Task GetEntityChangeCountAsync( -// Guid? auditLogId = null, -// DateTime? startTime = null, -// DateTime? endTime = null, -// EntityChangeType? changeType = null, -// string entityId = null, -// string entityTypeFullName = null, -// CancellationToken cancellationToken = default) -// { -// var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName); + public virtual async Task GetEntityChangeWithUsernameAsync( + Guid entityChangeId, + CancellationToken cancellationToken = default) + { + var auditLog = await (await GetDbContextAsync()).Queryable() + .Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId)).FirstAsync(cancellationToken); -// var totalCount = await query.LongCountAsync(GetCancellationToken(cancellationToken)); + return new EntityChangeWithUsername() + { + EntityChange = auditLog.EntityChanges.First(x => x.Id == entityChangeId), + UserName = auditLog.UserName + }; + } -// return totalCount; -// } + public virtual async Task> GetEntityChangesWithUsernameAsync( + string entityId, + string entityTypeFullName, + CancellationToken cancellationToken = default) + { + var dbContext = await GetDbContextAsync(); -// public virtual async Task GetEntityChangeWithUsernameAsync( -// Guid entityChangeId, -// CancellationToken cancellationToken = default) -// { -// var auditLog = await (await GetDbSetAsync()).AsNoTracking().IncludeDetails() -// .Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId)).FirstAsync(GetCancellationToken(cancellationToken)); + var query = dbContext.Queryable() + .Where(x => x.EntityId == entityId && x.EntityTypeFullName == entityTypeFullName); + return await query.LeftJoin((change, audit) => change.AuditLogId == audit.Id) + .Select((change, audit) => new EntityChangeWithUsername { EntityChange = change, UserName = audit.UserName }, true) + .OrderByDescending(x => x.EntityChange.ChangeTime).ToListAsync(cancellationToken); -// return new EntityChangeWithUsername() -// { -// EntityChange = auditLog.EntityChanges.First(x => x.Id == entityChangeId), -// UserName = auditLog.UserName -// }; -// } + } -// public virtual async Task> GetEntityChangesWithUsernameAsync( -// string entityId, -// string entityTypeFullName, -// CancellationToken cancellationToken = default) -// { -// var dbContext = await GetDbContextAsync(); + protected virtual async Task> GetEntityChangeListQueryAsync( + Guid? auditLogId = null, + DateTime? startTime = null, + DateTime? endTime = null, + EntityChangeType? changeType = null, + string entityId = null, + string entityTypeFullName = null, + bool includeDetails = false) + { + return (await GetDbContextAsync()) + .Queryable() + .WhereIF(auditLogId.HasValue, e => e.AuditLogId == auditLogId) + .WhereIF(startTime.HasValue, e => e.ChangeTime >= startTime) + .WhereIF(endTime.HasValue, e => e.ChangeTime <= endTime) + .WhereIF(changeType.HasValue, e => e.ChangeType == changeType) + .WhereIF(!string.IsNullOrWhiteSpace(entityId), e => e.EntityId == entityId) + .WhereIF(!string.IsNullOrWhiteSpace(entityTypeFullName), e => e.EntityTypeFullName.Contains(entityTypeFullName)); + } -// var query = dbContext.Set() -// .AsNoTracking() -// .IncludeDetails() -// .Where(x => x.EntityId == entityId && x.EntityTypeFullName == entityTypeFullName); + Task> IAuditLogRepository.GetListAsync(string sorting, int maxResultCount, int skipCount, DateTime? startTime, DateTime? endTime, string httpMethod, string url, Guid? userId, string userName, string applicationName, string clientIpAddress, string correlationId, int? maxExecutionDuration, int? minExecutionDuration, bool? hasException, HttpStatusCode? httpStatusCode, bool includeDetails, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } -// return await (from e in query -// join auditLog in dbContext.AuditLogs on e.AuditLogId equals auditLog.Id -// select new EntityChangeWithUsername { EntityChange = e, UserName = auditLog.UserName }) -// .OrderByDescending(x => x.EntityChange.ChangeTime).ToListAsync(GetCancellationToken(cancellationToken)); -// } -// protected virtual async Task> GetEntityChangeListQueryAsync( -// Guid? auditLogId = null, -// DateTime? startTime = null, -// DateTime? endTime = null, -// EntityChangeType? changeType = null, -// string entityId = null, -// string entityTypeFullName = null, -// bool includeDetails = false) -// { -// return (await GetDbContextAsync()) -// .Set() -// .AsNoTracking() -// .IncludeDetails(includeDetails) -// .WhereIf(auditLogId.HasValue, e => e.AuditLogId == auditLogId) -// .WhereIf(startTime.HasValue, e => e.ChangeTime >= startTime) -// .WhereIf(endTime.HasValue, e => e.ChangeTime <= endTime) -// .WhereIf(changeType.HasValue, e => e.ChangeType == changeType) -// .WhereIf(!string.IsNullOrWhiteSpace(entityId), e => e.EntityId == entityId) -// .WhereIf(!string.IsNullOrWhiteSpace(entityTypeFullName), e => e.EntityTypeFullName.Contains(entityTypeFullName)); -// } -//} + + public Task GetAsync(Expression> predicate, bool includeDetails = true, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task DeleteAsync(Expression> predicate, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task DeleteDirectAsync(Expression> predicate, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + IQueryable IReadOnlyRepository.WithDetails() + { + throw new NotImplementedException(); + } + + public IQueryable WithDetails(params Expression>[] propertySelectors) + { + throw new NotImplementedException(); + } + + Task> IReadOnlyRepository.WithDetailsAsync() + { + throw new NotImplementedException(); + } + + public Task> WithDetailsAsync(params Expression>[] propertySelectors) + { + throw new NotImplementedException(); + } + + Task> IReadOnlyRepository.GetQueryableAsync() + { + throw new NotImplementedException(); + } + + public Task> GetListAsync(Expression> predicate, bool includeDetails = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task InsertAsync(AuditLog entity, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task InsertManyAsync(IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task UpdateAsync(AuditLog entity, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task UpdateManyAsync(IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task DeleteAsync(AuditLog entity, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task DeleteManyAsync(IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + Task IReadOnlyBasicRepository.GetAsync(Guid id, bool includeDetails, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + Task IReadOnlyBasicRepository.FindAsync(Guid id, bool includeDetails, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + Task> IReadOnlyBasicRepository.GetListAsync(bool includeDetails, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + Task> IReadOnlyBasicRepository.GetPagedListAsync(int skipCount, int maxResultCount, string sorting, bool includeDetails, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } +} diff --git a/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/Yi.AuditLogging.SqlSugarCore.csproj b/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/Yi.AuditLogging.SqlSugarCore.csproj index f16bc4cd..b27ef778 100644 --- a/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/Yi.AuditLogging.SqlSugarCore.csproj +++ b/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/Yi.AuditLogging.SqlSugarCore.csproj @@ -11,6 +11,7 @@ + diff --git a/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/YiAuditLoggingDbContext.cs b/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/YiAuditLoggingDbContext.cs index 1726fe9c..5922f30b 100644 --- a/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/YiAuditLoggingDbContext.cs +++ b/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/YiAuditLoggingDbContext.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; +using System.Reflection; using SqlSugar; using Volo.Abp.AuditLogging; using Volo.Abp.DependencyInjection; @@ -23,11 +18,11 @@ namespace Yi.AuditLogging.SqlSugarCore column.DbTableName = AbpAuditLoggingDbProperties.DbTablePrefix + "AuditLogs"; column.IfTable() - + .UpdateProperty(x => x.Id, x => { - x.IsPrimarykey = true; + x.IsPrimarykey = true; }) .UpdateProperty(x => x.ApplicationName, @@ -38,97 +33,98 @@ namespace Yi.AuditLogging.SqlSugarCore }); - //builder.Entity(b => - //{ - // b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "AuditLogs", AbpAuditLoggingDbProperties.DbSchema); + // builder.Entity(b => + // { + // b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "AuditLogs", AbpAuditLoggingDbProperties.DbSchema); - // b.ConfigureByConvention(); + // b.ConfigureByConvention(); - // b.Property(x => x.ApplicationName).HasMaxLength(AuditLogConsts.MaxApplicationNameLength).HasColumnName(nameof(AuditLog.ApplicationName)); - // b.Property(x => x.ClientIpAddress).HasMaxLength(AuditLogConsts.MaxClientIpAddressLength).HasColumnName(nameof(AuditLog.ClientIpAddress)); - // b.Property(x => x.ClientName).HasMaxLength(AuditLogConsts.MaxClientNameLength).HasColumnName(nameof(AuditLog.ClientName)); - // b.Property(x => x.ClientId).HasMaxLength(AuditLogConsts.MaxClientIdLength).HasColumnName(nameof(AuditLog.ClientId)); - // b.Property(x => x.CorrelationId).HasMaxLength(AuditLogConsts.MaxCorrelationIdLength).HasColumnName(nameof(AuditLog.CorrelationId)); - // b.Property(x => x.BrowserInfo).HasMaxLength(AuditLogConsts.MaxBrowserInfoLength).HasColumnName(nameof(AuditLog.BrowserInfo)); - // b.Property(x => x.HttpMethod).HasMaxLength(AuditLogConsts.MaxHttpMethodLength).HasColumnName(nameof(AuditLog.HttpMethod)); - // b.Property(x => x.Url).HasMaxLength(AuditLogConsts.MaxUrlLength).HasColumnName(nameof(AuditLog.Url)); - // b.Property(x => x.HttpStatusCode).HasColumnName(nameof(AuditLog.HttpStatusCode)); + // b.Property(x => x.ApplicationName).HasMaxLength(AuditLogConsts.MaxApplicationNameLength).HasColumnName(nameof(AuditLog.ApplicationName)); + // b.Property(x => x.ClientIpAddress).HasMaxLength(AuditLogConsts.MaxClientIpAddressLength).HasColumnName(nameof(AuditLog.ClientIpAddress)); + // b.Property(x => x.ClientName).HasMaxLength(AuditLogConsts.MaxClientNameLength).HasColumnName(nameof(AuditLog.ClientName)); + // b.Property(x => x.ClientId).HasMaxLength(AuditLogConsts.MaxClientIdLength).HasColumnName(nameof(AuditLog.ClientId)); + // b.Property(x => x.CorrelationId).HasMaxLength(AuditLogConsts.MaxCorrelationIdLength).HasColumnName(nameof(AuditLog.CorrelationId)); + // b.Property(x => x.BrowserInfo).HasMaxLength(AuditLogConsts.MaxBrowserInfoLength).HasColumnName(nameof(AuditLog.BrowserInfo)); + // b.Property(x => x.HttpMethod).HasMaxLength(AuditLogConsts.MaxHttpMethodLength).HasColumnName(nameof(AuditLog.HttpMethod)); + // b.Property(x => x.Url).HasMaxLength(AuditLogConsts.MaxUrlLength).HasColumnName(nameof(AuditLog.Url)); + // b.Property(x => x.HttpStatusCode).HasColumnName(nameof(AuditLog.HttpStatusCode)); - // b.Property(x => x.Comments).HasMaxLength(AuditLogConsts.MaxCommentsLength).HasColumnName(nameof(AuditLog.Comments)); - // b.Property(x => x.ExecutionDuration).HasColumnName(nameof(AuditLog.ExecutionDuration)); - // b.Property(x => x.ImpersonatorTenantId).HasColumnName(nameof(AuditLog.ImpersonatorTenantId)); - // b.Property(x => x.ImpersonatorUserId).HasColumnName(nameof(AuditLog.ImpersonatorUserId)); - // b.Property(x => x.ImpersonatorTenantName).HasMaxLength(AuditLogConsts.MaxTenantNameLength).HasColumnName(nameof(AuditLog.ImpersonatorTenantName)); - // b.Property(x => x.ImpersonatorUserName).HasMaxLength(AuditLogConsts.MaxUserNameLength).HasColumnName(nameof(AuditLog.ImpersonatorUserName)); - // b.Property(x => x.UserId).HasColumnName(nameof(AuditLog.UserId)); - // b.Property(x => x.UserName).HasMaxLength(AuditLogConsts.MaxUserNameLength).HasColumnName(nameof(AuditLog.UserName)); - // b.Property(x => x.TenantId).HasColumnName(nameof(AuditLog.TenantId)); - // b.Property(x => x.TenantName).HasMaxLength(AuditLogConsts.MaxTenantNameLength).HasColumnName(nameof(AuditLog.TenantName)); + // b.Property(x => x.Comments).HasMaxLength(AuditLogConsts.MaxCommentsLength).HasColumnName(nameof(AuditLog.Comments)); + // b.Property(x => x.ExecutionDuration).HasColumnName(nameof(AuditLog.ExecutionDuration)); + // b.Property(x => x.ImpersonatorTenantId).HasColumnName(nameof(AuditLog.ImpersonatorTenantId)); + // b.Property(x => x.ImpersonatorUserId).HasColumnName(nameof(AuditLog.ImpersonatorUserId)); + // b.Property(x => x.ImpersonatorTenantName).HasMaxLength(AuditLogConsts.MaxTenantNameLength).HasColumnName(nameof(AuditLog.ImpersonatorTenantName)); + // b.Property(x => x.ImpersonatorUserName).HasMaxLength(AuditLogConsts.MaxUserNameLength).HasColumnName(nameof(AuditLog.ImpersonatorUserName)); + // b.Property(x => x.UserId).HasColumnName(nameof(AuditLog.UserId)); + // b.Property(x => x.UserName).HasMaxLength(AuditLogConsts.MaxUserNameLength).HasColumnName(nameof(AuditLog.UserName)); + // b.Property(x => x.TenantId).HasColumnName(nameof(AuditLog.TenantId)); + // b.Property(x => x.TenantName).HasMaxLength(AuditLogConsts.MaxTenantNameLength).HasColumnName(nameof(AuditLog.TenantName)); - // b.HasMany(a => a.Actions).WithOne().HasForeignKey(x => x.AuditLogId).IsRequired(); - // b.HasMany(a => a.EntityChanges).WithOne().HasForeignKey(x => x.AuditLogId).IsRequired(); + // b.HasMany(a => a.Actions).WithOne().HasForeignKey(x => x.AuditLogId).IsRequired(); + // b.HasMany(a => a.EntityChanges).WithOne().HasForeignKey(x => x.AuditLogId).IsRequired(); - // b.HasIndex(x => new { x.TenantId, x.ExecutionTime }); - // b.HasIndex(x => new { x.TenantId, x.UserId, x.ExecutionTime }); + // b.HasIndex(x => new { x.TenantId, x.ExecutionTime }); + // b.HasIndex(x => new { x.TenantId, x.UserId, x.ExecutionTime }); - // b.ApplyObjectExtensionMappings(); - //}); + // b.ApplyObjectExtensionMappings(); + // }); - //builder.Entity(b => - //{ - // b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "AuditLogActions", AbpAuditLoggingDbProperties.DbSchema); + // builder.Entity(b => + // { + // b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "AuditLogActions", AbpAuditLoggingDbProperties.DbSchema); - // b.ConfigureByConvention(); + // b.ConfigureByConvention(); - // b.Property(x => x.AuditLogId).HasColumnName(nameof(AuditLogAction.AuditLogId)); - // b.Property(x => x.ServiceName).HasMaxLength(AuditLogActionConsts.MaxServiceNameLength).HasColumnName(nameof(AuditLogAction.ServiceName)); - // b.Property(x => x.MethodName).HasMaxLength(AuditLogActionConsts.MaxMethodNameLength).HasColumnName(nameof(AuditLogAction.MethodName)); - // b.Property(x => x.Parameters).HasMaxLength(AuditLogActionConsts.MaxParametersLength).HasColumnName(nameof(AuditLogAction.Parameters)); - // b.Property(x => x.ExecutionTime).HasColumnName(nameof(AuditLogAction.ExecutionTime)); - // b.Property(x => x.ExecutionDuration).HasColumnName(nameof(AuditLogAction.ExecutionDuration)); + // b.Property(x => x.AuditLogId).HasColumnName(nameof(AuditLogAction.AuditLogId)); + // b.Property(x => x.ServiceName).HasMaxLength(AuditLogActionConsts.MaxServiceNameLength).HasColumnName(nameof(AuditLogAction.ServiceName)); + // b.Property(x => x.MethodName).HasMaxLength(AuditLogActionConsts.MaxMethodNameLength).HasColumnName(nameof(AuditLogAction.MethodName)); + // b.Property(x => x.Parameters).HasMaxLength(AuditLogActionConsts.MaxParametersLength).HasColumnName(nameof(AuditLogAction.Parameters)); + // b.Property(x => x.ExecutionTime).HasColumnName(nameof(AuditLogAction.ExecutionTime)); + // b.Property(x => x.ExecutionDuration).HasColumnName(nameof(AuditLogAction.ExecutionDuration)); - // b.HasIndex(x => new { x.AuditLogId }); - // b.HasIndex(x => new { x.TenantId, x.ServiceName, x.MethodName, x.ExecutionTime }); + // b.HasIndex(x => new { x.AuditLogId }); + // b.HasIndex(x => new { x.TenantId, x.ServiceName, x.MethodName, x.ExecutionTime }); - // b.ApplyObjectExtensionMappings(); - //}); + // b.ApplyObjectExtensionMappings(); + // }); - //builder.Entity(b => - //{ - // b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "EntityChanges", AbpAuditLoggingDbProperties.DbSchema); + // builder.Entity(b => + // { + // b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "EntityChanges", AbpAuditLoggingDbProperties.DbSchema); - // b.ConfigureByConvention(); + // b.ConfigureByConvention(); - // b.Property(x => x.EntityTypeFullName).HasMaxLength(EntityChangeConsts.MaxEntityTypeFullNameLength).IsRequired().HasColumnName(nameof(EntityChange.EntityTypeFullName)); - // b.Property(x => x.EntityId).HasMaxLength(EntityChangeConsts.MaxEntityIdLength).IsRequired().HasColumnName(nameof(EntityChange.EntityId)); - // b.Property(x => x.AuditLogId).IsRequired().HasColumnName(nameof(EntityChange.AuditLogId)); - // b.Property(x => x.ChangeTime).IsRequired().HasColumnName(nameof(EntityChange.ChangeTime)); - // b.Property(x => x.ChangeType).IsRequired().HasColumnName(nameof(EntityChange.ChangeType)); - // b.Property(x => x.TenantId).HasColumnName(nameof(EntityChange.TenantId)); + // b.Property(x => x.EntityTypeFullName).HasMaxLength(EntityChangeConsts.MaxEntityTypeFullNameLength).IsRequired().HasColumnName(nameof(EntityChange.EntityTypeFullName)); + // b.Property(x => x.EntityId).HasMaxLength(EntityChangeConsts.MaxEntityIdLength).IsRequired().HasColumnName(nameof(EntityChange.EntityId)); + // b.Property(x => x.AuditLogId).IsRequired().HasColumnName(nameof(EntityChange.AuditLogId)); + // b.Property(x => x.ChangeTime).IsRequired().HasColumnName(nameof(EntityChange.ChangeTime)); + // b.Property(x => x.ChangeType).IsRequired().HasColumnName(nameof(EntityChange.ChangeType)); + // b.Property(x => x.TenantId).HasColumnName(nameof(EntityChange.TenantId)); - // b.HasMany(a => a.PropertyChanges).WithOne().HasForeignKey(x => x.EntityChangeId); + // b.HasMany(a => a.PropertyChanges).WithOne().HasForeignKey(x => x.EntityChangeId); - // b.HasIndex(x => new { x.AuditLogId }); - // b.HasIndex(x => new { x.TenantId, x.EntityTypeFullName, x.EntityId }); + // b.HasIndex(x => new { x.AuditLogId }); + // b.HasIndex(x => new { x.TenantId, x.EntityTypeFullName, x.EntityId }); - // b.ApplyObjectExtensionMappings(); - //}); + // b.ApplyObjectExtensionMappings(); + // }); - //builder.Entity(b => - //{ - // b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "EntityPropertyChanges", AbpAuditLoggingDbProperties.DbSchema); + // builder.Entity(b => + // { + // b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "EntityPropertyChanges", AbpAuditLoggingDbProperties.DbSchema); - // b.ConfigureByConvention(); + // b.ConfigureByConvention(); - // b.Property(x => x.NewValue).HasMaxLength(EntityPropertyChangeConsts.MaxNewValueLength).HasColumnName(nameof(EntityPropertyChange.NewValue)); - // b.Property(x => x.PropertyName).HasMaxLength(EntityPropertyChangeConsts.MaxPropertyNameLength).IsRequired().HasColumnName(nameof(EntityPropertyChange.PropertyName)); - // b.Property(x => x.PropertyTypeFullName).HasMaxLength(EntityPropertyChangeConsts.MaxPropertyTypeFullNameLength).IsRequired().HasColumnName(nameof(EntityPropertyChange.PropertyTypeFullName)); - // b.Property(x => x.OriginalValue).HasMaxLength(EntityPropertyChangeConsts.MaxOriginalValueLength).HasColumnName(nameof(EntityPropertyChange.OriginalValue)); + // b.Property(x => x.NewValue).HasMaxLength(EntityPropertyChangeConsts.MaxNewValueLength).HasColumnName(nameof(EntityPropertyChange.NewValue)); + // b.Property(x => x.PropertyName).HasMaxLength(EntityPropertyChangeConsts.MaxPropertyNameLength).IsRequired().HasColumnName(nameof(EntityPropertyChange.PropertyName)); + // b.Property(x => x.PropertyTypeFullName).HasMaxLength(EntityPropertyChangeConsts.MaxPropertyTypeFullNameLength).IsRequired().HasColumnName(nameof(EntityPropertyChange.PropertyTypeFullName)); + // b.Property(x => x.OriginalValue).HasMaxLength(EntityPropertyChangeConsts.MaxOriginalValueLength).HasColumnName(nameof(EntityPropertyChange.OriginalValue)); - // b.HasIndex(x => new { x.EntityChangeId }); + // b.HasIndex(x => new { x.EntityChangeId }); - // b.ApplyObjectExtensionMappings(); - //}); + // b.ApplyObjectExtensionMappings(); + // }); + //} } } -} +} \ No newline at end of file diff --git a/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/YiAuditLoggingSqlSugarCoreModule.cs b/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/YiAuditLoggingSqlSugarCoreModule.cs index 2c0b2126..039c8039 100644 --- a/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/YiAuditLoggingSqlSugarCoreModule.cs +++ b/Yi.Abp.Net8/module/audit-logging/Yi.AuditLogging.SqlSugarCore/YiAuditLoggingSqlSugarCoreModule.cs @@ -1,4 +1,7 @@ -using Volo.Abp.AuditLogging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Volo.Abp.AuditLogging; +using Volo.Abp.AuditLogging.EntityFrameworkCore; using Volo.Abp.Modularity; using Yi.Framework.SqlSugarCore; @@ -6,11 +9,13 @@ namespace Yi.AuditLogging.SqlSugarCore { [DependsOn(typeof(AbpAuditLoggingDomainModule))] [DependsOn(typeof(YiFrameworkSqlSugarCoreModule))] - public class YiAuditLoggingSqlSugarCoreModule:AbpModule + public class YiAuditLoggingSqlSugarCoreModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { + context.Services.Replace(new ServiceDescriptor(typeof(IAuditLogRepository), typeof(SqlSugarCoreAuditLogRepository), lifetime: ServiceLifetime.Transient)); context.Services.AddYiDbContext(); + } } } diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Article/ArticleImprotDto.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Article/ArticleImprotDto.cs new file mode 100644 index 00000000..98e8ba3d --- /dev/null +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application.Contracts/Dtos/Article/ArticleImprotDto.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Yi.Framework.Bbs.Domain.Shared.Enums; + +namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Article +{ + public class ArticleImprotDto + { + /// + /// 主题id + /// + [Required] + public Guid DiscussId { get; set; } + + public Guid ArticleParentId { get; set; }= Guid.Empty; + + public ArticleImportTypeEnum ImportType { get; set; } = ArticleImportTypeEnum.Defalut; +} +} diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/ArticleService.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/ArticleService.cs index d6ef86c5..57de3e2b 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/ArticleService.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/ArticleService.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Text; using Mapster; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; @@ -13,8 +15,10 @@ using Yi.Framework.Bbs.Application.Contracts.Dtos.Plate; using Yi.Framework.Bbs.Application.Contracts.IServices; using Yi.Framework.Bbs.Domain.Entities; using Yi.Framework.Bbs.Domain.Extensions; +using Yi.Framework.Bbs.Domain.Managers; using Yi.Framework.Bbs.Domain.Repositories; using Yi.Framework.Bbs.Domain.Shared.Consts; +using Yi.Framework.Bbs.Domain.Shared.Model; using Yi.Framework.Core.Extensions; using Yi.Framework.Ddd.Application; using Yi.Framework.Rbac.Domain.Authorization; @@ -32,18 +36,20 @@ namespace Yi.Framework.Bbs.Application.Services { public ArticleService(IArticleRepository articleRepository, ISqlSugarRepository discussRepository, - IDiscussService discussService) : base(articleRepository) + IDiscussService discussService, + ForumManager forumManager) : base(articleRepository) { _articleRepository = articleRepository; _discussRepository = discussRepository; _discussService = discussService; - + _forumManager = forumManager; } - private IArticleRepository _articleRepository { get; set; } - private ISqlSugarRepository _discussRepository { get; set; } - private IDiscussService _discussService { get; set; } + private ForumManager _forumManager; + private IArticleRepository _articleRepository; + private ISqlSugarRepository _discussRepository; + private IDiscussService _discussService; public override async Task> GetListAsync(ArticleGetListInputVo input) { @@ -134,6 +140,41 @@ namespace Yi.Framework.Bbs.Application.Services } + /// + /// 导入文章 + /// + /// + public async Task PostImportAsync([FromQuery] ArticleImprotDto input, [FromForm][Required] IFormFileCollection file) + { + var fileObjs = new List(); + if (file.Count > 0) + { + foreach (var item in file) + { + if (item.Length > 0) + { + using (var stream = item.OpenReadStream()) + { + using (var fileStream = new MemoryStream()) + { + await item.CopyToAsync(fileStream); + var bytes = fileStream.ToArray(); + + // 将字节转换成字符串 + var content = Encoding.UTF8.GetString(bytes); + fileObjs.Add(new FileObject() { FileName = item.FileName, Content = content }); + } + } + } + } + } + else + { + throw new UserFriendlyException("未选择文件"); + } + //使用简单工厂根据传入的类型进行判断 + await _forumManager.PostImportAsync(input.DiscussId, input.ArticleParentId, fileObjs, input.ImportType); + } /// diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/SettingService.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/SettingService.cs index 14ec2213..14298787 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/SettingService.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Application/Services/SettingService.cs @@ -18,5 +18,16 @@ namespace Yi.Framework.Bbs.Application.Services { return Task.FromResult("你好世界"); } + + /// + /// 获取头像文件 + /// + /// + public List GetIcon() + { + + return Directory.GetFiles("wwwroot/icon").Select(x => "wwwroot/icon/"+ Path.GetFileName(x)).ToList(); + + } } } diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Enums/ArticleImportTypeEnum.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Enums/ArticleImportTypeEnum.cs new file mode 100644 index 00000000..01686b76 --- /dev/null +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Enums/ArticleImportTypeEnum.cs @@ -0,0 +1,16 @@ +using System.ComponentModel; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace Yi.Framework.Bbs.Domain.Shared.Enums +{ + [JsonConverter(typeof(StringEnumConverter))] + public enum ArticleImportTypeEnum + { + [Description("默认导入方式")] + Defalut, + + [Description("vuePresss方式")] + VuePress + } +} diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Model/FileObject.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Model/FileObject.cs new file mode 100644 index 00000000..c0cd5580 --- /dev/null +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Model/FileObject.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.Bbs.Domain.Shared.Model +{ + public class FileObject + { + public string Content { get; set; } + public string FileName { get; set; } + } +} diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ArticleImport/AbstractArticleImport.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ArticleImport/AbstractArticleImport.cs new file mode 100644 index 00000000..c39b5dec --- /dev/null +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ArticleImport/AbstractArticleImport.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Bbs.Domain.Entities; +using Yi.Framework.Bbs.Domain.Shared.Model; + +namespace Yi.Framework.Bbs.Domain.Managers.ArticleImport +{ + public abstract class AbstractArticleImport + { + public virtual List Import(Guid discussId,Guid articleParentId, List fileObjs) + { + var articles = Convert(fileObjs); + articles.ForEach(article => + { + article.DiscussId = discussId; + article.ParentId = articleParentId; + }); + return articles; + } + public abstract List Convert(List fileObjs); + } +} diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ArticleImport/DefaultArticleImport.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ArticleImport/DefaultArticleImport.cs new file mode 100644 index 00000000..8ca58332 --- /dev/null +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ArticleImport/DefaultArticleImport.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Bbs.Domain.Entities; +using Yi.Framework.Bbs.Domain.Shared.Model; + +namespace Yi.Framework.Bbs.Domain.Managers.ArticleImport +{ + internal class DefaultArticleImport : AbstractArticleImport + { + public override List Convert(List fileObjs) + { + return fileObjs.OrderBy(x => x.FileName).Select(x => new ArticleEntity { Name = x.FileName, Content = x.Content }).ToList(); + } + } +} diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ArticleImport/VuePressArticleImport.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ArticleImport/VuePressArticleImport.cs new file mode 100644 index 00000000..6ebb0626 --- /dev/null +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ArticleImport/VuePressArticleImport.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Bbs.Domain.Entities; +using Yi.Framework.Bbs.Domain.Shared.Model; + +namespace Yi.Framework.Bbs.Domain.Managers.ArticleImport +{ + internal class VuePressArticleImport : AbstractArticleImport + { + public override List Convert(List fileObjs) + { + //排序及处理目录名称 + var fileNameHandler = fileObjs.OrderBy(x => x.FileName).Select(x => + { + var f = new FileObject { Content = x.Content }; + + //除去数字 + f.FileName = x.FileName.Split('.')[1]; + return f; + }); + + + //处理内容 + var fileContentHandler= fileNameHandler.Select(x => + { + var f = new FileObject { FileName = x.FileName }; + var lines = x.Content.SplitToLines(); + + var num = 0; + var startIndex = 0; + for (int i = 0; i < lines.Length; i++) + { + if (lines[i] == "---") + { + num++; + if (num == 2) + { + startIndex = i; + + break; + } + + } + + } + var linesRef = lines.ToList(); + + linesRef.RemoveRange(0, startIndex+1); + var result = string.Join(Environment.NewLine, linesRef); + f.Content = result; + return f; + }); + + var output = fileContentHandler.Select(x => new ArticleEntity() { Content = x.Content, Name = x.FileName }).ToList(); + + return output; + } + } +} diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ForumManager.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ForumManager.cs index 44b28d15..7ffd1225 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ForumManager.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain/Managers/ForumManager.cs @@ -1,5 +1,10 @@ -using Volo.Abp.Domain.Services; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Domain.Services; using Yi.Framework.Bbs.Domain.Entities; +using Yi.Framework.Bbs.Domain.Managers.ArticleImport; +using Yi.Framework.Bbs.Domain.Shared.Enums; +using Yi.Framework.Bbs.Domain.Shared.Model; using Yi.Framework.SqlSugarCore.Abstractions; namespace Yi.Framework.Bbs.Domain.Managers @@ -9,14 +14,16 @@ namespace Yi.Framework.Bbs.Domain.Managers /// public class ForumManager : DomainService { - public readonly ISqlSugarRepository _discussRepository; + public readonly ISqlSugarRepository _discussRepository; public readonly ISqlSugarRepository _plateEntityRepository; public readonly ISqlSugarRepository _commentRepository; - public ForumManager(ISqlSugarRepository discussRepository, ISqlSugarRepository plateEntityRepository, ISqlSugarRepository commentRepository) + public readonly ISqlSugarRepository _articleRepository; + public ForumManager(ISqlSugarRepository discussRepository, ISqlSugarRepository plateEntityRepository, ISqlSugarRepository commentRepository, ISqlSugarRepository articleRepository) { _discussRepository = discussRepository; _plateEntityRepository = plateEntityRepository; _commentRepository = commentRepository; + _articleRepository = articleRepository; } //主题是不能直接创建的,需要由领域服务统一创建 @@ -36,5 +43,35 @@ namespace Yi.Framework.Bbs.Domain.Managers entity.RootId = rootId; return await _commentRepository.InsertReturnEntityAsync(entity); } + + /// + /// 导入文章 + /// + /// + /// + /// + /// + /// + public async Task PostImportAsync(Guid discussId,Guid articleParentId, List fileObjs, ArticleImportTypeEnum importType) + { + AbstractArticleImport abstractArticleImport = default; + switch (importType) + { + case ArticleImportTypeEnum.Defalut: + abstractArticleImport = new DefaultArticleImport(); + + break; + case ArticleImportTypeEnum.VuePress: + abstractArticleImport = new VuePressArticleImport(); + break; + + default: abstractArticleImport = new DefaultArticleImport(); break; + } + + var articleHandled = abstractArticleImport.Import(discussId, articleParentId, fileObjs); + + //await _articleRepository.InsertManyAsync(articleHandled); + + } } } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs index 83675077..f6c9462c 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs @@ -248,6 +248,17 @@ namespace Yi.Framework.Rbac.Application.Services throw new UserFriendlyException("验证码错误"); } + private void ValidateUserName(RegisterDto input) + { + // 正则表达式,匹配只包含数字和字母的字符串 + string pattern = @"^[a-zA-Z0-9]+$"; + + bool isMatch = Regex.IsMatch(input.UserName, pattern); + if (!isMatch) + { + throw new UserFriendlyException("用户名不能包含除【字母】与【数字】的其他字符"); + } + } /// /// 注册,需要验证码通过 @@ -276,6 +287,10 @@ namespace Yi.Framework.Rbac.Application.Services { throw new UserFriendlyException("密码需大于等于6位!"); } + + //效验用户名 + ValidateUserName(input); + //效验验证码,根据电话号码获取 value,比对验证码已经uuid await ValidationPhoneCaptchaAsync(input); @@ -283,7 +298,7 @@ namespace Yi.Framework.Rbac.Application.Services //输入的用户名与电话号码都不能在数据库中存在 UserEntity user = new(); - var isExist = await _userRepository.IsAnyAsync(x =>x.UserName == input.UserName|| x.Phone == input.Phone); + var isExist = await _userRepository.IsAnyAsync(x => x.UserName == input.UserName || x.Phone == input.Phone); if (isExist) { throw new UserFriendlyException("用户已存在,注册失败"); diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/FileService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/FileService.cs index a2d2e59e..f98dab39 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/FileService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/FileService.cs @@ -21,13 +21,11 @@ namespace Yi.Framework.Rbac.Application.Services public class FileService : ApplicationService, IFileService { private readonly IRepository _repository; - private readonly HttpContext _httpContext; private IGuidGenerator _guidGenerator; - public FileService(IRepository repository, IHttpContextAccessor httpContextAccessor, IGuidGenerator guidGenerator) + public FileService(IRepository repository, IGuidGenerator guidGenerator) { _guidGenerator = guidGenerator; _repository = repository; - _httpContext = httpContextAccessor.HttpContext; } /// diff --git a/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiDbContext.cs b/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiDbContext.cs index 15e1b0b2..35913b5e 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiDbContext.cs +++ b/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiDbContext.cs @@ -16,6 +16,7 @@ namespace Yi.Abp.SqlSugarCore base.CustomDataFilter(); } + protected override void DataExecuted(object oldValue, DataAfterModel entityInfo) { base.DataExecuted(oldValue, entityInfo); diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/Yi.Abp.Web.csproj b/Yi.Abp.Net8/src/Yi.Abp.Web/Yi.Abp.Web.csproj index 3762bfbb..f8c4237c 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/Yi.Abp.Web.csproj +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/Yi.Abp.Web.csproj @@ -27,6 +27,9 @@ Always + + Always + @@ -37,7 +40,7 @@ - + diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs index 151f5d74..13dc515b 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs @@ -1,8 +1,10 @@ using System.Text; +using System.Text.Json.Serialization; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Cors; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; +using Newtonsoft.Json.Converters; using Volo.Abp; using Volo.Abp.AspNetCore.Authentication.JwtBearer; using Volo.Abp.AspNetCore.Mvc; @@ -64,6 +66,7 @@ namespace Yi.Abp.Web service.AddControllers().AddNewtonsoftJson(options => { options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; + options.SerializerSettings.Converters.Add(new StringEnumConverter()); }); Configure(options => @@ -150,6 +153,11 @@ namespace Yi.Abp.Web //swagger app.UseYiSwagger(); + + //静态资源 + app.UseStaticFiles("/api/app/wwwroot"); + app.UseDefaultFiles(); + app.UseDirectoryBrowser("/api/app/wwwroot"); //工作单元 app.UseUnitOfWork(); diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/0.png b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/0.png new file mode 100644 index 00000000..652bdf37 Binary files /dev/null and b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/0.png differ diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/1.png b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/1.png new file mode 100644 index 00000000..1431fa2f Binary files /dev/null and b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/1.png differ diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/2.png b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/2.png new file mode 100644 index 00000000..302112b9 Binary files /dev/null and b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/2.png differ diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/3.png b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/3.png new file mode 100644 index 00000000..b06ceb01 Binary files /dev/null and b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/3.png differ diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/4.png b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/4.png new file mode 100644 index 00000000..bd47b1fe Binary files /dev/null and b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/4.png differ diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/5.png b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/5.png new file mode 100644 index 00000000..0d1a1d2a Binary files /dev/null and b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/5.png differ diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/6.png b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/6.png new file mode 100644 index 00000000..c116c298 Binary files /dev/null and b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/6.png differ diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/8.png b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/8.png new file mode 100644 index 00000000..c3f6dc07 Binary files /dev/null and b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/8.png differ diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/9.png b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/9.png new file mode 100644 index 00000000..b7c8410f Binary files /dev/null and b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/icon/9.png differ diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/logo.png b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/logo.png new file mode 100644 index 00000000..226b005a Binary files /dev/null and b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/logo.png differ diff --git a/Yi.Bbs.Vue3/src/config/axios/service.js b/Yi.Bbs.Vue3/src/config/axios/service.js index 7c677d5d..370ec116 100644 --- a/Yi.Bbs.Vue3/src/config/axios/service.js +++ b/Yi.Bbs.Vue3/src/config/axios/service.js @@ -6,7 +6,7 @@ import { Session } from "@/utils/storage"; import useAuths from "@/hooks/useAuths"; const { VITE_APP_ENV_NAME } = import.meta.env; -const { getToken } = useAuths(); +const { getToken, removeToken } = useAuths(); const { base_url, request_timeout, pre_interface } = config; export const PATH_URL = base_url[VITE_APP_ENV_NAME]; @@ -69,6 +69,7 @@ service.interceptors.response.use( cancelButtonText: "取消", type: "warning", }).then(() => { + removeToken(); router.push("/login"); }); return; diff --git a/readme/1.png b/readme/1.png index 476268b4..901b0c1d 100644 Binary files a/readme/1.png and b/readme/1.png differ diff --git a/readme/1696760969217.jpg b/readme/1696760969217.jpg index fad52ebe..ebef5032 100644 Binary files a/readme/1696760969217.jpg and b/readme/1696760969217.jpg differ diff --git a/readme/1696761014270.jpg b/readme/1696761014270.jpg index 29e28e93..21b9db40 100644 Binary files a/readme/1696761014270.jpg and b/readme/1696761014270.jpg differ diff --git a/readme/2.png b/readme/2.png index 12a7c7ad..e3885a42 100644 Binary files a/readme/2.png and b/readme/2.png differ diff --git a/readme/3.png b/readme/3.png index 85ac88f2..60733fb2 100644 Binary files a/readme/3.png and b/readme/3.png differ diff --git a/readme/4.png b/readme/4.png index d7ac081f..1213c1e7 100644 Binary files a/readme/4.png and b/readme/4.png differ diff --git a/readme/5.png b/readme/5.png index ea25ace3..bdfea170 100644 Binary files a/readme/5.png and b/readme/5.png differ diff --git a/readme/6.png b/readme/6.png index c67669d6..481b493d 100644 Binary files a/readme/6.png and b/readme/6.png differ diff --git a/readme/7.png b/readme/7.png index 984c1297..3084d2c6 100644 Binary files a/readme/7.png and b/readme/7.png differ diff --git a/readme/8.png b/readme/8.png index 10788d56..3e602e31 100644 Binary files a/readme/8.png and b/readme/8.png differ diff --git a/readme/9.png b/readme/9.png index bb6b1df9..37bb1f9d 100644 Binary files a/readme/9.png and b/readme/9.png differ