Compare commits

..

1 Commits

Author SHA1 Message Date
橙子
eabbd55789 feat: 基础设施搭建 2024-10-14 00:29:55 +08:00
154 changed files with 11553 additions and 2218 deletions

1
.gitignore vendored
View File

@@ -269,7 +269,6 @@ dist
/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.Production.json /Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.Production.json
/Yi.Abp.Net8/test/Yi.Abp.Test/appsettings.Development.json /Yi.Abp.Net8/test/Yi.Abp.Test/appsettings.Development.json
/Yi.Abp.Net8/test/Yi.Abp.Test/appsettings.Production.json /Yi.Abp.Net8/test/Yi.Abp.Test/appsettings.Production.json
/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/appsettings.Development.json
database_backup database_backup
/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.Staging.json /Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.Staging.json
/Yi.Abp.Net8/src/Yi.Abp.Web/logs/ /Yi.Abp.Net8/src/Yi.Abp.Web/logs/

View File

@@ -80,6 +80,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AuditLogging.S
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AspNetCore.Authentication.OAuth", "framework\Yi.Framework.AspNetCore.Authentication.OAuth\Yi.Framework.AspNetCore.Authentication.OAuth.csproj", "{791AC2FA-50D3-4408-8D68-31DA72F608BE}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AspNetCore.Authentication.OAuth", "framework\Yi.Framework.AspNetCore.Authentication.OAuth\Yi.Framework.AspNetCore.Authentication.OAuth.csproj", "{791AC2FA-50D3-4408-8D68-31DA72F608BE}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{01300F0F-686E-47B3-821D-12424177867B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Web", "sample\Acme.BookStore.Web\Acme.BookStore.Web.csproj", "{576DBC97-4E5D-4444-B65C-F41649A5F8E0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Domain.Shared", "sample\Acme.BookStore.Domain.Shared\Acme.BookStore.Domain.Shared.csproj", "{D7F8BD42-F6A2-4F0A-9212-391B5185A99D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Domain", "sample\Acme.BookStore.Domain\Acme.BookStore.Domain.csproj", "{B615847F-8568-41D1-8B7E-63D61AE69F3D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Application.Contracts", "sample\Acme.BookStore.Application.Contracts\Acme.BookStore.Application.Contracts.csproj", "{20827DB5-5CDE-491A-82E8-3CAB82618C1E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Application", "sample\Acme.BookStore.Application\Acme.BookStore.Application.csproj", "{320273B6-7AE3-42DA-9675-D9AD4928A289}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.SqlSugarCore", "sample\Acme.BookStore.SqlSugarCore\Acme.BookStore.SqlSugarCore.csproj", "{70CCBD89-C0A1-4AC8-9AFA-C86C356DFDD7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Test", "test\Yi.Abp.Test\Yi.Abp.Test.csproj", "{68627BC2-F049-4C69-AD17-81DF9478E8CE}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Test", "test\Yi.Abp.Test\Yi.Abp.Test.csproj", "{68627BC2-F049-4C69-AD17-81DF9478E8CE}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tenant-management", "tenant-management", "{499A8C71-7892-42D0-A77E-48756E1EFF16}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tenant-management", "tenant-management", "{499A8C71-7892-42D0-A77E-48756E1EFF16}"
@@ -262,6 +276,30 @@ Global
{791AC2FA-50D3-4408-8D68-31DA72F608BE}.Debug|Any CPU.Build.0 = Debug|Any CPU {791AC2FA-50D3-4408-8D68-31DA72F608BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{791AC2FA-50D3-4408-8D68-31DA72F608BE}.Release|Any CPU.ActiveCfg = Release|Any CPU {791AC2FA-50D3-4408-8D68-31DA72F608BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{791AC2FA-50D3-4408-8D68-31DA72F608BE}.Release|Any CPU.Build.0 = Release|Any CPU {791AC2FA-50D3-4408-8D68-31DA72F608BE}.Release|Any CPU.Build.0 = Release|Any CPU
{576DBC97-4E5D-4444-B65C-F41649A5F8E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{576DBC97-4E5D-4444-B65C-F41649A5F8E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{576DBC97-4E5D-4444-B65C-F41649A5F8E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{576DBC97-4E5D-4444-B65C-F41649A5F8E0}.Release|Any CPU.Build.0 = Release|Any CPU
{D7F8BD42-F6A2-4F0A-9212-391B5185A99D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7F8BD42-F6A2-4F0A-9212-391B5185A99D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7F8BD42-F6A2-4F0A-9212-391B5185A99D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7F8BD42-F6A2-4F0A-9212-391B5185A99D}.Release|Any CPU.Build.0 = Release|Any CPU
{B615847F-8568-41D1-8B7E-63D61AE69F3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B615847F-8568-41D1-8B7E-63D61AE69F3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B615847F-8568-41D1-8B7E-63D61AE69F3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B615847F-8568-41D1-8B7E-63D61AE69F3D}.Release|Any CPU.Build.0 = Release|Any CPU
{20827DB5-5CDE-491A-82E8-3CAB82618C1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{20827DB5-5CDE-491A-82E8-3CAB82618C1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20827DB5-5CDE-491A-82E8-3CAB82618C1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{20827DB5-5CDE-491A-82E8-3CAB82618C1E}.Release|Any CPU.Build.0 = Release|Any CPU
{320273B6-7AE3-42DA-9675-D9AD4928A289}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{320273B6-7AE3-42DA-9675-D9AD4928A289}.Debug|Any CPU.Build.0 = Debug|Any CPU
{320273B6-7AE3-42DA-9675-D9AD4928A289}.Release|Any CPU.ActiveCfg = Release|Any CPU
{320273B6-7AE3-42DA-9675-D9AD4928A289}.Release|Any CPU.Build.0 = Release|Any CPU
{70CCBD89-C0A1-4AC8-9AFA-C86C356DFDD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{70CCBD89-C0A1-4AC8-9AFA-C86C356DFDD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{70CCBD89-C0A1-4AC8-9AFA-C86C356DFDD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{70CCBD89-C0A1-4AC8-9AFA-C86C356DFDD7}.Release|Any CPU.Build.0 = Release|Any CPU
{68627BC2-F049-4C69-AD17-81DF9478E8CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {68627BC2-F049-4C69-AD17-81DF9478E8CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{68627BC2-F049-4C69-AD17-81DF9478E8CE}.Debug|Any CPU.Build.0 = Debug|Any CPU {68627BC2-F049-4C69-AD17-81DF9478E8CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68627BC2-F049-4C69-AD17-81DF9478E8CE}.Release|Any CPU.ActiveCfg = Release|Any CPU {68627BC2-F049-4C69-AD17-81DF9478E8CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -423,6 +461,12 @@ Global
{73CCF2C4-B9FD-44AB-8D4B-0A421805B094} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853} {73CCF2C4-B9FD-44AB-8D4B-0A421805B094} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853}
{48806510-8E18-4E1E-9BAF-5B97E88C5FC3} = {73CCF2C4-B9FD-44AB-8D4B-0A421805B094} {48806510-8E18-4E1E-9BAF-5B97E88C5FC3} = {73CCF2C4-B9FD-44AB-8D4B-0A421805B094}
{791AC2FA-50D3-4408-8D68-31DA72F608BE} = {77B949E9-530E-45A5-9657-20F7D5C6875C} {791AC2FA-50D3-4408-8D68-31DA72F608BE} = {77B949E9-530E-45A5-9657-20F7D5C6875C}
{576DBC97-4E5D-4444-B65C-F41649A5F8E0} = {01300F0F-686E-47B3-821D-12424177867B}
{D7F8BD42-F6A2-4F0A-9212-391B5185A99D} = {01300F0F-686E-47B3-821D-12424177867B}
{B615847F-8568-41D1-8B7E-63D61AE69F3D} = {01300F0F-686E-47B3-821D-12424177867B}
{20827DB5-5CDE-491A-82E8-3CAB82618C1E} = {01300F0F-686E-47B3-821D-12424177867B}
{320273B6-7AE3-42DA-9675-D9AD4928A289} = {01300F0F-686E-47B3-821D-12424177867B}
{70CCBD89-C0A1-4AC8-9AFA-C86C356DFDD7} = {01300F0F-686E-47B3-821D-12424177867B}
{68627BC2-F049-4C69-AD17-81DF9478E8CE} = {0D10EEF2-FBAE-4C72-B816-A52823FC299B} {68627BC2-F049-4C69-AD17-81DF9478E8CE} = {0D10EEF2-FBAE-4C72-B816-A52823FC299B}
{499A8C71-7892-42D0-A77E-48756E1EFF16} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853} {499A8C71-7892-42D0-A77E-48756E1EFF16} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853}
{FA5BBAA1-08DC-472F-BB2C-5314E59D1556} = {499A8C71-7892-42D0-A77E-48756E1EFF16} {FA5BBAA1-08DC-472F-BB2C-5314E59D1556} = {499A8C71-7892-42D0-A77E-48756E1EFF16}

View File

@@ -1,37 +0,0 @@
using System.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Volo.Abp.AspNetCore.WebClientInfo;
namespace Yi.Framework.AspNetCore;
public class RealIpHttpContextWebClientInfoProvider : HttpContextWebClientInfoProvider
{
public RealIpHttpContextWebClientInfoProvider(ILogger<HttpContextWebClientInfoProvider> logger,
IHttpContextAccessor httpContextAccessor) : base(logger, httpContextAccessor)
{
}
protected override string? GetClientIpAddress()
{
try
{
var httpContext = HttpContextAccessor.HttpContext;
var headers = httpContext?.Request?.Headers;
if (headers != null && headers.ContainsKey("X-Forwarded-For"))
{
httpContext.Connection.RemoteIpAddress =
IPAddress.Parse(headers["X-Forwarded-For"].FirstOrDefault());
}
return httpContext?.Connection?.RemoteIpAddress?.ToString();
}
catch (Exception ex)
{
Logger.LogException(ex, LogLevel.Warning);
return null;
}
}
}

View File

@@ -11,7 +11,6 @@ using Newtonsoft.Json.Linq;
using Swashbuckle.AspNetCore.SwaggerGen; using Swashbuckle.AspNetCore.SwaggerGen;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.WebClientInfo;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Yi.Framework.AspNetCore.Mvc; using Yi.Framework.AspNetCore.Mvc;
@@ -23,11 +22,6 @@ namespace Yi.Framework.AspNetCore
)] )]
public class YiFrameworkAspNetCoreModule : AbpModule public class YiFrameworkAspNetCoreModule : AbpModule
{ {
public override void PostConfigureServices(ServiceConfigurationContext context)
{
var services = context.Services;
services.Replace(new ServiceDescriptor(typeof(IWebClientInfoProvider),
typeof(RealIpHttpContextWebClientInfoProvider), ServiceLifetime.Transient));
}
} }
} }

View File

@@ -1,27 +0,0 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Yi.Framework.Core.Json;
public class DatetimeJsonConverter : JsonConverter<DateTime>
{
private string _format;
public DatetimeJsonConverter(string format="yyyy-MM-dd HH:mm:ss")
{
_format = format;
}
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if(reader.TokenType==JsonTokenType.String)
{
if (DateTime.TryParse(reader.GetString(), out DateTime dateTime)) return dateTime;
}
return reader.GetDateTime();
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString(_format));
}
}

View File

@@ -16,7 +16,6 @@ public class AuditingStore : IAuditingStore, ITransientDependency
protected IUnitOfWorkManager UnitOfWorkManager { get; } protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected AbpAuditingOptions Options { get; } protected AbpAuditingOptions Options { get; }
protected IAuditLogInfoToAuditLogConverter Converter { get; } protected IAuditLogInfoToAuditLogConverter Converter { get; }
public AuditingStore( public AuditingStore(
IAuditLogRepository auditLogRepository, IAuditLogRepository auditLogRepository,
IUnitOfWorkManager unitOfWorkManager, IUnitOfWorkManager unitOfWorkManager,
@@ -53,10 +52,10 @@ public class AuditingStore : IAuditingStore, ITransientDependency
protected virtual async Task SaveLogAsync(AuditLogInfo auditInfo) protected virtual async Task SaveLogAsync(AuditLogInfo auditInfo)
{ {
Logger.LogDebug("Yi-请求追踪:" + JsonHelper.ObjToStr(auditInfo, "yyyy-MM-dd HH:mm:ss")); Logger.LogDebug("Yi-请求追踪:" + JsonHelper.ObjToStr(auditInfo, "yyyy-MM-dd HH:mm:ss"));
// using (var uow = UnitOfWorkManager.Begin(true,isTransactional:false)) using (var uow = UnitOfWorkManager.Begin(true))
// { {
await AuditLogRepository.InsertAsync(await Converter.ConvertAsync(auditInfo)); await AuditLogRepository.InsertAsync(await Converter.ConvertAsync(auditInfo));
// await uow.CompleteAsync(); await uow.CompleteAsync();
// } }
} }
} }

View File

@@ -22,7 +22,6 @@ public class AuditLogActionEntity : Entity<Guid>, IMultiTenant
public virtual string? MethodName { get; protected set; } public virtual string? MethodName { get; protected set; }
[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)]
public virtual string? Parameters { get; protected set; } public virtual string? Parameters { get; protected set; }
public virtual DateTime? ExecutionTime { get; protected set; } public virtual DateTime? ExecutionTime { get; protected set; }

View File

@@ -103,14 +103,12 @@ namespace Yi.Framework.AuditLogging.Domain.Entities
public virtual string? CorrelationId { get; set; } public virtual string? CorrelationId { get; set; }
[SugarColumn(Length = 2000)]
public virtual string? BrowserInfo { get; protected set; } public virtual string? BrowserInfo { get; protected set; }
public virtual string? HttpMethod { get; protected set; } public virtual string? HttpMethod { get; protected set; }
public virtual string? Url { get; protected set; } public virtual string? Url { get; protected set; }
[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)]
public virtual string? Exceptions { get; protected set; } public virtual string? Exceptions { get; protected set; }
public virtual string? Comments { get; protected set; } public virtual string? Comments { get; protected set; }

View File

@@ -4,9 +4,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus;
using Yi.Framework.Bbs.Domain.Shared.Caches; using Yi.Framework.Bbs.Domain.Shared.Caches;
using Yi.Framework.Bbs.Domain.Shared.Etos;
namespace Yi.Framework.Bbs.Application.Extensions; namespace Yi.Framework.Bbs.Application.Extensions;
@@ -16,29 +14,6 @@ namespace Yi.Framework.Bbs.Application.Extensions;
/// 需考虑一致性问题,又不能上锁影响性能 /// 需考虑一致性问题,又不能上锁影响性能
/// </summary> /// </summary>
public class AccessLogMiddleware : IMiddleware, ITransientDependency public class AccessLogMiddleware : IMiddleware, ITransientDependency
{
private static int _accessLogNumber = 0;
internal static void ResetAccessLogNumber()
{
_accessLogNumber = 0;
}
internal static int GetAccessLogNumber()
{
return _accessLogNumber;
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
await next(context);
Interlocked.Increment(ref _accessLogNumber);
}
}
public class AccessLogResetEventHandler : ILocalEventHandler<AccessLogResetArgs>,
ITransientDependency
{ {
/// <summary> /// <summary>
/// 缓存前缀 /// 缓存前缀
@@ -65,27 +40,12 @@ public class AccessLogResetEventHandler : ILocalEventHandler<AccessLogResetArgs>
} }
} }
//该事件由job定时10秒触发 public async Task InvokeAsync(HttpContext context, RequestDelegate next)
public async Task HandleEventAsync(AccessLogResetArgs eventData)
{ {
await next(context);
if (EnableRedisCache) if (EnableRedisCache)
{ {
//分布式锁 await RedisClient.IncrByAsync($"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date}", 1);
if (await RedisClient.SetNxAsync("AccessLogLock",true,TimeSpan.FromSeconds(5)))
{
//自增长数
var incrNumber= AccessLogMiddleware.GetAccessLogNumber();
//立即重置,开始计算,方式丢失
AccessLogMiddleware.ResetAccessLogNumber();
if (incrNumber>0)
{
await RedisClient.IncrByAsync(
$"{CacheKeyPrefix}{AccessLogCacheConst.Key}:{DateTime.Now.Date:yyyyMMdd}", incrNumber);
}
}
} }
} }
} }

View File

@@ -1,38 +0,0 @@
using FreeRedis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Quartz;
using Volo.Abp.BackgroundWorkers.Quartz;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.EventBus.Local;
using Yi.Framework.Bbs.Domain.Entities;
using Yi.Framework.Bbs.Domain.Shared.Caches;
using Yi.Framework.Bbs.Domain.Shared.Enums;
using Yi.Framework.Bbs.Domain.Shared.Etos;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.Bbs.Application.Jobs;
public class AccessLogCacheJob : QuartzBackgroundWorkerBase
{
private readonly ILocalEventBus _localEventBus;
public AccessLogCacheJob(ILocalEventBus localEventBus)
{
_localEventBus = localEventBus;
JobDetail = JobBuilder.Create<AccessLogCacheJob>().WithIdentity(nameof(AccessLogCacheJob))
.Build();
//每10秒执行一次将本地缓存转入redis防止丢数据
Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogCacheJob))
.WithSimpleSchedule((schedule) => { schedule.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever();; })
.Build();
}
public override async Task Execute(IJobExecutionContext context)
{
await _localEventBus.PublishAsync(new AccessLogResetArgs());
}
}

View File

@@ -62,7 +62,7 @@ public class AccessLogStoreJob : QuartzBackgroundWorkerBase
{ {
//当天的访问量 //当天的访问量
var number = var number =
await RedisClient.GetAsync<long>($"{CacheKeyPrefix}{AccessLogCacheConst.Key}:{DateTime.Now.Date:yyyyMMdd}"); await RedisClient.GetAsync<long>($"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date}");
var entity = await _repository._DbQueryable.Where(x => x.AccessLogType == AccessLogTypeEnum.Request) var entity = await _repository._DbQueryable.Where(x => x.AccessLogType == AccessLogTypeEnum.Request)
@@ -81,7 +81,7 @@ public class AccessLogStoreJob : QuartzBackgroundWorkerBase
} }
//删除前一天的缓存 //删除前一天的缓存
await RedisClient.DelAsync($"{CacheKeyPrefix}{AccessLogCacheConst.Key}:{DateTime.Now.Date.AddDays(-1):yyyyMMdd}"); await RedisClient.DelAsync($"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date.AddDays(-1)}");
} }
} }
} }

View File

@@ -16,7 +16,7 @@ namespace Yi.Framework.Bbs.Application.Services.Integral
/// <summary> /// <summary>
/// 大转盘 /// 大转盘
/// Todo: 可放入领域层,但是太简单了,不重要 /// Todo: 可放入领域层
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[Authorize] [Authorize]
@@ -33,6 +33,12 @@ namespace Yi.Framework.Bbs.Application.Services.Integral
var index = GetWheelIndex(); var index = GetWheelIndex();
var value = values[index] - 50; var value = values[index] - 50;
////不存在负数钱钱
//if (value < 0)
//{
// value = 0;
//}
//修改钱钱,如果钱钱不足,直接会丢出去,那本次抽奖将无效 //修改钱钱,如果钱钱不足,直接会丢出去,那本次抽奖将无效
await _localEventBus.PublishAsync(new MoneyChangeEventArgs { UserId = CurrentUser.Id!.Value, Number = value }, false); await _localEventBus.PublishAsync(new MoneyChangeEventArgs { UserId = CurrentUser.Id!.Value, Number = value }, false);
@@ -41,7 +47,7 @@ namespace Yi.Framework.Bbs.Application.Services.Integral
private int GetWheelIndex() private int GetWheelIndex()
{ {
int[] probabilities = {5 , 30, 40, 30, 20, 10, 4, 3, 2, 1 }; int[] probabilities = { 30, 40, 30, 15, 15, 10, 4, 3, 2, 1 };
int total = 0; int total = 0;
foreach (var prob in probabilities) foreach (var prob in probabilities)

View File

@@ -1,9 +0,0 @@
namespace Yi.Framework.Bbs.Domain.Shared.Enums;
public enum GoodsTypeEnum
{
/// <summary>
/// 申请类型
/// </summary>
Apply
}

View File

@@ -19,10 +19,5 @@ namespace Yi.Framework.Bbs.Domain.Shared.Enums
/// 广播 /// 广播
/// </summary> /// </summary>
Broadcast, Broadcast,
/// <summary>
/// 钱钱
/// </summary>
Money
} }
} }

View File

@@ -1,6 +0,0 @@
namespace Yi.Framework.Bbs.Domain.Shared.Etos;
public class AccessLogResetArgs
{
}

View File

@@ -16,13 +16,6 @@ namespace Yi.Framework.Bbs.Domain.Shared.Etos
Message = message; Message = message;
} }
public BbsNoticeEventArgs( NoticeTypeEnum noticeType, Guid acceptUserId, string message)
{
NoticeType = noticeType;
AcceptUserId = acceptUserId;
Message = message;
}
/// <summary> /// <summary>
/// 发送广播 /// 发送广播
/// </summary> /// </summary>

View File

@@ -31,7 +31,7 @@ namespace Yi.Framework.Bbs.Domain.Entities.Forum
public override Guid Id { get; protected set; } public override Guid Id { get; protected set; }
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }
[SugarColumn(Length = 2000)] [SugarColumn(Length = 500)]
public string Content { get; set; } public string Content { get; set; }
public Guid DiscussId { get; set; } public Guid DiscussId { get; set; }

View File

@@ -1,73 +0,0 @@
using SqlSugar;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Yi.Framework.Bbs.Domain.Shared.Enums;
namespace Yi.Framework.Bbs.Domain.Entities.Shop;
/// <summary>
/// 商品定义表
/// </summary>
[SugarTable("BbsGoods")]
public class BbsGoodsAggregateRoot: AggregateRoot<Guid>, IHasCreationTime
{
/// <summary>
/// 上架时间
/// </summary>
public DateTime CreationTime { get; set; }
/// <summary>
/// 商品类型
/// </summary>
public GoodsTypeEnum GoodsType{ get; set; }
/// <summary>
/// 下架时间
/// </summary>
public DateTime? EndTime { get; set; }
/// <summary>
/// 商品名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 每人限购数量
/// </summary>
public int LimitNumber { get; set; }
/// <summary>
/// 当前库存数量
/// </summary>
public int StockNumber { get; set; }
/// <summary>
/// 商品图片url
/// </summary>
public string ImageUrl { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Describe { get; set; }
/// <summary>
/// 编号
/// </summary>
public string Code { get; set; }
/// <summary>
/// 所需钱钱
/// </summary>
public decimal NeedMoney { get; set; }
/// <summary>
/// 所需价值
/// </summary>
public decimal NeedValue { get; set; }
/// <summary>
/// 所需积分
/// </summary>
public decimal NeedPoints { get; set; }
}

View File

@@ -1,32 +0,0 @@
using SqlSugar;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
namespace Yi.Framework.Bbs.Domain.Entities.Shop;
/// <summary>
/// 商品申请记录表
/// </summary>
[SugarTable("BbsGoodsApply")]
public class BbsGoodsApplyAggregateRoot: AggregateRoot<Guid>, IHasCreationTime
{
/// <summary>
/// 商品id
/// </summary>
public Guid GoodsId { get; set; }
/// <summary>
/// 申请时间
/// </summary>
public DateTime CreationTime { get; set; }
/// <summary>
/// 申请人用户id
/// </summary>
public Guid UserId { get; set; }
/// <summary>
/// 联系方式
/// </summary>
public string ContactInformation { get; set; }
}

View File

@@ -1,6 +0,0 @@
namespace Yi.Framework.Bbs.Domain.Entities.Shop.ValueObjects;
public class ShippingAddress
{
}

View File

@@ -25,40 +25,23 @@ namespace Yi.Framework.Bbs.Domain.EventHandlers
} }
public async Task HandleEventAsync(BbsNoticeEventArgs eventData) public async Task HandleEventAsync(BbsNoticeEventArgs eventData)
{ {
//离线存储
var entity= await _repository.InsertReturnEntityAsync(new BbsNoticeAggregateRoot(eventData.NoticeType, eventData.Message, eventData.AcceptUserId));
//是否需要离线存储 switch (eventData.NoticeType)
bool isStore = true;
var now = DateTime.Now;
switch (eventData.NoticeType)
{ {
case Shared.Enums.NoticeTypeEnum.Personal: case Shared.Enums.NoticeTypeEnum.Personal:
if (BbsNoticeHub.HubUserModels.TryGetValue(eventData.AcceptUserId.ToString(), out var hubUserModel)) if (BbsNoticeHub.HubUserModels.TryGetValue(eventData.AcceptUserId.ToString(), out var hubUserModel))
{ {
_hubContext.Clients.Client(hubUserModel.ConnnectionId).SendAsync(NoticeTypeEnum.Personal.ToString(), eventData.Message,now); _hubContext.Clients.Client(hubUserModel.ConnnectionId).SendAsync(NoticeTypeEnum.Personal.ToString(), eventData.Message,entity.CreationTime);
} }
break; break;
case Shared.Enums.NoticeTypeEnum.Broadcast: case Shared.Enums.NoticeTypeEnum.Broadcast:
_hubContext.Clients.All.SendAsync(NoticeTypeEnum.Broadcast.ToString(), eventData.Message); _hubContext.Clients.All.SendAsync(NoticeTypeEnum.Broadcast.ToString(), eventData.Message);
break; break;
case Shared.Enums.NoticeTypeEnum.Money:
if (BbsNoticeHub.HubUserModels.TryGetValue(eventData.AcceptUserId.ToString(), out var hubUserModel2))
{
_hubContext.Clients.Client(hubUserModel2.ConnnectionId).SendAsync(NoticeTypeEnum.Money.ToString(), eventData.Message,now);
}
isStore = false;
break;
default: default:
break; break;
} }
if (isStore)
{ //离线存储
var entity= await _repository.InsertReturnEntityAsync(new BbsNoticeAggregateRoot(eventData.NoticeType, eventData.Message, eventData.AcceptUserId){CreationTime = now});
}
} }
} }
} }

View File

@@ -1,10 +1,8 @@
using Volo.Abp; using Volo.Abp;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus; using Volo.Abp.EventBus;
using Volo.Abp.EventBus.Local;
using Yi.Framework.Bbs.Domain.Entities; using Yi.Framework.Bbs.Domain.Entities;
using Yi.Framework.Bbs.Domain.Shared.Consts; using Yi.Framework.Bbs.Domain.Shared.Consts;
using Yi.Framework.Bbs.Domain.Shared.Enums;
using Yi.Framework.Bbs.Domain.Shared.Etos; using Yi.Framework.Bbs.Domain.Shared.Etos;
using Yi.Framework.SqlSugarCore.Abstractions; using Yi.Framework.SqlSugarCore.Abstractions;
@@ -13,11 +11,9 @@ namespace Yi.Framework.Bbs.Domain.EventHandlers
public class MoneyChangeEventHandler : ILocalEventHandler<MoneyChangeEventArgs>, ITransientDependency public class MoneyChangeEventHandler : ILocalEventHandler<MoneyChangeEventArgs>, ITransientDependency
{ {
private ISqlSugarRepository<BbsUserExtraInfoEntity> _userInfoRepository; private ISqlSugarRepository<BbsUserExtraInfoEntity> _userInfoRepository;
private ILocalEventBus _localEventBus; public MoneyChangeEventHandler(ISqlSugarRepository<BbsUserExtraInfoEntity> userInfoRepository)
public MoneyChangeEventHandler(ISqlSugarRepository<BbsUserExtraInfoEntity> userInfoRepository, ILocalEventBus localEventBus)
{ {
_userInfoRepository = userInfoRepository; _userInfoRepository = userInfoRepository;
_localEventBus = localEventBus;
} }
public async Task HandleEventAsync(MoneyChangeEventArgs eventData) public async Task HandleEventAsync(MoneyChangeEventArgs eventData)
{ {
@@ -32,9 +28,6 @@ namespace Yi.Framework.Bbs.Domain.EventHandlers
await _userInfoRepository._Db.Updateable<BbsUserExtraInfoEntity>() await _userInfoRepository._Db.Updateable<BbsUserExtraInfoEntity>()
.SetColumns(it => it.Money == it.Money + eventData.Number) .SetColumns(it => it.Money == it.Money + eventData.Number)
.Where(x => x.UserId == eventData.UserId).ExecuteCommandAsync(); .Where(x => x.UserId == eventData.UserId).ExecuteCommandAsync();
await _localEventBus.PublishAsync(new BbsNoticeEventArgs(NoticeTypeEnum.Money, eventData.UserId,eventData.Number.ToString()), false);
} }
} }
} }

View File

@@ -1,11 +0,0 @@
using Volo.Abp.Domain.Services;
namespace Yi.Framework.Bbs.Domain.Managers;
/// <summary>
/// bbs商品领域
/// </summary>
public class BbsShopManager: DomainService
{
}

View File

@@ -4,7 +4,5 @@
{ {
public Guid Uuid { get; set; } = Guid.Empty; public Guid Uuid { get; set; } = Guid.Empty;
public byte[] Img { get; set; } public byte[] Img { get; set; }
public bool IsEnableCaptcha { get; set; }
} }
} }

View File

@@ -3,9 +3,5 @@
public class PhoneCaptchaImageDto public class PhoneCaptchaImageDto
{ {
public string Phone { get; set; } public string Phone { get; set; }
public string Uuid { get; set; }
public string Code { get; set; }
} }
} }

View File

@@ -5,7 +5,6 @@ namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Dictionary
/// </summary> /// </summary>
public class DictionaryCreateInputVo public class DictionaryCreateInputVo
{ {
public int OrderNum { get; set; }
public string? Remark { get; set; } public string? Remark { get; set; }
public string? ListClass { get; set; } public string? ListClass { get; set; }
public string? CssClass { get; set; } public string? CssClass { get; set; }

View File

@@ -4,7 +4,6 @@ namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Dictionary
{ {
public class DictionaryGetListOutputDto : EntityDto<Guid> public class DictionaryGetListOutputDto : EntityDto<Guid>
{ {
public int OrderNum { get; set; }
public DateTime CreationTime { get; set; } = DateTime.Now; public DateTime CreationTime { get; set; } = DateTime.Now;
public Guid? CreatorId { get; set; } public Guid? CreatorId { get; set; }
public string? Remark { get; set; } public string? Remark { get; set; }

View File

@@ -4,7 +4,6 @@ namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Dictionary
{ {
public class DictionaryGetOutputDto : EntityDto<Guid> public class DictionaryGetOutputDto : EntityDto<Guid>
{ {
public int OrderNum { get; set; }
public DateTime CreationTime { get; set; } = DateTime.Now; public DateTime CreationTime { get; set; } = DateTime.Now;
public Guid? CreatorId { get; set; } public Guid? CreatorId { get; set; }
public string? Remark { get; set; } public string? Remark { get; set; }

View File

@@ -2,7 +2,6 @@ namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Dictionary
{ {
public class DictionaryUpdateInputVo public class DictionaryUpdateInputVo
{ {
public int OrderNum { get; set; }
public string? Remark { get; set; } public string? Remark { get; set; }
public string? ListClass { get; set; } public string? ListClass { get; set; }
public string? CssClass { get; set; } public string? CssClass { get; set; }

View File

@@ -20,7 +20,7 @@ namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Menu
public string? Remark { get; set; } public string? Remark { get; set; }
public string? Component { get; set; } public string? Component { get; set; }
public string? Query { get; set; } public string? Query { get; set; }
public string? RouterName { get; set; }
public int OrderNum { get; set; } public int OrderNum { get; set; }
//public List<MenuEntity>? Children { get; set; } //public List<MenuEntity>? Children { get; set; }
} }

View File

@@ -24,8 +24,6 @@ namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Menu
public int OrderNum { get; set; } public int OrderNum { get; set; }
public string? RouterName { get; set; }
//public List<MenuEntity>? Children { get; set; } //public List<MenuEntity>? Children { get; set; }
} }
} }

View File

@@ -3,7 +3,6 @@ namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Post
public class PostUpdateInputVo public class PostUpdateInputVo
{ {
public bool? State { get; set; } public bool? State { get; set; }
public int OrderNum { get; set; }
public string PostCode { get; set; } public string PostCode { get; set; }
public string PostName { get; set; } public string PostName { get; set; }
public string? Remark { get; set; } public string? Remark { get; set; }

View File

@@ -82,12 +82,12 @@ namespace Yi.Framework.Rbac.Application.Services
/// 校验图片登录验证码,无需和账号绑定 /// 校验图片登录验证码,无需和账号绑定
/// </summary> /// </summary>
[AllowAnonymous] [AllowAnonymous]
private void ValidationImageCaptcha(string? uuid,string? code ) private void ValidationImageCaptcha(LoginInputVo input)
{ {
if (_rbacOptions.EnableCaptcha) if (_rbacOptions.EnableCaptcha)
{ {
//登录不想要验证码 ,可不校验 //登录不想要验证码 ,可不校验
if (!_captcha.Validate(uuid, code)) if (!_captcha.Validate(input.Uuid, input.Code))
{ {
throw new UserFriendlyException("验证码错误"); throw new UserFriendlyException("验证码错误");
} }
@@ -109,7 +109,7 @@ namespace Yi.Framework.Rbac.Application.Services
} }
//校验验证码 //校验验证码
ValidationImageCaptcha(input.Uuid,input.Code); ValidationImageCaptcha(input);
UserAggregateRoot user = new(); UserAggregateRoot user = new();
//校验 //校验
@@ -157,8 +157,7 @@ namespace Yi.Framework.Rbac.Application.Services
{ {
var uuid = _guidGenerator.Create(); var uuid = _guidGenerator.Create();
var captcha = _captcha.Generate(uuid.ToString()); var captcha = _captcha.Generate(uuid.ToString());
var enableCaptcha = _rbacOptions.EnableCaptcha; return new CaptchaImageDto { Img = captcha.Bytes, Uuid = uuid };
return new CaptchaImageDto { Img = captcha.Bytes, Uuid = uuid,IsEnableCaptcha= enableCaptcha };
} }
/// <summary> /// <summary>
@@ -199,15 +198,12 @@ namespace Yi.Framework.Rbac.Application.Services
} }
/// <summary> /// <summary>
/// 手机验证码-需通过图形验证码 /// 手机验证码
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private async Task<object> PostCaptchaPhoneAsync(ValidationPhoneTypeEnum validationPhoneType, private async Task<object> PostCaptchaPhoneAsync(ValidationPhoneTypeEnum validationPhoneType,
PhoneCaptchaImageDto input) PhoneCaptchaImageDto input)
{ {
//验证uuid 和 验证码
ValidationImageCaptcha(input.Uuid,input.Code);
await ValidationPhone(input.Phone); await ValidationPhone(input.Phone);
//注册的手机号验证,是不能已经注册过的 //注册的手机号验证,是不能已经注册过的

View File

@@ -6,6 +6,7 @@ using Yi.Framework.Ddd.Application;
using Yi.Framework.Rbac.Application.Contracts.Dtos.Dictionary; using Yi.Framework.Rbac.Application.Contracts.Dtos.Dictionary;
using Yi.Framework.Rbac.Application.Contracts.IServices; using Yi.Framework.Rbac.Application.Contracts.IServices;
using Yi.Framework.Rbac.Domain.Entities; using Yi.Framework.Rbac.Domain.Entities;
using Yi.Framework.Rbac.Domain.Shared.Consts;
using Yi.Framework.SqlSugarCore.Abstractions; using Yi.Framework.SqlSugarCore.Abstractions;
@@ -14,27 +15,29 @@ namespace Yi.Framework.Rbac.Application.Services
/// <summary> /// <summary>
/// Dictionary服务实现 /// Dictionary服务实现
/// </summary> /// </summary>
public class DictionaryService : YiCrudAppService<DictionaryEntity, DictionaryGetOutputDto, DictionaryGetListOutputDto, Guid, DictionaryGetListInputVo, DictionaryCreateInputVo, DictionaryUpdateInputVo>, public class DictionaryService : YiCrudAppService<DictionaryEntity, DictionaryGetOutputDto,
IDictionaryService DictionaryGetListOutputDto, Guid, DictionaryGetListInputVo, DictionaryCreateInputVo,
DictionaryUpdateInputVo>,
IDictionaryService
{ {
private ISqlSugarRepository<DictionaryEntity, Guid> _repository; private ISqlSugarRepository<DictionaryEntity, Guid> _repository;
public DictionaryService(ISqlSugarRepository<DictionaryEntity, Guid> repository) : base(repository) public DictionaryService(ISqlSugarRepository<DictionaryEntity, Guid> repository) : base(repository)
{ {
_repository= repository; _repository = repository;
} }
/// <summary> /// <summary>
/// 查询 /// 查询
/// </summary> /// </summary>
public override async Task<PagedResultDto<DictionaryGetListOutputDto>> GetListAsync(
public override async Task<PagedResultDto<DictionaryGetListOutputDto>> GetListAsync(DictionaryGetListInputVo input) DictionaryGetListInputVo input)
{ {
RefAsync<int> total = 0; RefAsync<int> total = 0;
var entities = await _repository._DbQueryable var entities = await _repository._DbQueryable
.WhereIF(input.DictType is not null, x => x.DictType == input.DictType) .WhereIF(input.DictType is not null, x => x.DictType == input.DictType)
.WhereIF(input.DictLabel is not null, x => x.DictLabel!.Contains(input.DictLabel!)) .WhereIF(input.DictLabel is not null, x => x.DictLabel!.Contains(input.DictLabel!))
.WhereIF(input.State is not null, x => x.State == input.State) .WhereIF(input.State is not null, x => x.State == input.State)
.OrderByDescending(x => x.OrderNum)
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total); .ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<DictionaryGetListOutputDto> return new PagedResultDto<DictionaryGetListOutputDto>
{ {

View File

@@ -20,12 +20,12 @@ namespace Yi.Framework.Rbac.Application.Services.RecordLog
public override async Task<PagedResultDto<LoginLogGetListOutputDto>> GetListAsync(LoginLogGetListInputVo input) public override async Task<PagedResultDto<LoginLogGetListOutputDto>> GetListAsync(LoginLogGetListInputVo input)
{ {
RefAsync<int> total = 0; RefAsync<int> total = 0;
//if (input.Sorting.IsNullOrWhiteSpace()) if (input.Sorting.IsNullOrWhiteSpace())
// input.Sorting = $"{nameof(LoginLogAggregateRoot.CreationTime)} Desc"; input.Sorting = $"{nameof(LoginLogAggregateRoot.CreationTime)} Desc";
var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.LoginIp), x => x.LoginIp.Contains(input.LoginIp!)) var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.LoginIp), x => x.LoginIp.Contains(input.LoginIp!))
.WhereIF(!string.IsNullOrEmpty(input.LoginUser), x => x.LoginUser!.Contains(input.LoginUser!)) .WhereIF(!string.IsNullOrEmpty(input.LoginUser), x => x.LoginUser!.Contains(input.LoginUser!))
.WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime) .WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
.OrderByDescending(it => it.CreationTime) //降序 .OrderBy(input.Sorting)
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total); .ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<LoginLogGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities)); return new PagedResultDto<LoginLogGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities));
} }

View File

@@ -24,12 +24,12 @@ namespace Yi.Framework.Rbac.Application.Services.RecordLog
public override async Task<PagedResultDto<OperationLogGetListOutputDto>> GetListAsync(OperationLogGetListInputVo input) public override async Task<PagedResultDto<OperationLogGetListOutputDto>> GetListAsync(OperationLogGetListInputVo input)
{ {
RefAsync<int> total = 0; RefAsync<int> total = 0;
//if (input.Sorting.IsNullOrWhiteSpace()) if (input.Sorting.IsNullOrWhiteSpace())
// input.Sorting = $"{nameof(OperationLogEntity.CreationTime)} Desc"; input.Sorting = $"{nameof(OperationLogEntity.CreationTime)} Desc";
var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.OperUser), x => x.OperUser.Contains(input.OperUser!)) var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.OperUser), x => x.OperUser.Contains(input.OperUser!))
.WhereIF(input.OperType is not null, x => x.OperType == input.OperType) .WhereIF(input.OperType is not null, x => x.OperType == input.OperType)
.WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime) .WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
.OrderByDescending(it => it.CreationTime) //降序 .OrderBy(input.Sorting)
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total); .ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<OperationLogGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities)); return new PagedResultDto<OperationLogGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities));
} }

View File

@@ -30,7 +30,6 @@ namespace Yi.Framework.Rbac.Application.Services.System
var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.PostName), var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.PostName),
x => x.PostName.Contains(input.PostName!)) x => x.PostName.Contains(input.PostName!))
.WhereIF(input.State is not null, x => x.State == input.State) .WhereIF(input.State is not null, x => x.State == input.State)
.OrderByDescending(x => x.OrderNum)
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total); .ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<PostGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities)); return new PagedResultDto<PostGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities));
} }

View File

@@ -1,5 +1,4 @@
using Lazy.Captcha.Core.Generator; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.BackgroundWorkers; using Volo.Abp.BackgroundWorkers;
using Volo.Abp.BackgroundWorkers.Quartz; using Volo.Abp.BackgroundWorkers.Quartz;
@@ -25,11 +24,7 @@ namespace Yi.Framework.Rbac.Application
{ {
var service = context.Services; var service = context.Services;
service.AddCaptcha(options => service.AddCaptcha();
{
options.CaptchaType = CaptchaType.ARITHMETIC;
});
} }
public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) public async override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)

View File

@@ -63,12 +63,12 @@ namespace Yi.Framework.Rbac.Domain.Entities
/// <summary> /// <summary>
/// 部门名称 /// 部门名称
///</summary> ///</summary>
public string DeptName { get; set; } public string DeptName { get; set; } = string.Empty;
/// <summary> /// <summary>
/// 部门编码 /// 部门编码
///</summary> ///</summary>
[SugarColumn(ColumnName = "DeptCode")] [SugarColumn(ColumnName = "DeptCode")]
public string DeptCode { get; set; } public string DeptCode { get; set; } = string.Empty;
/// <summary> /// <summary>
/// 负责人 /// 负责人
///</summary> ///</summary>

View File

@@ -41,7 +41,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot shenzhenDept = new DeptAggregateRoot(_guidGenerator.Create()) DeptAggregateRoot shenzhenDept = new DeptAggregateRoot(_guidGenerator.Create())
{ {
DeptCode = "SZ",
DeptName = "深圳总公司", DeptName = "深圳总公司",
OrderNum = 100, OrderNum = 100,
IsDeleted = false, IsDeleted = false,
@@ -52,7 +52,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot jiangxiDept = new DeptAggregateRoot(_guidGenerator.Create()) DeptAggregateRoot jiangxiDept = new DeptAggregateRoot(_guidGenerator.Create())
{ {
DeptCode = "JX",
DeptName = "江西总公司", DeptName = "江西总公司",
OrderNum = 100, OrderNum = 100,
IsDeleted = false, IsDeleted = false,
@@ -64,7 +64,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot szDept1 = new DeptAggregateRoot(_guidGenerator.Create()) DeptAggregateRoot szDept1 = new DeptAggregateRoot(_guidGenerator.Create())
{ {
DeptCode = "YF",
DeptName = "研发部门", DeptName = "研发部门",
OrderNum = 100, OrderNum = 100,
IsDeleted = false, IsDeleted = false,
@@ -74,7 +74,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot szDept2 = new DeptAggregateRoot(_guidGenerator.Create()) DeptAggregateRoot szDept2 = new DeptAggregateRoot(_guidGenerator.Create())
{ {
DeptCode = "SC",
DeptName = "市场部门", DeptName = "市场部门",
OrderNum = 100, OrderNum = 100,
IsDeleted = false, IsDeleted = false,
@@ -84,7 +84,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot szDept3 = new DeptAggregateRoot(_guidGenerator.Create()) DeptAggregateRoot szDept3 = new DeptAggregateRoot(_guidGenerator.Create())
{ {
DeptCode = "CS",
DeptName = "测试部门", DeptName = "测试部门",
OrderNum = 100, OrderNum = 100,
IsDeleted = false, IsDeleted = false,
@@ -94,7 +94,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot szDept4 = new DeptAggregateRoot(_guidGenerator.Create()) DeptAggregateRoot szDept4 = new DeptAggregateRoot(_guidGenerator.Create())
{ {
DeptCode = "CW",
DeptName = "财务部门", DeptName = "财务部门",
OrderNum = 100, OrderNum = 100,
IsDeleted = false, IsDeleted = false,
@@ -104,7 +104,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot szDept5 = new DeptAggregateRoot(_guidGenerator.Create()) DeptAggregateRoot szDept5 = new DeptAggregateRoot(_guidGenerator.Create())
{ {
DeptCode = "YW",
DeptName = "运维部门", DeptName = "运维部门",
OrderNum = 100, OrderNum = 100,
IsDeleted = false, IsDeleted = false,
@@ -115,7 +115,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot jxDept1 = new DeptAggregateRoot(_guidGenerator.Create()) DeptAggregateRoot jxDept1 = new DeptAggregateRoot(_guidGenerator.Create())
{ {
DeptCode = "SC",
DeptName = "市场部门", DeptName = "市场部门",
OrderNum = 100, OrderNum = 100,
IsDeleted = false, IsDeleted = false,
@@ -126,7 +126,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot jxDept2 = new DeptAggregateRoot(_guidGenerator.Create()) DeptAggregateRoot jxDept2 = new DeptAggregateRoot(_guidGenerator.Create())
{ {
DeptCode = "CW2",
DeptName = "财务部门", DeptName = "财务部门",
OrderNum = 100, OrderNum = 100,
IsDeleted = false, IsDeleted = false,

View File

@@ -19,7 +19,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
public async Task SeedAsync(DataSeedContext context) public async Task SeedAsync(DataSeedContext context)
{ {
if (!await _repository.IsAnyAsync(x => x.MenuName == "系统管理" && x.MenuSource == MenuSourceEnum.Pure)) if (!await _repository.IsAnyAsync(x => x.MenuName == "系统管理"&&x.MenuSource==MenuSourceEnum.Pure))
{ {
await _repository.InsertManyAsync(GetSeedData()); await _repository.InsertManyAsync(GetSeedData());
} }
@@ -141,7 +141,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
entities.Add(userRemove); entities.Add(userRemove);
MenuAggregateRoot userResetPwd = new MenuAggregateRoot(_guidGenerator.Create()) MenuAggregateRoot userResetPwd = new MenuAggregateRoot(_guidGenerator.Create())
{ {
MenuName = "重置密码", MenuName = "重置密码",
@@ -495,74 +495,6 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
}; };
entities.Add(loginLogRemove); entities.Add(loginLogRemove);
//参数设置
MenuAggregateRoot config = new MenuAggregateRoot(_guidGenerator.Create())
{
MenuName = "参数设置",
PermissionCode = "system:config:list",
MenuType = MenuTypeEnum.Menu,
Router = "config",
IsShow = true,
IsLink = false,
IsCache = true,
Component = "/system/config/index",
MenuIcon = "ri:edit-box-line",
OrderNum = 94,
ParentId = system.Id,
IsDeleted = false
};
entities.Add(config);
MenuAggregateRoot configQuery = new MenuAggregateRoot(_guidGenerator.Create())
{
MenuName = "参数查询",
PermissionCode = "system:config:query",
MenuType = MenuTypeEnum.Component,
OrderNum = 100,
ParentId = config.Id,
IsDeleted = false
};
entities.Add(configQuery);
MenuAggregateRoot configAdd = new MenuAggregateRoot(_guidGenerator.Create())
{
MenuName = "参数新增",
PermissionCode = "system:config:add",
MenuType = MenuTypeEnum.Component,
OrderNum = 100,
ParentId = config.Id,
IsDeleted = false
};
entities.Add(configAdd);
MenuAggregateRoot configEdit = new MenuAggregateRoot(_guidGenerator.Create())
{
MenuName = "参数修改",
PermissionCode = "system:config:edit",
MenuType = MenuTypeEnum.Component,
OrderNum = 100,
ParentId = config.Id,
IsDeleted = false
};
entities.Add(configEdit);
MenuAggregateRoot configRemove = new MenuAggregateRoot(_guidGenerator.Create())
{
MenuName = "参数删除",
PermissionCode = "system:config:remove",
MenuType = MenuTypeEnum.Component,
OrderNum = 100,
ParentId = config.Id,
IsDeleted = false
};
entities.Add(configRemove);
//默认值 //默认值
entities.ForEach(m => entities.ForEach(m =>
{ {

View File

@@ -228,21 +228,6 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
}; };
entities.Add(swagger); entities.Add(swagger);
//表单构建
MenuAggregateRoot builder = new MenuAggregateRoot(_guidGenerator.Create(), tool.Id)
{
MenuName = "表单生成器",
MenuType = MenuTypeEnum.Menu,
Router = "build",
IsShow = true,
IsLink = false,
MenuIcon = "form",
Component = "tool/build/index",
IsCache = true,
OrderNum = 101,
IsDeleted = false,
};
entities.Add(builder);
// //ERP // //ERP
// MenuAggregateRoot erp = new MenuAggregateRoot(_guidGenerator.Create()) // MenuAggregateRoot erp = new MenuAggregateRoot(_guidGenerator.Create())

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.TenantManagement.Domain.Shared
{
public class TenantConst
{
public static string TenantDbDefaultName = "Master";
}
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.TenantManagement.Domain.Shared" Version="8.0.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,11 @@
using Volo.Abp.Modularity;
using Volo.Abp.TenantManagement;
namespace YiFrameworkTenantManagementDomain.Shared
{
[DependsOn(typeof(AbpTenantManagementDomainSharedModule))]
public class YiFrameworkTenantManagementDomainSharedModule : AbpModule
{
}
}

View File

@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<ItemGroup>
<ProjectReference Include="..\..\framework\Yi.Framework.Ddd.Application.Contracts\Yi.Framework.Ddd.Application.Contracts.csproj" />
<ProjectReference Include="..\..\module\bbs\Yi.Framework.Bbs.Application.Contracts\Yi.Framework.Bbs.Application.Contracts.csproj" />
<ProjectReference Include="..\..\module\rbac\Yi.Framework.Rbac.Application.Contracts\Yi.Framework.Rbac.Application.Contracts.csproj" />
<ProjectReference Include="..\Acme.BookStore.Domain.Shared\Acme.BookStore.Domain.Shared.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
using Acme.BookStore.Domain.Shared.Enums;
namespace Acme.BookStore.Application.Contracts.Dtos.Book
{
public class BookCreateUpdateDto
{
[Required]
[StringLength(128)]
public string Name { get; set; }
[Required]
public BookTypeEnum Type { get; set; } = BookTypeEnum.Undefined;
[Required]
[DataType(DataType.Date)]
public DateTime PublishDate { get; set; } = DateTime.Now;
[Required]
public float Price { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using Acme.BookStore.Domain.Shared.Enums;
using Volo.Abp.Application.Dtos;
namespace Acme.BookStore.Application.Contracts.Dtos.Book
{
public class BookDto : AuditedEntityDto<Guid>
{
public string Name { get; set; }
public BookTypeEnum Type { get; set; }
public DateTime PublishDate { get; set; }
public float Price { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using Acme.BookStore.Application.Contracts.Dtos.Book;
using Volo.Abp.Application.Dtos;
using Yi.Framework.Ddd.Application.Contracts;
namespace Acme.BookStore.Application.Contracts.IServices
{
public interface IBookAppService :
IYiCrudAppService< //Defines CRUD methods
BookDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting
BookCreateUpdateDto> //Used to create/update a book
{
}
}

View File

@@ -0,0 +1,20 @@
using Volo.Abp.Modularity;
using Acme.BookStore.Domain.Shared;
using Yi.Framework.Bbs.Application.Contracts;
using Yi.Framework.Ddd.Application.Contracts;
using Yi.Framework.Rbac.Application.Contracts;
namespace Acme.BookStore.Application.Contracts
{
[DependsOn(
typeof(YiAbpDomainSharedModule),
typeof(YiFrameworkRbacApplicationContractsModule),
typeof(YiFrameworkBbsApplicationContractsModule),
typeof(YiFrameworkDddApplicationContractsModule))]
public class YiAbpApplicationContractsModule:AbpModule
{
}
}

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<ItemGroup>
<ProjectReference Include="..\..\framework\Yi.Framework.Ddd.Application\Yi.Framework.Ddd.Application.csproj" />
<ProjectReference Include="..\..\module\bbs\Yi.Framework.Bbs.Application\Yi.Framework.Bbs.Application.csproj" />
<ProjectReference Include="..\..\module\rbac\Yi.Framework.Rbac.Application\Yi.Framework.Rbac.Application.csproj" />
<ProjectReference Include="..\Acme.BookStore.Application.Contracts\Acme.BookStore.Application.Contracts.csproj" />
<ProjectReference Include="..\Acme.BookStore.Domain\Acme.BookStore.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Jobs\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,36 @@
using Quartz;
using SqlSugar;
using Volo.Abp.BackgroundWorkers.Quartz;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;
using Yi.Framework.Rbac.Domain.Entities;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Acme.BookStore.Application.Jobs
{
/// <summary>
/// 定时任务
/// </summary>
public class TestJob : QuartzBackgroundWorkerBase
{
private ISqlSugarRepository<UserAggregateRoot> _repository;
public TestJob(ISqlSugarRepository<UserAggregateRoot> repository)
{
_repository = repository;
JobDetail = JobBuilder.Create<TestJob>().WithIdentity(nameof(TestJob)).Build();
Trigger = TriggerBuilder.Create().WithIdentity(nameof(TestJob)).StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(1000 * 60)
.RepeatForever())
.Build();
}
public override async Task Execute(IJobExecutionContext context)
{
//定时任务,非常简单
Console.WriteLine("你好,世界");
// var eneities= await _repository.GetListAsync();
//var entities= await _sqlSugarClient.Queryable<UserEntity>().ToListAsync();
//await Console.Out.WriteLineAsync(entities.Count().ToString());
}
}
}

View File

@@ -0,0 +1,42 @@
using Acme.BookStore.Application.Contracts.Dtos.Book;
using Acme.BookStore.Application.Contracts.IServices;
using Acme.BookStore.Domain.Entities;
using SqlSugar;
using Volo.Abp.Application.Dtos;
using Yi.Framework.Ddd.Application;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Acme.BookStore.Application.Services
{
public class BookAppService :
YiCrudAppService<
BookAggregateRoot, //The Book entity
BookDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting
BookCreateUpdateDto>, //Used to create/update a book
IBookAppService //implement the IBookAppService
{
private ISqlSugarRepository<BookAggregateRoot, Guid> _repository;
public BookAppService(ISqlSugarRepository<BookAggregateRoot, Guid> repository)
: base(repository)
{
_repository = repository;
}
public override async Task<PagedResultDto<BookDto>> GetListAsync(PagedAndSortedResultRequestDto input)
{
{
RefAsync<int> total = 0;
//由于直接查询接口基本上都是有包含查询条件的,默认内置的查询接口将无法满足业务的需求,所以基本上多查询都是有进行重写的
var entities = await _repository._DbQueryable
//.WhereIF(!string.IsNullOrEmpty(input.ConfigKey), x => x.ConfigKey.Contains(input.ConfigKey!))
// .WhereIF(!string.IsNullOrEmpty(input.ConfigName), x => x.ConfigName!.Contains(input.ConfigName!))
// .WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<BookDto>(total, await MapToGetListOutputDtosAsync(entities));
}
}
}
}

View File

@@ -0,0 +1,18 @@
using Volo.Abp.Application.Services;
using Volo.Abp.DependencyInjection;
namespace Acme.BookStore.Application.Services
{
public class TestService : ApplicationService
{
/// <summary>
/// 你好世界
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public string GetHelloWorld(string? name)
{
return name ?? "HelloWord";
}
}
}

View File

@@ -0,0 +1,23 @@
using Volo.Abp.Modularity;
using Acme.BookStore.Application.Contracts;
using Acme.BookStore.Domain;
using Yi.Framework.Bbs.Application;
using Yi.Framework.Ddd.Application;
using Yi.Framework.Rbac.Application;
namespace Acme.BookStore.Application
{
[DependsOn(
typeof(YiAbpApplicationContractsModule),
typeof(YiAbpDomainModule),
typeof(YiFrameworkRbacApplicationModule),
typeof(YiFrameworkBbsApplicationModule),
typeof(YiFrameworkDddApplicationModule)
)]
public class YiAbpApplicationModule : AbpModule
{
}
}

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Domain.Shared" Version="$(AbpVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\module\bbs\Yi.Framework.Bbs.Domain.Shared\Yi.Framework.Bbs.Domain.Shared.csproj" />
<ProjectReference Include="..\..\module\rbac\Yi.Framework.Rbac.Domain.Shared\Yi.Framework.Rbac.Domain.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Consts\" />
<Folder Include="Dtos\" />
<Folder Include="Etos\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Acme.BookStore.Domain.Shared.Enums
{
public enum BookTypeEnum
{
Undefined,
Adventure,
Biography,
Dystopia,
Fantastic,
Horror,
Science,
ScienceFiction,
Poetry
}
}

View File

@@ -0,0 +1,17 @@
using Volo.Abp.Domain;
using Volo.Abp.Modularity;
using Yi.Framework.Bbs.Domain.Shared;
using Yi.Framework.Rbac.Domain.Shared;
namespace Acme.BookStore.Domain.Shared
{
[DependsOn(
typeof(YiFrameworkRbacDomainSharedModule),
typeof(YiFrameworkBbsDomainSharedModule),
typeof(AbpDddDomainSharedModule))]
public class YiAbpDomainSharedModule : AbpModule
{
}
}

View File

@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="$(AbpVersion)" />
<PackageReference Include="Volo.Abp.Caching" Version="$(AbpVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\framework\Yi.Framework.Mapster\Yi.Framework.Mapster.csproj" />
<ProjectReference Include="..\..\framework\Yi.Framework.SqlSugarCore.Abstractions\Yi.Framework.SqlSugarCore.Abstractions.csproj" />
<ProjectReference Include="..\..\module\bbs\Yi.Framework.Bbs.Domain\Yi.Framework.Bbs.Domain.csproj" />
<ProjectReference Include="..\..\module\rbac\Yi.Framework.Rbac.Domain\Yi.Framework.Rbac.Domain.csproj" />
<ProjectReference Include="..\Acme.BookStore.Domain.Shared\Acme.BookStore.Domain.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Managers\" />
<Folder Include="Repositories\" />
<Folder Include="EventHandlers\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
using Acme.BookStore.Domain.Shared.Enums;
using SqlSugar;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities.Auditing;
namespace Acme.BookStore.Domain.Entities
{
[SugarTable("Book")]
public class BookAggregateRoot : AuditedAggregateRoot<Guid>
{
[SugarColumn(IsPrimaryKey = true)]
public override Guid Id { get; protected set; }
public string Name { get; set; }
public BookTypeEnum Type { get; set; }
public DateTime PublishDate { get; set; }
public float Price { get; set; }
[SugarColumn(IsIgnore = true)]
public override ExtraPropertyDictionary ExtraProperties { get; protected set; }
}
}

View File

@@ -0,0 +1,26 @@
using Volo.Abp.Caching;
using Volo.Abp.Domain;
using Volo.Abp.Modularity;
using Acme.BookStore.Domain.Shared;
using Yi.Framework.Bbs.Domain;
using Yi.Framework.Mapster;
using Yi.Framework.Rbac.Domain;
namespace Acme.BookStore.Domain
{
[DependsOn(
typeof(YiAbpDomainSharedModule),
typeof(YiFrameworkRbacDomainModule),
typeof(YiFrameworkBbsDomainModule),
typeof(YiFrameworkMapsterModule),
typeof(AbpDddDomainModule),
typeof(AbpCachingModule)
)]
public class YiAbpDomainModule : AbpModule
{
}
}

View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<ItemGroup>
<ProjectReference Include="..\..\framework\Yi.Framework.Mapster\Yi.Framework.Mapster.csproj" />
<ProjectReference Include="..\..\framework\Yi.Framework.SqlSugarCore\Yi.Framework.SqlSugarCore.csproj" />
<ProjectReference Include="..\..\module\bbs\Yi.Framework.Bbs.SqlSugarCore\Yi.Framework.Bbs.SqlSugarCore.csproj" />
<ProjectReference Include="..\..\module\rbac\Yi.Framework.Rbac.SqlSugarCore\Yi.Framework.Rbac.SqlSugarCore.csproj" />
<ProjectReference Include="..\Acme.BookStore.Domain\Acme.BookStore.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Repositories\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,50 @@
using Acme.BookStore.Domain.Entities;
using Acme.BookStore.Domain.Shared.Enums;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Acme.BookStore.SqlSugarCore.DataSeeds
{
public class BookStoreDataSeed : IDataSeedContributor, ITransientDependency
{
private ISqlSugarRepository<BookAggregateRoot> _bookRepository;
private IGuidGenerator _guidGenerator;
public BookStoreDataSeed(ISqlSugarRepository<BookAggregateRoot> repository, IGuidGenerator guidGenerator)
{
_bookRepository = repository;
_guidGenerator = guidGenerator;
}
public async Task SeedAsync(DataSeedContext context)
{
if (!await _bookRepository.IsAnyAsync(x => true))
{
await _bookRepository.InsertAsync(
new BookAggregateRoot
{
Name = "1984",
Type = BookTypeEnum.Dystopia,
PublishDate = new DateTime(1949, 6, 8),
Price = 19.84f
},
autoSave: true
);
await _bookRepository.InsertAsync(
new BookAggregateRoot
{
Name = "The Hitchhiker's Guide to the Galaxy",
Type = BookTypeEnum.ScienceFiction,
PublishDate = new DateTime(1995, 9, 27),
Price = 42.0f
},
autoSave: true
);
}
}
}
}

View File

@@ -0,0 +1,31 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
using Acme.BookStore.Domain;
using Acme.BookStore.SqlSugarCore;
using Yi.Framework.Bbs.SqlSugarCore;
using Yi.Framework.Mapster;
using Yi.Framework.Rbac.SqlSugarCore;
using Yi.Framework.SqlSugarCore;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Acme.BookStore.SqlsugarCore
{
[DependsOn(
typeof(YiAbpDomainModule),
typeof(YiFrameworkRbacSqlSugarCoreModule),
typeof(YiFrameworkBbsSqlSugarCoreModule),
typeof(YiFrameworkMapsterModule),
typeof(YiFrameworkSqlSugarCoreModule)
)]
public class YiAbpSqlSugarCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddYiDbContext<YiDbContext>();
//默认不开放可根据项目需要是否Db直接对外开放
//context.Services.AddTransient(x => x.GetRequiredService<ISqlSugarDbContext>().SqlSugarClient);
}
}
}

View File

@@ -0,0 +1,14 @@
using Microsoft.Extensions.Logging;
using SqlSugar;
using Volo.Abp.DependencyInjection;
using Yi.Framework.Rbac.SqlSugarCore;
namespace Acme.BookStore.SqlSugarCore
{
public class YiDbContext : YiRbacDbContext
{
public YiDbContext(IAbpLazyServiceProvider lazyServiceProvider) : base(lazyServiceProvider)
{
}
}
}

View File

@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="..\..\common.props" />
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.3" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.3" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="$(AbpVersion)" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="$(AbpVersion)" />
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="$(AbpVersion)" />
<PackageReference Include="Volo.Abp.Autofac" Version="$(AbpVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\framework\Yi.Framework.AspNetCore.Authentication.OAuth\Yi.Framework.AspNetCore.Authentication.OAuth.csproj" />
<ProjectReference Include="..\..\framework\Yi.Framework.AspNetCore\Yi.Framework.AspNetCore.csproj" />
<ProjectReference Include="..\Acme.BookStore.Application\Acme.BookStore.Application.csproj" />
<ProjectReference Include="..\Acme.BookStore.SqlSugarCore\Acme.BookStore.SqlSugarCore.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\icon\**">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Update="ip2region.db">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="database_backup\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,37 @@
using Serilog;
using Serilog.Events;
using Acme.BookStore.Web;
//创建日志,可使用{SourceContext}记录
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.MinimumLevel.Override("Microsoft.AspNetCore.Hosting.Diagnostics", LogEventLevel.Error)
.MinimumLevel.Override("Quartz", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Async(c => c.File("logs/all/log-.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Debug))
.WriteTo.Async(c => c.File("logs/error/errorlog-.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Error))
.WriteTo.Async(c => c.Console(restrictedToMinimumLevel: LogEventLevel.Information))
.CreateLogger();
try
{
Log.Information("Yi框架-Abp.vNext启动");
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseUrls(builder.Configuration["App:SelfUrl"]);
builder.Host.UseAutofac();
builder.Host.UseSerilog();
await builder.Services.AddApplicationAsync<YiAbpWebModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
await app.RunAsync();
}
catch (Exception ex)
{
Log.Fatal(ex, "Yi框架-Abp.vNext爆炸");
}
finally
{
Log.CloseAndFlush();
}

View File

@@ -0,0 +1,15 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"Acme.BookStore.Web": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:19001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,198 @@
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;
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Auditing;
using Volo.Abp.Autofac;
using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;
using Acme.BookStore.Application;
using Acme.BookStore.SqlsugarCore;
using Yi.Framework.AspNetCore;
using Yi.Framework.AspNetCore.Authentication.OAuth;
using Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
using Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
using Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
using Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection;
using Yi.Framework.Bbs.Application;
using Yi.Framework.Rbac.Application;
using Yi.Framework.Rbac.Domain.Shared.Options;
namespace Acme.BookStore.Web
{
[DependsOn(
typeof(YiAbpSqlSugarCoreModule),
typeof(YiAbpApplicationModule),
typeof(AbpAspNetCoreMvcModule),
typeof(AbpAutofacModule),
typeof(AbpSwashbuckleModule),
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpAuditingModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(YiFrameworkAspNetCoreModule),
typeof(YiFrameworkAspNetCoreAuthenticationOAuthModule)
)]
public class YiAbpWebModule : AbpModule
{
private const string DefaultCorsPolicyName = "Default";
public override Task ConfigureServicesAsync(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
var host = context.Services.GetHostingEnvironment();
var service = context.Services;
//请求日志
Configure<AbpAuditingOptions>(optios =>
{
optios.IsEnabled = true;
optios.AlwaysLogSelectors.Add(x => Task.FromResult(true));
});
//动态Api
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(YiAbpApplicationModule).Assembly, options => options.RemoteServiceName = "default");
options.ConventionalControllers.Create(typeof(YiFrameworkRbacApplicationModule).Assembly, options => options.RemoteServiceName = "rbac");
options.ConventionalControllers.Create(typeof(YiFrameworkBbsApplicationModule).Assembly, options => options.RemoteServiceName = "bbs");
});
//设置api格式
service.AddControllers().AddNewtonsoftJson(options =>
{
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
options.SerializerSettings.Converters.Add(new StringEnumConverter());
});
Configure<AbpAntiForgeryOptions>(options =>
{
options.AutoValidate = false;
});
//Swagger
context.Services.AddYiSwaggerGen<YiAbpWebModule>(options =>
{
options.SwaggerDoc("default", new OpenApiInfo { Title = "Yi.Framework.Abp", Version = "v1", Description = "集大成者" });
});
//跨域
context.Services.AddCors(options =>
{
options.AddPolicy(DefaultCorsPolicyName, builder =>
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]!
.Split(";", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray()
)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
//jwt鉴权
var jwtOptions = configuration.GetSection(nameof(JwtOptions)).Get<JwtOptions>();
context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ClockSkew = TimeSpan.Zero,
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtOptions.Issuer,
ValidAudience = jwtOptions.Audience,
RequireExpirationTime = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.SecurityKey))
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
})
.AddQQ(options =>
{
configuration.GetSection("OAuth:QQ").Bind(options);
})
.AddGitee(options =>
{
configuration.GetSection("OAuth:Gitee").Bind(options);
});
//授权
context.Services.AddAuthorization();
return Task.CompletedTask;
}
public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{
var service = context.ServiceProvider;
var env = context.GetEnvironment();
var app = context.GetApplicationBuilder();
app.UseRouting();
//跨域
app.UseCors(DefaultCorsPolicyName);
//鉴权
app.UseAuthentication();
//swagger
app.UseYiSwagger();
//请求处理
app.UseYiApiHandlinge();
//静态资源
app.UseStaticFiles("/api/app/wwwroot");
app.UseDefaultFiles();
app.UseDirectoryBrowser("/api/app/wwwroot");
//工作单元
app.UseUnitOfWork();
//授权
app.UseAuthorization();
//审计日志
app.UseAuditing();
//日志记录
app.UseAbpSerilogEnrichers();
//终节点
app.UseConfiguredEndpoints();
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,73 @@
{
"Logging": {
"LogLevel": {
//"Default": "Information",
"Default": "Debug",
"Microsoft.AspNetCore": "Warning"
}
},
//应用启动
"App": {
"SelfUrl": "http://*:19001",
"CorsOrigins": "http://localhost:19001;http://localhost:18000"
},
//数据库类型列表
"DbList": [ "Sqlite", "Mysql", "Sqlserver", "Oracle", "PostgreSQL" ],
"DbConnOptions": {
"Url": "DataSource=yi-abp-dev.db",
"DbType": "Sqlite",
"EnabledReadWrite": false,
"EnabledCodeFirst": true,
"EnabledSqlLog": true,
"EnabledDbSeed": true,
"EnableUnderLine": false // 启用驼峰转下划线
//读写分离地址
//"ReadUrl": [
// "DataSource=[xxxx]", //Sqlite
// "server=[xxxx];port=3306;database=[xxxx];user id=[xxxx];password=[xxxx]", //Mysql
// "Data Source=[xxxx];Initial Catalog=[xxxx];User ID=[xxxx];password=[xxxx]" //Sqlserver
// "HOST=[xxxx];PORT=5432;DATABASE=[xxxx];USERID=[xxxx];PASSWORD=[xxxx]" //PostgreSQL
//]
},
//鉴权
"JwtOptions": {
"Issuer": "https://ccnetcore.com",
"Audience": "https://ccnetcore.com",
"SecurityKey": "zqxwcevrbtnymu312412ihe9rfwhe78rh23djoi32hrui3ryf9e8wfh34iuj54y0934uti4h97fgw7hf97wyh8yy69520",
"ExpiresMinuteTime": 86400
},
//第三方登录
"OAuth": {
//QQ
"QQ": {
"ClientId": "",
"ClientSecret": "",
"RedirectUri": ""
},
//码云
"Gitee": {
"ClientId": "",
"ClientSecret": "",
"RedirectUri": ""
}
},
//Rbac模块
"RbacOptions": {
//超级管理员种子数据默认密码
"AdminPassword": "123456",
//是否开启验证码验证
"EnableCaptcha": true,
//是否开启注册功能
"EnableRegister": false,
//开启定时数据库备份
"EnableDataBaseBackup": false
}
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@@ -1,14 +1,10 @@
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using System.Threading.RateLimiting; using System.Threading.RateLimiting;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
@@ -22,8 +18,6 @@ using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.Json;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.Swashbuckle; using Volo.Abp.Swashbuckle;
using Yi.Abp.Application; using Yi.Abp.Application;
@@ -39,7 +33,6 @@ using Yi.Framework.Bbs.Application;
using Yi.Framework.Bbs.Application.Extensions; using Yi.Framework.Bbs.Application.Extensions;
using Yi.Framework.ChatHub.Application; using Yi.Framework.ChatHub.Application;
using Yi.Framework.CodeGen.Application; using Yi.Framework.CodeGen.Application;
using Yi.Framework.Core.Json;
using Yi.Framework.Rbac.Application; using Yi.Framework.Rbac.Application;
using Yi.Framework.Rbac.Domain.Authorization; using Yi.Framework.Rbac.Domain.Authorization;
using Yi.Framework.Rbac.Domain.Shared.Consts; using Yi.Framework.Rbac.Domain.Shared.Consts;
@@ -74,9 +67,9 @@ namespace Yi.Abp.Web
Configure<AbpAuditingOptions>(optios => Configure<AbpAuditingOptions>(optios =>
{ {
//默认关闭,开启会有大量的审计日志 //默认关闭,开启会有大量的审计日志
optios.IsEnabled = true; optios.IsEnabled = false;
//审计日志过滤器 //审计日志过滤器
optios.AlwaysLogSelectors.Add(x => Task.FromResult(!x.Url.StartsWith("/api/app/file/"))); optios.AlwaysLogSelectors.Add(x => Task.FromResult(true));
}); });
//采用furion格式的规范化api默认不开启使用abp优雅的方式 //采用furion格式的规范化api默认不开启使用abp优雅的方式
@@ -106,19 +99,11 @@ namespace Yi.Abp.Web
options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app"); options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app");
}); });
//【NewtonsoftJson严重问题逆天】设置api格式留给后人铭记 //设置api格式
// service.AddControllers().AddNewtonsoftJson(options => service.AddControllers().AddNewtonsoftJson(options =>
// {
// options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
// options.SerializerSettings.Converters.Add(new StringEnumConverter());
// });
//请使用微软的注意abp date又包了一层采用DefaultJsonTypeInfoResolver统一覆盖
Configure<JsonOptions>(options =>
{ {
options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver(); options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter()); options.SerializerSettings.Converters.Add(new StringEnumConverter());
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
}); });
//设置缓存不要过期默认滑动20分钟 //设置缓存不要过期默认滑动20分钟
@@ -283,6 +268,7 @@ namespace Yi.Abp.Web
public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{ {
var service = context.ServiceProvider; var service = context.ServiceProvider;
var env = context.GetEnvironment(); var env = context.GetEnvironment();
var app = context.GetApplicationBuilder(); var app = context.GetApplicationBuilder();

View File

@@ -14,10 +14,6 @@ namespace Yi.Abp.Tool.Application.Contracts.Dtos
/// </summary> /// </summary>
public string Name { get; set; } public string Name { get; set; }
/// <summary>
/// 模块类型
/// </summary>
public string ModuleSoure { get; set; }
/// <summary> /// <summary>
/// 数据库提供者 /// 数据库提供者

View File

@@ -7,6 +7,6 @@ namespace Yi.Abp.Tool.Application.Contracts
public interface ITemplateGenService: IApplicationService public interface ITemplateGenService: IApplicationService
{ {
Task<byte[]> CreateModuleAsync(TemplateGenCreateInputDto moduleCreateInputDto); Task<byte[]> CreateModuleAsync(TemplateGenCreateInputDto moduleCreateInputDto);
Task<List<string>> GetAllTemplatesAsync(); Task<byte[]> CreateProjectAsync(TemplateGenCreateInputDto moduleCreateInputDto);
} }
} }

View File

@@ -16,14 +16,10 @@ using Yi.Framework.Core.Helper;
namespace Yi.Abp.Tool.Application namespace Yi.Abp.Tool.Application
{ {
public class TemplateGenService : ApplicationService, ITemplateGenService public class TemplateGenService : ApplicationService,ITemplateGenService
{ {
private readonly TemplateGenManager _templateGenManager; private readonly TemplateGenManager _templateGenManager;
public TemplateGenService(TemplateGenManager templateGenManager) { _templateGenManager = templateGenManager; }
public TemplateGenService(TemplateGenManager templateGenManager)
{
_templateGenManager = templateGenManager;
}
/// <summary> /// <summary>
/// 下载模块文件 /// 下载模块文件
@@ -33,10 +29,8 @@ namespace Yi.Abp.Tool.Application
{ {
moduleCreateInputDto.SetNameReplace(); moduleCreateInputDto.SetNameReplace();
//模块类型,就是分支小写
var input = moduleCreateInputDto.Adapt<TemplateGenCreateDto>(); var input = moduleCreateInputDto.Adapt<TemplateGenCreateDto>();
input.SetTemplateGiteeRef(moduleCreateInputDto.ModuleSoure); input.SetTemplateFilePath(_templateGenManager._toolOptions.ModuleTemplateFilePath);
var filePath = await _templateGenManager.CreateTemplateAsync(input); var filePath = await _templateGenManager.CreateTemplateAsync(input);
////考虑从路径中获取 ////考虑从路径中获取
@@ -45,15 +39,22 @@ namespace Yi.Abp.Tool.Application
return await File.ReadAllBytesAsync(filePath); return await File.ReadAllBytesAsync(filePath);
} }
/// <summary> /// <summary>
/// 获取全部模板列表 /// 下载模块文件
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpGet("template-gen/template")] public async Task<byte[]> CreateProjectAsync(TemplateGenCreateInputDto moduleCreateInputDto)
public async Task<List<string>> GetAllTemplatesAsync()
{ {
return await _templateGenManager.GetAllTemplatesAsync(); moduleCreateInputDto.SetNameReplace();
var input = moduleCreateInputDto.Adapt<TemplateGenCreateDto>();
input.SetTemplateFilePath(_templateGenManager._toolOptions.ProjectTemplateFilePath);
var filePath = await _templateGenManager.CreateTemplateAsync(input);
//考虑从路径中获取
// var fileContentType = MimeHelper.GetMimeMapping(Path.GetFileName(filePath));
//设置附件下载,下载名称
return await File.ReadAllBytesAsync(filePath);
} }
} }
} }

View File

@@ -9,19 +9,21 @@ namespace Yi.Abp.Tool.Domain.Shared.Dtos
{ {
public class TemplateGenCreateDto public class TemplateGenCreateDto
{ {
public void SetTemplateGiteeRef(string moduleType) public void SetTemplateFilePath(string templateFilePath)
{ {
this.GiteeRef = moduleType.ToLower(); this.TemplateFilePath = templateFilePath;
} }
/// <summary>
/// 模板文件路径
/// </summary>
public string TemplateFilePath { get; set; }
/// <summary> /// <summary>
/// 模块名称 /// 模块名称
/// </summary> /// </summary>
public string Name { get; set; } public string Name { get; set; }
/// <summary>
/// 模块所属gitee分支
/// </summary>
public string GiteeRef { get; set; }
/// <summary> /// <summary>
/// 数据库提供者 /// 数据库提供者

View File

@@ -8,6 +8,17 @@ namespace Yi.Abp.Tool.Domain.Shared.Options
{ {
public class ToolOptions public class ToolOptions
{ {
/// <summary>
/// 模块模板zip文件路径
/// </summary>
public string ModuleTemplateFilePath { get; set; }
/// <summary>
/// 项目模板zip文件路径
/// </summary>
public string ProjectTemplateFilePath { get; set; }
/// <summary> /// <summary>
/// 临时文件目录 /// 临时文件目录
/// </summary> /// </summary>

View File

@@ -9,8 +9,5 @@
<ProjectReference Include="..\..\framework\Yi.Framework.Core\Yi.Framework.Core.csproj" /> <ProjectReference Include="..\..\framework\Yi.Framework.Core\Yi.Framework.Core.csproj" />
<ProjectReference Include="..\..\framework\Yi.Framework.Mapster\Yi.Framework.Mapster.csproj" /> <ProjectReference Include="..\..\framework\Yi.Framework.Mapster\Yi.Framework.Mapster.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Options\" />
</ItemGroup>
</Project> </Project>

View File

@@ -1,85 +0,0 @@
using System.Net;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using Volo.Abp.DependencyInjection;
namespace Yi.Abp.Tool.Domain;
public class GiteeManager : ITransientDependency
{
private readonly string _accessToken;
private readonly IHttpClientFactory _httpClientFactory;
private const string GiteeHost = "https://gitee.com/api/v5";
private const string Owner = "ccnetcore";
private const string Repo = "yi-template";
public GiteeManager(IConfiguration configuration, IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
_accessToken = configuration.GetValue<string>("GiteeAccession");
}
/// <summary>
/// 是否存在当前分支
/// </summary>
/// <returns></returns>
public async Task<bool> IsExsitBranchAsync(string branch)
{
using var client = _httpClientFactory.CreateClient();
var response =
await client.GetAsync(
$"{GiteeHost}/repos/{Owner}/{Repo}/branches/{branch}?access_token={_accessToken}");
if (response.StatusCode == HttpStatusCode.NotFound)
{
return false;
}
return true;
}
/// <summary>
/// 获取所有分支
/// </summary>
/// <returns></returns>
public async Task<List<string>> GetAllBranchAsync()
{
using var client = _httpClientFactory.CreateClient();
var response =
await client.GetAsync(
$"{GiteeHost}/repos/{Owner}/{Repo}/branches?access_token={_accessToken}&sort=name&direction=asc&page=1&per_page=100");
response.EnsureSuccessStatusCode();
var result= await response.Content.ReadAsStringAsync();
JArray jsonArray= JArray.Parse(result);
// 创建一个列表来存储名字
List<string> names = new List<string>();
// 遍历每个对象,获取 name 字段
foreach (JObject obj in jsonArray)
{
// 获取 name 字段的值
string name = obj["name"]?.ToString();
if (name != null)
{
names.Add(name);
}
}
return names;
}
/// <summary>
/// 下载仓库分支代码
/// </summary>
/// <param name="branch"></param>
/// <returns></returns>
public async Task<Stream> DownLoadFileAsync(string branch)
{
using var client = _httpClientFactory.CreateClient();
var response =
await client.GetAsync(
$"{GiteeHost}/repos/{Owner}/{Repo}/zipball?access_token={_accessToken}&ref={branch}");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStreamAsync();
}
}

View File

@@ -13,23 +13,14 @@ namespace Yi.Abp.Tool.Domain
{ {
public class TemplateGenManager : ITransientDependency public class TemplateGenManager : ITransientDependency
{ {
private readonly ToolOptions _toolOptions; public readonly ToolOptions _toolOptions;
private readonly GiteeManager _giteeManager; public TemplateGenManager(IOptionsMonitor<ToolOptions> toolOptions) { _toolOptions = toolOptions.CurrentValue; }
public TemplateGenManager(IOptionsMonitor<ToolOptions> toolOptions, GiteeManager giteeManager)
{
_giteeManager = giteeManager;
_toolOptions = toolOptions.CurrentValue;
}
public async Task<string> CreateTemplateAsync(TemplateGenCreateDto input) public async Task<string> CreateTemplateAsync(TemplateGenCreateDto input)
{ {
//这里判断gitee上是否有这个分支 if (string.IsNullOrEmpty(input.TemplateFilePath))
if (!await _giteeManager.IsExsitBranchAsync(input.GiteeRef))
{ {
throw new UserFriendlyException($"Gitee分支未找到{input.GiteeRef},请检查,[{input.GiteeRef}]分支是否存在"); throw new UserFriendlyException($"模板路径无法找到,请检查,[{input.TemplateFilePath}]路径");
} }
if (string.IsNullOrEmpty(_toolOptions.TempDirPath)) if (string.IsNullOrEmpty(_toolOptions.TempDirPath))
{ {
throw new UserFriendlyException($"临时目录路径无法找到,请检查,[{_toolOptions.TempDirPath}]路径"); throw new UserFriendlyException($"临时目录路径无法找到,请检查,[{_toolOptions.TempDirPath}]路径");
@@ -42,56 +33,25 @@ namespace Yi.Abp.Tool.Domain
Directory.CreateDirectory(tempFileDirPath); Directory.CreateDirectory(tempFileDirPath);
} }
//文件解压覆盖
ZipFile.ExtractToDirectory(input.TemplateFilePath, tempFileDirPath, true);
//下载的模板存放文件路径 await ReplaceContentAsync(tempFileDirPath, input.ReplaceStrData);
var downloadPath = Path.Combine(_toolOptions.TempDirPath, "download");
if (!Directory.Exists(downloadPath))
{
Directory.CreateDirectory(downloadPath);
}
var downloadFilePath = Path.Combine(downloadPath, $"{id}.zip");
var gitSteam = await _giteeManager.DownLoadFileAsync(input.GiteeRef);
using (FileStream fileStream = new FileStream(downloadFilePath, FileMode.Create, FileAccess.Write))
{
await gitSteam.CopyToAsync(fileStream);
}
//文件解压覆盖,将刚刚下载的模板,解压即可
ZipFile.ExtractToDirectory(downloadFilePath, tempFileDirPath, true);
//注意这里下载的zip包其实多了一层我们进行操作的时候要将操作目录进一步
var operPath = Directory.GetDirectories(tempFileDirPath)[0];
await ReplaceContentAsync(operPath, input.ReplaceStrData);
var tempFilePath = Path.Combine(_toolOptions.TempDirPath, $"{id}.zip"); var tempFilePath = Path.Combine(_toolOptions.TempDirPath, $"{id}.zip");
ZipFile.CreateFromDirectory(operPath, tempFilePath);
ZipFile.CreateFromDirectory(tempFileDirPath, tempFilePath);
//创建压缩包后删除临时目录 //创建压缩包后删除临时目录
Directory.Delete(tempFileDirPath, true); Directory.Delete(tempFileDirPath, true);
return tempFilePath; return tempFilePath;
} }
/// <summary>
/// 获取全部模板列表
/// </summary>
/// <returns></returns>
public async Task<List<string>> GetAllTemplatesAsync()
{
var refs = await _giteeManager.GetAllBranchAsync();
//移除主分支
refs.Remove("master");
return refs;
}
/// <summary> /// <summary>
/// 替换内容,key为要替换的内容value为替换成的内容 /// 替换内容,key为要替换的内容value为替换成的内容
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private async Task ReplaceContentAsync(string rootDirectory, Dictionary<string, string> dic) private async Task ReplaceContentAsync(string rootDirectory, Dictionary<string, string> dic)
{ {
foreach (var dicEntry in dic) foreach (var dicEntry in dic)
{ {
await ReplaceInDirectory(rootDirectory, dicEntry.Key, dicEntry.Value); await ReplaceInDirectory(rootDirectory, dicEntry.Key, dicEntry.Value);

View File

@@ -19,7 +19,6 @@
<ItemGroup> <ItemGroup>
<Folder Include="wwwroot\" /> <Folder Include="wwwroot\" />
<Folder Include="wwwroot\temp\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -34,8 +33,4 @@
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup>
<_ContentIncludedByDefault Remove="wwwroot\temp\download\d5bb6f4c5ca24da29ebe1b67e1e4595d.zip" />
</ItemGroup>
</Project> </Project>

View File

@@ -1,9 +1,6 @@
using System.Globalization; using System.Globalization;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using System.Threading.RateLimiting; using System.Threading.RateLimiting;
using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
@@ -15,7 +12,6 @@ using Yi.Abp.Tool.Application;
using Yi.Framework.AspNetCore; using Yi.Framework.AspNetCore;
using Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder; using Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
using Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection; using Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection;
using Yi.Framework.Core.Json;
namespace Yi.Abp.Tool.Web namespace Yi.Abp.Tool.Web
{ {
@@ -45,17 +41,15 @@ namespace Yi.Abp.Tool.Web
}); });
//设置api格式 //设置api格式
Configure<JsonOptions>(options => service.AddControllers().AddNewtonsoftJson(options =>
{ {
options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver(); options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter()); options.SerializerSettings.Converters.Add(new StringEnumConverter());
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
}); });
Configure<AbpAntiForgeryOptions>(options => Configure<AbpAntiForgeryOptions>(options =>
{ {
options.AutoValidate = false; options.AutoValidate = false;
@@ -87,7 +81,7 @@ namespace Yi.Abp.Tool.Web
}); });
}); });
service.AddHttpClient();
//速率限制 //速率限制
//每60秒限制100个请求滑块添加分6段 //每60秒限制100个请求滑块添加分6段
service.AddRateLimiter(_ => service.AddRateLimiter(_ =>

View File

@@ -1,3 +1,8 @@
{ {
"GiteeAccession": "8d9f05faec154475f121079579a0abf0" "Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
} }

View File

@@ -15,6 +15,5 @@
"TempDirPath": "wwwroot/temp", "TempDirPath": "wwwroot/temp",
"ModuleTemplateFilePath": "wwwroot/ModuleTemplate.zip", "ModuleTemplateFilePath": "wwwroot/ModuleTemplate.zip",
"ProjectTemplateFilePath": "wwwroot/ProjectTemplate.zip" "ProjectTemplateFilePath": "wwwroot/ProjectTemplate.zip"
}, }
"GiteeAccession": ""
} }

Some files were not shown because too many files have changed in this diff Show More