Compare commits
3 Commits
hangfire
...
AbpUnitOfW
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b7abd4fe0 | ||
|
|
bbc18dcaf9 | ||
|
|
7cb78e70cb |
1
.gitignore
vendored
@@ -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/
|
||||||
|
|||||||
@@ -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}"
|
||||||
@@ -156,8 +170,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Tool.HttpApi.Client"
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.SettingManagement.Application", "module\setting-management\Yi.Framework.SettingManagement.Application\Yi.Framework.SettingManagement.Application.csproj", "{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.SettingManagement.Application", "module\setting-management\Yi.Framework.SettingManagement.Application\Yi.Framework.SettingManagement.Application.csproj", "{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.BackgroundWorkers.Hangfire", "framework\Yi.Framework.BackgroundWorkers.Hangfire\Yi.Framework.BackgroundWorkers.Hangfire.csproj", "{862CA181-BEE6-4870-82D2-B662E527ED8C}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -264,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
|
||||||
@@ -392,10 +428,6 @@ Global
|
|||||||
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}.Release|Any CPU.Build.0 = Release|Any CPU
|
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{862CA181-BEE6-4870-82D2-B662E527ED8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{862CA181-BEE6-4870-82D2-B662E527ED8C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{862CA181-BEE6-4870-82D2-B662E527ED8C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{862CA181-BEE6-4870-82D2-B662E527ED8C}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -429,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}
|
||||||
@@ -465,7 +503,6 @@ Global
|
|||||||
{4AE84CDE-2A47-4D68-8E93-86193F72E4E8} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4}
|
{4AE84CDE-2A47-4D68-8E93-86193F72E4E8} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4}
|
||||||
{C8F97775-D903-4365-A4FF-3DA97E318CD2} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4}
|
{C8F97775-D903-4365-A4FF-3DA97E318CD2} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4}
|
||||||
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956} = {8C68059E-F3B1-4D28-A1C9-A5830F53E5D3}
|
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956} = {8C68059E-F3B1-4D28-A1C9-A5830F53E5D3}
|
||||||
{862CA181-BEE6-4870-82D2-B662E527ED8C} = {77B949E9-530E-45A5-9657-20F7D5C6875C}
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {23D6FBC9-C970-4641-BC1E-2AEA59F51C18}
|
SolutionGuid = {23D6FBC9-C970-4641-BC1E-2AEA59F51C18}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<Import Project="..\..\common.props" />
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Volo.Abp.BackgroundWorkers.Hangfire" Version="$(AbpVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Volo.Abp.BackgroundWorkers;
|
|
||||||
using Volo.Abp.BackgroundWorkers.Hangfire;
|
|
||||||
|
|
||||||
namespace Yi.Framework.BackgroundWorkers.Hangfire;
|
|
||||||
|
|
||||||
[DependsOn(typeof(AbpBackgroundWorkersHangfireModule))]
|
|
||||||
public class YiFrameworkBackgroundWorkersHangfireModule:AbpModule
|
|
||||||
{
|
|
||||||
public override void PreConfigureServices(ServiceConfigurationContext context)
|
|
||||||
{
|
|
||||||
context.Services.AddConventionalRegistrar(new YiHangfireConventionalRegistrar());
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
|
|
||||||
{
|
|
||||||
//定时任务自动注入,Abp默认只有在Quartz才实现
|
|
||||||
var backgroundWorkerManager = context.ServiceProvider.GetRequiredService<IBackgroundWorkerManager>();
|
|
||||||
var works = context.ServiceProvider.GetServices<IHangfireBackgroundWorker>();
|
|
||||||
|
|
||||||
foreach (var work in works)
|
|
||||||
{
|
|
||||||
await backgroundWorkerManager.AddAsync(work);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
using Volo.Abp.BackgroundWorkers.Hangfire;
|
|
||||||
using Volo.Abp.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Yi.Framework.BackgroundWorkers.Hangfire;
|
|
||||||
|
|
||||||
public class YiHangfireConventionalRegistrar : DefaultConventionalRegistrar
|
|
||||||
{
|
|
||||||
protected override bool IsConventionalRegistrationDisabled(Type type)
|
|
||||||
{
|
|
||||||
return !typeof(IHangfireBackgroundWorker).IsAssignableFrom(type) || base.IsConventionalRegistrationDisabled(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override List<Type> GetExposedServiceTypes(Type type)
|
|
||||||
{
|
|
||||||
return new List<Type>()
|
|
||||||
{
|
|
||||||
typeof(IHangfireBackgroundWorker)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -36,18 +36,15 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
|
|
||||||
protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled<ISoftDelete>() ?? false;
|
protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled<ISoftDelete>() ?? false;
|
||||||
|
|
||||||
private IEntityChangeEventHelper EntityChangeEventHelper =>
|
private IEntityChangeEventHelper EntityChangeEventHelper => LazyServiceProvider.LazyGetService<IEntityChangeEventHelper>(NullEntityChangeEventHelper.Instance);
|
||||||
LazyServiceProvider.LazyGetService<IEntityChangeEventHelper>(NullEntityChangeEventHelper.Instance);
|
|
||||||
|
|
||||||
public DbConnOptions Options => LazyServiceProvider.LazyGetRequiredService<IOptions<DbConnOptions>>().Value;
|
public DbConnOptions Options => LazyServiceProvider.LazyGetRequiredService<IOptions<DbConnOptions>>().Value;
|
||||||
|
|
||||||
private ISerializeService SerializeService => LazyServiceProvider.LazyGetRequiredService<ISerializeService>();
|
private ISerializeService SerializeService=> LazyServiceProvider.LazyGetRequiredService<ISerializeService>();
|
||||||
|
|
||||||
public void SetSqlSugarClient(ISqlSugarClient sqlSugarClient)
|
public void SetSqlSugarClient(ISqlSugarClient sqlSugarClient)
|
||||||
{
|
{
|
||||||
SqlSugarClient = sqlSugarClient;
|
SqlSugarClient = sqlSugarClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SqlSugarDbContext(IAbpLazyServiceProvider lazyServiceProvider)
|
public SqlSugarDbContext(IAbpLazyServiceProvider lazyServiceProvider)
|
||||||
{
|
{
|
||||||
LazyServiceProvider = lazyServiceProvider;
|
LazyServiceProvider = lazyServiceProvider;
|
||||||
@@ -76,14 +73,12 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
protected virtual string GetCurrentConnectionString()
|
protected virtual string GetCurrentConnectionString()
|
||||||
{
|
{
|
||||||
var connectionStringResolver = LazyServiceProvider.LazyGetRequiredService<IConnectionStringResolver>();
|
var connectionStringResolver = LazyServiceProvider.LazyGetRequiredService<IConnectionStringResolver>();
|
||||||
var connectionString =
|
var connectionString = connectionStringResolver.ResolveAsync().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||||
connectionStringResolver.ResolveAsync().ConfigureAwait(false).GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(connectionString))
|
if (string.IsNullOrWhiteSpace(connectionString))
|
||||||
{
|
{
|
||||||
Check.NotNull(Options.Url, "dbUrl未配置");
|
Check.NotNull(Options.Url, "dbUrl未配置");
|
||||||
}
|
}
|
||||||
|
|
||||||
return connectionString!;
|
return connectionString!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +92,6 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
return dbTypeFromTenantName.Value;
|
return dbTypeFromTenantName.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Check.NotNull(Options.DbType, "默认DbType未配置!");
|
Check.NotNull(Options.DbType, "默认DbType未配置!");
|
||||||
return Options.DbType!.Value;
|
return Options.DbType!.Value;
|
||||||
}
|
}
|
||||||
@@ -132,6 +126,7 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 上下文对象扩展
|
/// 上下文对象扩展
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -143,23 +138,21 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
{
|
{
|
||||||
sqlSugarClient.QueryFilter.AddTableFilter<ISoftDelete>(u => u.IsDeleted == false);
|
sqlSugarClient.QueryFilter.AddTableFilter<ISoftDelete>(u => u.IsDeleted == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsMultiTenantFilterEnabled)
|
if (IsMultiTenantFilterEnabled)
|
||||||
{
|
{
|
||||||
//表达式里只能有具体值,不能运算
|
//表达式里只能有具体值,不能运算
|
||||||
var expressionCurrentTenant = CurrentTenant.Id ?? null;
|
var expressionCurrentTenant = CurrentTenant.Id ?? null;
|
||||||
sqlSugarClient.QueryFilter.AddTableFilter<IMultiTenant>(u => u.TenantId == expressionCurrentTenant);
|
sqlSugarClient.QueryFilter.AddTableFilter<IMultiTenant>(u => u.TenantId == expressionCurrentTenant);
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomDataFilter(sqlSugarClient);
|
CustomDataFilter(sqlSugarClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void CustomDataFilter(ISqlSugarClient sqlSugarClient)
|
protected virtual void CustomDataFilter(ISqlSugarClient sqlSugarClient)
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
protected virtual void DataExecuted(object oldValue, DataAfterModel entityInfo)
|
protected virtual void DataExecuted(object oldValue, DataAfterModel entityInfo)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -181,34 +174,25 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
entityInfo.SetValue(DateTime.Now);
|
entityInfo.SetValue(DateTime.Now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.LastModifierId)))
|
if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.LastModifierId)))
|
||||||
{
|
{
|
||||||
if (typeof(Guid?) == entityInfo.EntityColumnInfo.PropertyInfo.PropertyType)
|
if (CurrentUser.Id != null)
|
||||||
{
|
{
|
||||||
if (CurrentUser.Id != null)
|
entityInfo.SetValue(CurrentUser.Id);
|
||||||
{
|
|
||||||
entityInfo.SetValue(CurrentUser.Id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DataFilterType.InsertByObject:
|
case DataFilterType.InsertByObject:
|
||||||
|
|
||||||
if (entityInfo.PropertyName.Equals(nameof(IEntity<Guid>.Id)))
|
if (entityInfo.PropertyName.Equals(nameof(IEntity<Guid>.Id)))
|
||||||
{
|
{
|
||||||
//类型为guid
|
//主键为空或者为默认最小值
|
||||||
if (typeof(Guid) == entityInfo.EntityColumnInfo.PropertyInfo.PropertyType)
|
if (Guid.Empty.Equals(oldValue))
|
||||||
{
|
{
|
||||||
//主键为空或者为默认最小值
|
entityInfo.SetValue(GuidGenerator.Create());
|
||||||
if (Guid.Empty.Equals(oldValue))
|
|
||||||
{
|
|
||||||
entityInfo.SetValue(GuidGenerator.Create());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreationTime)))
|
if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreationTime)))
|
||||||
{
|
{
|
||||||
//为空或者为默认最小值
|
//为空或者为默认最小值
|
||||||
if (DateTime.MinValue.Equals(oldValue))
|
if (DateTime.MinValue.Equals(oldValue))
|
||||||
@@ -216,26 +200,21 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
entityInfo.SetValue(DateTime.Now);
|
entityInfo.SetValue(DateTime.Now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreatorId)))
|
if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreatorId)))
|
||||||
{
|
{
|
||||||
//类型为guid
|
if (CurrentUser.Id is not null)
|
||||||
if (typeof(Guid?) == entityInfo.EntityColumnInfo.PropertyInfo.PropertyType)
|
|
||||||
{
|
{
|
||||||
if (CurrentUser.Id is not null)
|
entityInfo.SetValue(CurrentUser.Id);
|
||||||
{
|
|
||||||
entityInfo.SetValue(CurrentUser.Id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (entityInfo.PropertyName.Equals(nameof(IMultiTenant.TenantId)))
|
if (entityInfo.PropertyName.Equals(nameof(IMultiTenant.TenantId)))
|
||||||
{
|
{
|
||||||
if (CurrentTenant.Id is not null)
|
if (CurrentTenant.Id is not null)
|
||||||
{
|
{
|
||||||
entityInfo.SetValue(CurrentTenant.Id);
|
entityInfo.SetValue(CurrentTenant.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,7 +227,6 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
{
|
{
|
||||||
EntityChangeEventHelper.PublishEntityCreatedEvent(entityInfo.EntityValue);
|
EntityChangeEventHelper.PublishEntityCreatedEvent(entityInfo.EntityValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DataFilterType.UpdateByObject:
|
case DataFilterType.UpdateByObject:
|
||||||
if (entityInfo.PropertyName == nameof(IEntity<object>.Id))
|
if (entityInfo.PropertyName == nameof(IEntity<object>.Id))
|
||||||
@@ -265,8 +243,8 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
{
|
{
|
||||||
EntityChangeEventHelper.PublishEntityUpdatedEvent(entityInfo.EntityValue);
|
EntityChangeEventHelper.PublishEntityUpdatedEvent(entityInfo.EntityValue);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DataFilterType.DeleteByObject:
|
case DataFilterType.DeleteByObject:
|
||||||
if (entityInfo.PropertyName == nameof(IEntity<object>.Id))
|
if (entityInfo.PropertyName == nameof(IEntity<object>.Id))
|
||||||
@@ -276,13 +254,14 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
{
|
{
|
||||||
foreach (var entityValue in entityValues)
|
foreach (var entityValue in entityValues)
|
||||||
{
|
{
|
||||||
|
|
||||||
EntityChangeEventHelper.PublishEntityDeletedEvent(entityValue);
|
EntityChangeEventHelper.PublishEntityDeletedEvent(entityValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -301,6 +280,7 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
sb.AppendLine("===============================");
|
sb.AppendLine("===============================");
|
||||||
Logger.CreateLogger<SqlSugarDbContext>().LogDebug(sb.ToString());
|
Logger.CreateLogger<SqlSugarDbContext>().LogDebug(sb.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -326,14 +306,14 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
{
|
{
|
||||||
if (property.Name == nameof(IHasConcurrencyStamp.ConcurrencyStamp)) //带版本号并发更新
|
if (property.Name == nameof(IHasConcurrencyStamp.ConcurrencyStamp)) //带版本号并发更新
|
||||||
{
|
{
|
||||||
|
// column.IsOnlyIgnoreInsert = true;
|
||||||
|
// column.IsOnlyIgnoreUpdate = true;
|
||||||
column.IsEnableUpdateVersionValidation = true;
|
column.IsEnableUpdateVersionValidation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (property.PropertyType == typeof(ExtraPropertyDictionary))
|
if (property.PropertyType == typeof(ExtraPropertyDictionary))
|
||||||
{
|
{
|
||||||
column.IsIgnore = true;
|
column.IsIgnore = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (property.Name == nameof(Entity<object>.Id))
|
if (property.Name == nameof(Entity<object>.Id))
|
||||||
{
|
{
|
||||||
column.IsPrimarykey = true;
|
column.IsPrimarykey = true;
|
||||||
@@ -348,13 +328,11 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
{
|
{
|
||||||
Directory.CreateDirectory(directoryName);
|
Directory.CreateDirectory(directoryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Options.DbType)
|
switch (Options.DbType)
|
||||||
{
|
{
|
||||||
case DbType.MySql:
|
case DbType.MySql:
|
||||||
//MySql
|
//MySql
|
||||||
SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database,
|
SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database, $"{Path.Combine(directoryName, fileName)}.sql");//mysql 只支持.net core
|
||||||
$"{Path.Combine(directoryName, fileName)}.sql"); //mysql 只支持.net core
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
@@ -366,14 +344,19 @@ namespace Yi.Framework.SqlSugarCore
|
|||||||
|
|
||||||
case DbType.SqlServer:
|
case DbType.SqlServer:
|
||||||
//SqlServer
|
//SqlServer
|
||||||
SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database,
|
SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database, $"{Path.Combine(directoryName, fileName)}.bak"/*服务器路径*/);//第一个参数库名
|
||||||
$"{Path.Combine(directoryName, fileName)}.bak" /*服务器路径*/); //第一个参数库名
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException("其他数据库备份未实现");
|
throw new NotImplementedException("其他数据库备份未实现");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ 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; }
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using Yi.Framework.Rbac.Application.Contracts.Dtos.User;
|
|||||||
namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Comment
|
namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Comment
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 单返回,返回单条评论即可
|
/// 单返回,返回单条评论即可
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CommentGetOutputDto : EntityDto<Guid>
|
public class CommentGetOutputDto : EntityDto<Guid>
|
||||||
{
|
{
|
||||||
@@ -17,17 +17,17 @@ namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Comment
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户id联表为用户对象
|
/// 用户id联表为用户对象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public BbsUserGetOutputDto User { get; set; }
|
public BbsUserGetOutputDto User { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根节点的评论id
|
/// 根节点的评论id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid RootId { get; set; }
|
public Guid RootId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 被回复的CommentId
|
/// 被回复的CommentId
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid ParentId { get; set; }
|
public Guid ParentId { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,15 @@ namespace Yi.Framework.Bbs.Application.Contracts.IServices
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Comment服务抽象
|
/// Comment服务抽象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ICommentService : IYiCrudAppService<CommentGetOutputDto, CommentGetListOutputDto, Guid, CommentGetListInputVo, CommentCreateInputVo, CommentUpdateInputVo>
|
public interface ICommentService{
|
||||||
{
|
/// <summary>
|
||||||
|
/// 发表评论
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="UserFriendlyException"></exception>
|
||||||
|
// [Permission("bbs:comment:add")]
|
||||||
|
// [Authorize]
|
||||||
|
Task<CommentGetOutputDto> CreateAsync(CommentCreateInputVo input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using FreeRedis;
|
using FreeRedis;
|
||||||
using Hangfire;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Volo.Abp.BackgroundWorkers.Hangfire;
|
using Quartz;
|
||||||
|
using Volo.Abp.BackgroundWorkers.Quartz;
|
||||||
using Volo.Abp.Caching;
|
using Volo.Abp.Caching;
|
||||||
using Volo.Abp.DependencyInjection;
|
using Volo.Abp.DependencyInjection;
|
||||||
using Volo.Abp.Domain.Entities;
|
using Volo.Abp.Domain.Entities;
|
||||||
@@ -15,27 +15,23 @@ using Yi.Framework.SqlSugarCore.Abstractions;
|
|||||||
|
|
||||||
namespace Yi.Framework.Bbs.Application.Jobs;
|
namespace Yi.Framework.Bbs.Application.Jobs;
|
||||||
|
|
||||||
public class AccessLogCacheJob : HangfireBackgroundWorkerBase
|
public class AccessLogCacheJob : QuartzBackgroundWorkerBase
|
||||||
{
|
{
|
||||||
private readonly ILocalEventBus _localEventBus;
|
private readonly ILocalEventBus _localEventBus;
|
||||||
|
|
||||||
public AccessLogCacheJob(ILocalEventBus localEventBus)
|
public AccessLogCacheJob(ILocalEventBus localEventBus)
|
||||||
{
|
{
|
||||||
_localEventBus = localEventBus;
|
_localEventBus = localEventBus;
|
||||||
RecurringJobId = "访问日志写入缓存";
|
JobDetail = JobBuilder.Create<AccessLogCacheJob>().WithIdentity(nameof(AccessLogCacheJob))
|
||||||
//每10秒执行一次,将本地缓存转入redis,防止丢数据
|
.Build();
|
||||||
CronExpression = "*/10 * * * * *";
|
|
||||||
//
|
|
||||||
// JobDetail = JobBuilder.Create<AccessLogCacheJob>().WithIdentity(nameof(AccessLogCacheJob))
|
|
||||||
// .Build();
|
|
||||||
|
|
||||||
//每10秒执行一次,将本地缓存转入redis,防止丢数据
|
//每10秒执行一次,将本地缓存转入redis,防止丢数据
|
||||||
// Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogCacheJob))
|
Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogCacheJob))
|
||||||
// .WithSimpleSchedule((schedule) => { schedule.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever();; })
|
.WithSimpleSchedule((schedule) => { schedule.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever();; })
|
||||||
// .Build();
|
.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken())
|
public override async Task Execute(IJobExecutionContext context)
|
||||||
{
|
{
|
||||||
await _localEventBus.PublishAsync(new AccessLogResetArgs());
|
await _localEventBus.PublishAsync(new AccessLogResetArgs());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using FreeRedis;
|
using FreeRedis;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Volo.Abp.BackgroundWorkers.Hangfire;
|
using Quartz;
|
||||||
|
using Volo.Abp.BackgroundWorkers.Quartz;
|
||||||
using Volo.Abp.Caching;
|
using Volo.Abp.Caching;
|
||||||
using Volo.Abp.DependencyInjection;
|
using Volo.Abp.DependencyInjection;
|
||||||
|
using Volo.Abp.Domain.Entities;
|
||||||
using Yi.Framework.Bbs.Domain.Entities;
|
using Yi.Framework.Bbs.Domain.Entities;
|
||||||
using Yi.Framework.Bbs.Domain.Shared.Caches;
|
using Yi.Framework.Bbs.Domain.Shared.Caches;
|
||||||
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
||||||
@@ -11,7 +13,7 @@ using Yi.Framework.SqlSugarCore.Abstractions;
|
|||||||
|
|
||||||
namespace Yi.Framework.Bbs.Application.Jobs;
|
namespace Yi.Framework.Bbs.Application.Jobs;
|
||||||
|
|
||||||
public class AccessLogStoreJob : HangfireBackgroundWorkerBase
|
public class AccessLogStoreJob : QuartzBackgroundWorkerBase
|
||||||
{
|
{
|
||||||
private readonly ISqlSugarRepository<AccessLogAggregateRoot> _repository;
|
private readonly ISqlSugarRepository<AccessLogAggregateRoot> _repository;
|
||||||
|
|
||||||
@@ -43,23 +45,18 @@ public class AccessLogStoreJob : HangfireBackgroundWorkerBase
|
|||||||
public AccessLogStoreJob(ISqlSugarRepository<AccessLogAggregateRoot> repository)
|
public AccessLogStoreJob(ISqlSugarRepository<AccessLogAggregateRoot> repository)
|
||||||
{
|
{
|
||||||
_repository = repository;
|
_repository = repository;
|
||||||
|
JobDetail = JobBuilder.Create<AccessLogStoreJob>().WithIdentity(nameof(AccessLogStoreJob))
|
||||||
|
.Build();
|
||||||
|
|
||||||
RecurringJobId = "访问日志写入数据库";
|
|
||||||
//每分钟执行一次
|
//每分钟执行一次
|
||||||
CronExpression = "0 * * * * ?";
|
Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogStoreJob))
|
||||||
// JobDetail = JobBuilder.Create<AccessLogStoreJob>().WithIdentity(nameof(AccessLogStoreJob))
|
.WithCronSchedule("0 * * * * ?")
|
||||||
// .Build();
|
.Build();
|
||||||
// //每分钟执行一次
|
|
||||||
// Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogStoreJob))
|
|
||||||
// .WithCronSchedule("0 * * * * ?")
|
|
||||||
// .Build();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override async Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken())
|
public override async Task Execute(IJobExecutionContext context)
|
||||||
{
|
{
|
||||||
if (EnableRedisCache)
|
if (EnableRedisCache)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Volo.Abp.BackgroundWorkers.Hangfire;
|
using Quartz;
|
||||||
|
using Volo.Abp.BackgroundWorkers.Quartz;
|
||||||
using Yi.Framework.Bbs.Domain.Managers;
|
using Yi.Framework.Bbs.Domain.Managers;
|
||||||
|
|
||||||
namespace Yi.Framework.Bbs.Application.Jobs;
|
namespace Yi.Framework.Bbs.Application.Jobs;
|
||||||
@@ -6,25 +7,20 @@ namespace Yi.Framework.Bbs.Application.Jobs;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 每日任务job
|
/// 每日任务job
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AssignmentExpireTimeOutJob : HangfireBackgroundWorkerBase
|
public class AssignmentExpireTimeOutJob : QuartzBackgroundWorkerBase
|
||||||
{
|
{
|
||||||
private readonly AssignmentManager _assignmentManager;
|
private readonly AssignmentManager _assignmentManager;
|
||||||
|
|
||||||
public AssignmentExpireTimeOutJob(AssignmentManager assignmentManager)
|
public AssignmentExpireTimeOutJob(AssignmentManager assignmentManager)
|
||||||
{
|
{
|
||||||
_assignmentManager = assignmentManager;
|
_assignmentManager = assignmentManager;
|
||||||
|
JobDetail = JobBuilder.Create<AssignmentExpireTimeOutJob>().WithIdentity(nameof(AssignmentExpireTimeOutJob)).Build();
|
||||||
RecurringJobId = "每日任务系统超时检测";
|
//每个小时整点执行一次
|
||||||
//每分钟执行一次
|
Trigger = TriggerBuilder.Create().WithIdentity(nameof(AssignmentExpireTimeOutJob)).WithCronSchedule("0 0 * * * ?")
|
||||||
CronExpression = "0 * * * * ?";
|
.Build();
|
||||||
//
|
|
||||||
// JobDetail = JobBuilder.Create<AssignmentExpireTimeOutJob>().WithIdentity(nameof(AssignmentExpireTimeOutJob)).Build();
|
|
||||||
// //每个小时整点执行一次
|
|
||||||
// Trigger = TriggerBuilder.Create().WithIdentity(nameof(AssignmentExpireTimeOutJob)).WithCronSchedule("0 0 * * * ?")
|
|
||||||
// .Build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken())
|
public override async Task Execute(IJobExecutionContext context)
|
||||||
{
|
{
|
||||||
await _assignmentManager.ExpireTimeoutAsync();
|
await _assignmentManager.ExpireTimeoutAsync();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,20 @@
|
|||||||
using Volo.Abp.BackgroundWorkers.Hangfire;
|
using Quartz;
|
||||||
|
using Volo.Abp.BackgroundWorkers.Quartz;
|
||||||
using Yi.Framework.Bbs.Domain.Managers;
|
using Yi.Framework.Bbs.Domain.Managers;
|
||||||
|
|
||||||
namespace Yi.Framework.Bbs.Application.Jobs
|
namespace Yi.Framework.Bbs.Application.Jobs
|
||||||
{
|
{
|
||||||
public class InterestRecordsJob : HangfireBackgroundWorkerBase
|
public class InterestRecordsJob : QuartzBackgroundWorkerBase
|
||||||
{
|
{
|
||||||
private BankManager _bankManager;
|
private BankManager _bankManager;
|
||||||
public InterestRecordsJob(BankManager bankManager)
|
public InterestRecordsJob(BankManager bankManager)
|
||||||
{
|
{
|
||||||
_bankManager = bankManager;
|
_bankManager = bankManager;
|
||||||
|
JobDetail = JobBuilder.Create<InterestRecordsJob>().WithIdentity(nameof(InterestRecordsJob)).Build();
|
||||||
RecurringJobId = "银行利息积分刷新";
|
|
||||||
//每个小时整点执行一次
|
//每个小时整点执行一次
|
||||||
CronExpression = "0 0 * * * ?";
|
|
||||||
|
Trigger = TriggerBuilder.Create().WithIdentity(nameof(InterestRecordsJob)).WithCronSchedule("0 0 * * * ?").Build();
|
||||||
// JobDetail = JobBuilder.Create<InterestRecordsJob>().WithIdentity(nameof(InterestRecordsJob)).Build();
|
|
||||||
//
|
|
||||||
// //每个小时整点执行一次
|
|
||||||
//
|
|
||||||
// Trigger = TriggerBuilder.Create().WithIdentity(nameof(InterestRecordsJob)).WithCronSchedule("0 0 * * * ?").Build();
|
|
||||||
|
|
||||||
//测试
|
//测试
|
||||||
// Trigger = TriggerBuilder.Create().WithIdentity(nameof(InterestRecordsJob))
|
// Trigger = TriggerBuilder.Create().WithIdentity(nameof(InterestRecordsJob))
|
||||||
@@ -27,8 +23,7 @@ namespace Yi.Framework.Bbs.Application.Jobs
|
|||||||
// .RepeatForever())
|
// .RepeatForever())
|
||||||
//.Build();
|
//.Build();
|
||||||
}
|
}
|
||||||
|
public override async Task Execute(IJobExecutionContext context)
|
||||||
public override async Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken())
|
|
||||||
{
|
{
|
||||||
//创建一个记录,莫得了
|
//创建一个记录,莫得了
|
||||||
await _bankManager.GetCurrentInterestRate();
|
await _bankManager.GetCurrentInterestRate();
|
||||||
|
|||||||
@@ -27,19 +27,13 @@ namespace Yi.Framework.Bbs.Application.Services
|
|||||||
var userEntity = await _bbsUserManager._userRepository.GetFirstAsync(x => x.UserName == userNameOrUserId);
|
var userEntity = await _bbsUserManager._userRepository.GetFirstAsync(x => x.UserName == userNameOrUserId);
|
||||||
if (userEntity == null)
|
if (userEntity == null)
|
||||||
{
|
{
|
||||||
throw new UserFriendlyException("该用户不存在");
|
throw new Volo.Abp.UserFriendlyException("该用户不存在");
|
||||||
}
|
}
|
||||||
userId= userEntity.Id;
|
userId= userEntity.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
var output =await _bbsUserManager.GetBbsUserInfoAsync(userId);
|
var output =await _bbsUserManager.GetBbsUserInfoAsync(userId);
|
||||||
|
|
||||||
//不是自己
|
|
||||||
if (CurrentUser.Id != output.Id)
|
|
||||||
{
|
|
||||||
output.Phone = null;
|
|
||||||
output.Email=null;
|
|
||||||
}
|
|
||||||
return output!;
|
return output!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using Volo.Abp;
|
using Volo.Abp;
|
||||||
using Volo.Abp.Application.Dtos;
|
using Volo.Abp.Application.Dtos;
|
||||||
|
using Volo.Abp.Application.Services;
|
||||||
|
using Volo.Abp.Domain.Repositories;
|
||||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.BbsUser;
|
using Yi.Framework.Bbs.Application.Contracts.Dtos.BbsUser;
|
||||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.Comment;
|
using Yi.Framework.Bbs.Application.Contracts.Dtos.Comment;
|
||||||
using Yi.Framework.Bbs.Application.Contracts.IServices;
|
using Yi.Framework.Bbs.Application.Contracts.IServices;
|
||||||
@@ -21,19 +23,11 @@ namespace Yi.Framework.Bbs.Application.Services.Forum
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 评论
|
/// 评论
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CommentService : YiCrudAppService<CommentAggregateRoot, CommentGetOutputDto, CommentGetListOutputDto, Guid, CommentGetListInputVo, CommentCreateInputVo, CommentUpdateInputVo>,
|
public class CommentService : ApplicationService,
|
||||||
ICommentService
|
ICommentService
|
||||||
{
|
{
|
||||||
private readonly ISqlSugarRepository<CommentAggregateRoot, Guid> _repository;
|
private readonly ISqlSugarRepository<CommentAggregateRoot, Guid> _repository;
|
||||||
private readonly BbsUserManager _bbsUserManager;
|
private readonly BbsUserManager _bbsUserManager;
|
||||||
public CommentService(ForumManager forumManager, ISqlSugarRepository<DiscussAggregateRoot> discussRepository, IDiscussService discussService, ISqlSugarRepository<CommentAggregateRoot, Guid> CommentRepository, BbsUserManager bbsUserManager) : base(CommentRepository)
|
|
||||||
{
|
|
||||||
_forumManager = forumManager;
|
|
||||||
_discussRepository = discussRepository;
|
|
||||||
_discussService = discussService;
|
|
||||||
_repository = CommentRepository;
|
|
||||||
_bbsUserManager = bbsUserManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ForumManager _forumManager { get; set; }
|
private ForumManager _forumManager { get; set; }
|
||||||
|
|
||||||
@@ -42,121 +36,50 @@ namespace Yi.Framework.Bbs.Application.Services.Forum
|
|||||||
private ISqlSugarRepository<DiscussAggregateRoot> _discussRepository { get; set; }
|
private ISqlSugarRepository<DiscussAggregateRoot> _discussRepository { get; set; }
|
||||||
|
|
||||||
private IDiscussService _discussService { get; set; }
|
private IDiscussService _discussService { get; set; }
|
||||||
/// <summary>
|
|
||||||
/// 获取改主题下的评论,结构为二维列表,该查询无分页
|
|
||||||
/// Todo: 可放入领域层
|
public async Task<CommentGetOutputDto> Create2Async(CommentCreateInputVo input)
|
||||||
/// </summary>
|
|
||||||
/// <param name="discussId"></param>
|
|
||||||
/// <param name="input"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<PagedResultDto<CommentGetListOutputDto>> GetDiscussIdAsync([FromRoute] Guid discussId, [FromQuery] CommentGetListInputVo input)
|
|
||||||
{
|
{
|
||||||
await _discussService.VerifyDiscussPermissionAsync(discussId);
|
var entity = new CommentAggregateRoot(Guid.Empty);
|
||||||
|
return new CommentGetOutputDto();
|
||||||
var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.Content), x => x.Content.Contains(input.Content))
|
|
||||||
.Where(x => x.DiscussId == discussId)
|
|
||||||
.Includes(x => x.CreateUser)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
//该实体需要进行转换
|
|
||||||
|
|
||||||
//同时为所有用户id进行bbs的扩展即可
|
|
||||||
List<Guid> userIds = entities.Where(x => x.CreatorId != null).Select(x => x.CreatorId ?? Guid.Empty).ToList();
|
|
||||||
var bbsUserInfoDic = (await _bbsUserManager.GetBbsUserInfoAsync(userIds)).ToDictionary(x => x.Id);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//------数据查询完成------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//从根目录开始组装
|
|
||||||
//结果初始值,第一层等于全部根节点
|
|
||||||
var allOutPut = entities.OrderByDescending(x => x.CreationTime).ToList();
|
|
||||||
|
|
||||||
//获取全量主题评论, 先获取顶级的,将其他子组合到顶级下,形成一个二维,先转成dto
|
|
||||||
List<CommentGetListOutputDto> allOutoutDto = await MapToGetListOutputDtosAsync(allOutPut);
|
|
||||||
|
|
||||||
//开始映射额外用户信息字段
|
|
||||||
allOutoutDto?.ForEach(x => x.CreateUser = bbsUserInfoDic[x.CreatorId ?? Guid.Empty].Adapt<BbsUserGetOutputDto>());
|
|
||||||
|
|
||||||
//开始组装dto的层级关系
|
|
||||||
//将全部数据进行hash
|
|
||||||
var dic = allOutoutDto.ToDictionary(x => x.Id);
|
|
||||||
|
|
||||||
foreach (var comment in allOutoutDto)
|
|
||||||
{
|
|
||||||
//不是根节点,需要赋值 被评论者用户信息等
|
|
||||||
if (comment.ParentId != Guid.Empty)
|
|
||||||
{
|
|
||||||
if (dic.ContainsKey(comment.ParentId))
|
|
||||||
{
|
|
||||||
var parentComment = dic[comment.ParentId];
|
|
||||||
comment.CommentedUser = parentComment.CreateUser;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//root或者parent id,根节点都是等于0的
|
|
||||||
var id = comment.RootId;
|
|
||||||
if (id != Guid.Empty)
|
|
||||||
{
|
|
||||||
dic[id].Children.Add(comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//子类需要排序
|
|
||||||
var rootOutoutDto = allOutoutDto.Where(x => x.ParentId == Guid.Empty).ToList();
|
|
||||||
rootOutoutDto?.ForEach(x =>
|
|
||||||
{
|
|
||||||
x.Children = x.Children.OrderByDescending(x => x.CreationTime).ToList();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return new PagedResultDto<CommentGetListOutputDto>(entities.Count(), rootOutoutDto);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("Create22")]
|
||||||
|
public async Task<CommentGetOutputDto> Create22Async(CommentCreateInputVo input)
|
||||||
|
{
|
||||||
|
var entity = new CommentAggregateRoot(Guid.Empty);
|
||||||
|
return new CommentGetOutputDto();
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 发表评论
|
/// 发表评论
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="input"></param>
|
/// <param name="input"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <exception cref="UserFriendlyException"></exception>
|
/// <exception cref="UserFriendlyException"></exception>
|
||||||
[Permission("bbs:comment:add")]
|
// [Permission("bbs:comment:add")]
|
||||||
[Authorize]
|
// [Authorize]
|
||||||
public override async Task<CommentGetOutputDto> CreateAsync(CommentCreateInputVo input)
|
public async Task<CommentGetOutputDto> CreateAsync(CommentCreateInputVo input)
|
||||||
{
|
{
|
||||||
if (input.Content.Length<=6)
|
// var discuess = await _discussRepository.GetFirstAsync(x => x.Id == input.DiscussId);
|
||||||
{
|
// if (discuess is null)
|
||||||
throw new UserFriendlyException("评论长度至少大于6");
|
// {
|
||||||
}
|
// throw new UserFriendlyException(DiscussConst.No_Exist);
|
||||||
|
// }
|
||||||
var discuess = await _discussRepository.GetFirstAsync(x => x.Id == input.DiscussId);
|
|
||||||
if (discuess is null)
|
|
||||||
{
|
|
||||||
throw new UserFriendlyException(DiscussConst.No_Exist);
|
|
||||||
}
|
|
||||||
//不是超级管理员,且主题开启禁止评论
|
//不是超级管理员,且主题开启禁止评论
|
||||||
|
|
||||||
if (discuess.IsDisableCreateComment == true && !CurrentUser.GetPermissions().Contains(UserConst.AdminPermissionCode))
|
// if (discuess.IsDisableCreateComment == true && !CurrentUser.GetPermissions().Contains(UserConst.AdminPermissionCode))
|
||||||
{
|
// {
|
||||||
throw new UserFriendlyException("该主题已禁止评论功能");
|
// throw new UserFriendlyException("该主题已禁止评论功能");
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
var entity = await _forumManager.CreateCommentAsync(input.DiscussId, input.ParentId, input.RootId, input.Content);
|
// var entity = await _forumManager.CreateCommentAsync(input.DiscussId, input.ParentId, input.RootId, input.Content);
|
||||||
return await MapToGetOutputDtoAsync(entity);
|
var entity = new CommentAggregateRoot(Guid.Empty);
|
||||||
|
return new CommentGetOutputDto();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommentService(IRepository<CommentAggregateRoot, Guid> repository)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace Yi.Framework.Bbs.Application.Services.Integral
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 大转盘
|
/// 大转盘
|
||||||
/// Todo: 可放入领域层,但是太简单了,不重要
|
/// Todo: 可放入领域层
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Authorize]
|
[Authorize]
|
||||||
@@ -32,7 +32,13 @@ namespace Yi.Framework.Bbs.Application.Services.Integral
|
|||||||
int[] values = new int[10] { 0, 10, 30, 50, 60, 80, 90, 100, 200, 666 };
|
int[] values = new int[10] { 0, 10, 30, 50, 60, 80, 90, 100, 200, 666 };
|
||||||
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)
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace Yi.Framework.Bbs.Domain.Shared.Enums;
|
|
||||||
|
|
||||||
public enum GoodsTypeEnum
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 申请类型
|
|
||||||
/// </summary>
|
|
||||||
Apply
|
|
||||||
}
|
|
||||||
@@ -19,10 +19,5 @@ namespace Yi.Framework.Bbs.Domain.Shared.Enums
|
|||||||
/// 广播
|
/// 广播
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Broadcast,
|
Broadcast,
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 钱钱
|
|
||||||
/// </summary>
|
|
||||||
Money
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|||||||
@@ -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; }
|
|
||||||
}
|
|
||||||
@@ -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; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Yi.Framework.Bbs.Domain.Entities.Shop.ValueObjects;
|
|
||||||
|
|
||||||
public class ShippingAddress
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,73 +1,73 @@
|
|||||||
using TencentCloud.Tbm.V20180129.Models;
|
// using TencentCloud.Tbm.V20180129.Models;
|
||||||
using Volo.Abp.DependencyInjection;
|
// using Volo.Abp.DependencyInjection;
|
||||||
using Volo.Abp.Domain.Entities.Events;
|
// using Volo.Abp.Domain.Entities.Events;
|
||||||
using Volo.Abp.EventBus;
|
// using Volo.Abp.EventBus;
|
||||||
using Volo.Abp.EventBus.Local;
|
// using Volo.Abp.EventBus.Local;
|
||||||
using Yi.Framework.Bbs.Domain.Entities;
|
// using Yi.Framework.Bbs.Domain.Entities;
|
||||||
using Yi.Framework.Bbs.Domain.Entities.Forum;
|
// using Yi.Framework.Bbs.Domain.Entities.Forum;
|
||||||
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.Enums;
|
||||||
using Yi.Framework.Bbs.Domain.Shared.Etos;
|
// using Yi.Framework.Bbs.Domain.Shared.Etos;
|
||||||
using Yi.Framework.Rbac.Domain.Entities;
|
// using Yi.Framework.Rbac.Domain.Entities;
|
||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
// using Yi.Framework.SqlSugarCore.Abstractions;
|
||||||
|
//
|
||||||
namespace Yi.Framework.Bbs.Domain.EventHandlers
|
// namespace Yi.Framework.Bbs.Domain.EventHandlers
|
||||||
{
|
// {
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 评论创建的领域事件
|
// /// 评论创建的领域事件
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
public class CommentCreatedEventHandler : ILocalEventHandler<EntityCreatedEventData<CommentAggregateRoot>>,
|
// public class CommentCreatedEventHandler : ILocalEventHandler<EntityCreatedEventData<CommentAggregateRoot>>,
|
||||||
ITransientDependency
|
// ITransientDependency
|
||||||
{
|
// {
|
||||||
private ILocalEventBus _localEventBus;
|
// private ILocalEventBus _localEventBus;
|
||||||
private ISqlSugarRepository<DiscussAggregateRoot> _discussRepository;
|
// private ISqlSugarRepository<DiscussAggregateRoot> _discussRepository;
|
||||||
private ISqlSugarRepository<UserAggregateRoot> _userRepository;
|
// private ISqlSugarRepository<UserAggregateRoot> _userRepository;
|
||||||
public CommentCreatedEventHandler(ILocalEventBus localEventBus, ISqlSugarRepository<DiscussAggregateRoot> discussRepository, ISqlSugarRepository<UserAggregateRoot> userRepository)
|
// public CommentCreatedEventHandler(ILocalEventBus localEventBus, ISqlSugarRepository<DiscussAggregateRoot> discussRepository, ISqlSugarRepository<UserAggregateRoot> userRepository)
|
||||||
{
|
// {
|
||||||
_userRepository = userRepository;
|
// _userRepository = userRepository;
|
||||||
_localEventBus = localEventBus;
|
// _localEventBus = localEventBus;
|
||||||
_discussRepository = discussRepository;
|
// _discussRepository = discussRepository;
|
||||||
}
|
// }
|
||||||
public async Task HandleEventAsync(EntityCreatedEventData<CommentAggregateRoot> eventData)
|
// public async Task HandleEventAsync(EntityCreatedEventData<CommentAggregateRoot> eventData)
|
||||||
{
|
// {
|
||||||
var commentEntity = eventData.Entity;
|
// var commentEntity = eventData.Entity;
|
||||||
|
//
|
||||||
//给创建者发布数量+1
|
// //给创建者发布数量+1
|
||||||
await _userRepository._Db.Updateable<BbsUserExtraInfoEntity>()
|
// await _userRepository._Db.Updateable<BbsUserExtraInfoEntity>()
|
||||||
.SetColumns(it => it.CommentNumber == it.CommentNumber + 1)
|
// .SetColumns(it => it.CommentNumber == it.CommentNumber + 1)
|
||||||
.Where(it => it.UserId == commentEntity.CreatorId)
|
// .Where(it => it.UserId == commentEntity.CreatorId)
|
||||||
.ExecuteCommandAsync();
|
// .ExecuteCommandAsync();
|
||||||
var disucssDto = await _discussRepository._DbQueryable
|
// var disucssDto = await _discussRepository._DbQueryable
|
||||||
.Where(x => x.Id == commentEntity.DiscussId)
|
// .Where(x => x.Id == commentEntity.DiscussId)
|
||||||
.LeftJoin<UserAggregateRoot>((dicuss, user) => dicuss.CreatorId == user.Id)
|
// .LeftJoin<UserAggregateRoot>((dicuss, user) => dicuss.CreatorId == user.Id)
|
||||||
.Select((dicuss, user) =>
|
// .Select((dicuss, user) =>
|
||||||
new
|
// new
|
||||||
{
|
// {
|
||||||
DiscussUserId = user.Id,
|
// DiscussUserId = user.Id,
|
||||||
DiscussTitle = dicuss.Title,
|
// DiscussTitle = dicuss.Title,
|
||||||
|
//
|
||||||
})
|
// })
|
||||||
.FirstAsync();
|
// .FirstAsync();
|
||||||
|
//
|
||||||
var commentUser = await _userRepository.GetFirstAsync(x => x.Id == commentEntity.CreatorId);
|
// var commentUser = await _userRepository.GetFirstAsync(x => x.Id == commentEntity.CreatorId);
|
||||||
|
//
|
||||||
//截取30个长度
|
// //截取30个长度
|
||||||
var content = commentEntity.Content.Length >= 30 ? commentEntity.Content.Substring(0, 30)+"..." : commentEntity.Content;
|
// var content = commentEntity.Content.Length >= 30 ? commentEntity.Content.Substring(0, 30)+"..." : commentEntity.Content;
|
||||||
//通知主题作者,有人评论
|
// //通知主题作者,有人评论
|
||||||
await _localEventBus.PublishAsync(new BbsNoticeEventArgs(disucssDto.DiscussUserId, string.Format(DiscussConst.CommentNotice, disucssDto.DiscussTitle, commentUser.UserName, content,commentEntity.DiscussId)), false);
|
// await _localEventBus.PublishAsync(new BbsNoticeEventArgs(disucssDto.DiscussUserId, string.Format(DiscussConst.CommentNotice, disucssDto.DiscussTitle, commentUser.UserName, content,commentEntity.DiscussId)), false);
|
||||||
|
//
|
||||||
//如果为空,表示根路径,没有回复者
|
// //如果为空,表示根路径,没有回复者
|
||||||
if (commentEntity.ParentId != Guid.Empty)
|
// if (commentEntity.ParentId != Guid.Empty)
|
||||||
{
|
// {
|
||||||
//通知回复者,有人评论
|
// //通知回复者,有人评论
|
||||||
await _localEventBus.PublishAsync(new BbsNoticeEventArgs(commentEntity.ParentId, string.Format(DiscussConst.CommentNoticeToReply, disucssDto.DiscussTitle, commentUser.UserName, content,commentEntity.DiscussId)), false);
|
// await _localEventBus.PublishAsync(new BbsNoticeEventArgs(commentEntity.ParentId, string.Format(DiscussConst.CommentNoticeToReply, disucssDto.DiscussTitle, commentUser.UserName, content,commentEntity.DiscussId)), false);
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
//最后发布任务触发事件
|
// //最后发布任务触发事件
|
||||||
await _localEventBus.PublishAsync(
|
// await _localEventBus.PublishAsync(
|
||||||
new AssignmentEventArgs(AssignmentRequirementTypeEnum.Comment, commentUser.Id),false);
|
// new AssignmentEventArgs(AssignmentRequirementTypeEnum.Comment, commentUser.Id),false);
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
using Volo.Abp.Domain.Services;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Bbs.Domain.Managers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// bbs商品领域
|
|
||||||
/// </summary>
|
|
||||||
public class BbsShopManager: DomainService
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -41,7 +41,8 @@ namespace Yi.Framework.Bbs.Domain.Managers
|
|||||||
entity.Content = content;
|
entity.Content = content;
|
||||||
entity.ParentId = parentId;
|
entity.ParentId = parentId;
|
||||||
entity.RootId = rootId;
|
entity.RootId = rootId;
|
||||||
return await _commentRepository.InsertReturnEntityAsync(entity);
|
await _commentRepository.InsertAsync(entity);
|
||||||
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -78,12 +78,7 @@ namespace Yi.Framework.ChatHub.Domain.Managers
|
|||||||
public async Task<ChatOnlineUserCacheItem?> GetUserAsync(Guid userId)
|
public async Task<ChatOnlineUserCacheItem?> GetUserAsync(Guid userId)
|
||||||
{
|
{
|
||||||
var key = new ChatOnlineUserCacheKey(CacheKeyPrefix);
|
var key = new ChatOnlineUserCacheKey(CacheKeyPrefix);
|
||||||
var cacheUserOrNull= await RedisClient.HGetAsync(key.GetKey(), key.GetField(userId));
|
var cacheUser = System.Text.Json.JsonSerializer.Deserialize<ChatOnlineUserCacheItem>(await RedisClient.HGetAsync(key.GetKey(), key.GetField(userId)));
|
||||||
if (cacheUserOrNull is null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
var cacheUser = System.Text.Json.JsonSerializer.Deserialize<ChatOnlineUserCacheItem>(cacheUserOrNull);
|
|
||||||
return cacheUser;
|
return cacheUser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,16 @@ using System.Threading.Tasks;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Volo.Abp.BackgroundWorkers.Hangfire;
|
using Quartz;
|
||||||
|
using Quartz.Logging;
|
||||||
|
using Volo.Abp.BackgroundWorkers.Quartz;
|
||||||
using Volo.Abp.Domain.Repositories;
|
using Volo.Abp.Domain.Repositories;
|
||||||
using Yi.Framework.Rbac.Domain.Shared.Options;
|
using Yi.Framework.Rbac.Domain.Shared.Options;
|
||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||||
|
|
||||||
namespace Yi.Framework.Rbac.Application.Jobs
|
namespace Yi.Framework.Rbac.Application.Jobs
|
||||||
{
|
{
|
||||||
public class BackupDataBaseJob: HangfireBackgroundWorkerBase
|
public class BackupDataBaseJob : QuartzBackgroundWorkerBase
|
||||||
{
|
{
|
||||||
private ISqlSugarDbContext _dbContext;
|
private ISqlSugarDbContext _dbContext;
|
||||||
private IOptions<RbacOptions> _options;
|
private IOptions<RbacOptions> _options;
|
||||||
@@ -22,12 +24,13 @@ namespace Yi.Framework.Rbac.Application.Jobs
|
|||||||
|
|
||||||
_options = options;
|
_options = options;
|
||||||
_dbContext = dbContext;
|
_dbContext = dbContext;
|
||||||
|
JobDetail = JobBuilder.Create<BackupDataBaseJob>().WithIdentity(nameof(BackupDataBaseJob)).Build();
|
||||||
RecurringJobId = "数据库备份";
|
|
||||||
//每天00点与24点进行备份
|
//每天00点与24点进行备份
|
||||||
CronExpression = "0 0 0,12 * * ? ";
|
Trigger = TriggerBuilder.Create().WithIdentity(nameof(BackupDataBaseJob)).WithCronSchedule("0 0 0,12 * * ? ").Build();
|
||||||
|
//Trigger = TriggerBuilder.Create().WithIdentity(nameof(BackupDataBaseJob)).WithSimpleSchedule(x=>x.WithIntervalInSeconds(10)).Build();
|
||||||
}
|
}
|
||||||
public override Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken())
|
public override Task Execute(IJobExecutionContext context)
|
||||||
{
|
{
|
||||||
if (_options.Value.EnableDataBaseBackup)
|
if (_options.Value.EnableDataBaseBackup)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,220 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Mapster;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Quartz;
|
||||||
|
using Quartz.Impl.Matchers;
|
||||||
|
using Volo.Abp;
|
||||||
|
using Volo.Abp.Application.Dtos;
|
||||||
|
using Volo.Abp.Application.Services;
|
||||||
|
using Volo.Abp.Timing;
|
||||||
|
using Yi.Framework.Rbac.Application.Contracts.Dtos.Task;
|
||||||
|
using Yi.Framework.Rbac.Application.Contracts.IServices;
|
||||||
|
using Yi.Framework.Rbac.Domain.Shared.Enums;
|
||||||
|
|
||||||
|
namespace Yi.Framework.Rbac.Application.Services.Monitor
|
||||||
|
{
|
||||||
|
public class TaskService : ApplicationService, ITaskService
|
||||||
|
{
|
||||||
|
private readonly ISchedulerFactory _schedulerFactory;
|
||||||
|
private readonly IClock _clock;
|
||||||
|
public TaskService(ISchedulerFactory schedulerFactory, IClock clock)
|
||||||
|
{
|
||||||
|
_clock = clock;
|
||||||
|
_schedulerFactory = schedulerFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 单查job
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="jobId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("task/{jobId}")]
|
||||||
|
public async Task<TaskGetOutput> GetAsync([FromRoute] string jobId)
|
||||||
|
{
|
||||||
|
var scheduler = await _schedulerFactory.GetScheduler();
|
||||||
|
|
||||||
|
var jobDetail = await scheduler.GetJobDetail(new JobKey(jobId));
|
||||||
|
var trigger = (await scheduler.GetTriggersOfJob(new JobKey(jobId))).First();
|
||||||
|
//状态
|
||||||
|
var state = await scheduler.GetTriggerState(trigger.Key);
|
||||||
|
|
||||||
|
|
||||||
|
var output = new TaskGetOutput
|
||||||
|
{
|
||||||
|
JobId = jobDetail.Key.Name,
|
||||||
|
GroupName = jobDetail.Key.Group,
|
||||||
|
JobType = jobDetail.JobType.Name,
|
||||||
|
Properties = Newtonsoft.Json.JsonConvert.SerializeObject(jobDetail.JobDataMap),
|
||||||
|
Concurrent = !jobDetail.ConcurrentExecutionDisallowed,
|
||||||
|
Description = jobDetail.Description,
|
||||||
|
LastRunTime = _clock.Normalize(trigger.GetPreviousFireTimeUtc()?.DateTime ?? DateTime.MinValue),
|
||||||
|
NextRunTime = _clock.Normalize(trigger.GetNextFireTimeUtc()?.DateTime ?? DateTime.MinValue),
|
||||||
|
AssemblyName = jobDetail.JobType.Assembly.GetName().Name,
|
||||||
|
Status = state.ToString()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (trigger is ISimpleTrigger simple)
|
||||||
|
{
|
||||||
|
output.TriggerArgs = Math.Round(simple.RepeatInterval.TotalMinutes, 2).ToString() + "分钟";
|
||||||
|
output.Type = JobTypeEnum.Millisecond;
|
||||||
|
output.Millisecond = simple.RepeatInterval.TotalMilliseconds;
|
||||||
|
}
|
||||||
|
else if (trigger is ICronTrigger cron)
|
||||||
|
{
|
||||||
|
output.TriggerArgs = cron.CronExpressionString!;
|
||||||
|
output.Type = JobTypeEnum.Cron;
|
||||||
|
output.Cron = cron.CronExpressionString;
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 多查job
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<PagedResultDto<TaskGetListOutput>> GetListAsync([FromQuery] TaskGetListInput input)
|
||||||
|
{
|
||||||
|
var items = new List<TaskGetOutput>();
|
||||||
|
|
||||||
|
var scheduler = await _schedulerFactory.GetScheduler();
|
||||||
|
|
||||||
|
var groups = await scheduler.GetJobGroupNames();
|
||||||
|
|
||||||
|
foreach (var groupName in groups)
|
||||||
|
{
|
||||||
|
foreach (var jobKey in await scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals(groupName)))
|
||||||
|
{
|
||||||
|
string jobName = jobKey.Name;
|
||||||
|
string jobGroup = jobKey.Group;
|
||||||
|
var triggers = (await scheduler.GetTriggersOfJob(jobKey)).First();
|
||||||
|
items.Add(await GetAsync(jobName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var output = items.Skip((input.SkipCount - 1) * input.MaxResultCount).Take(input.MaxResultCount)
|
||||||
|
.OrderByDescending(x => x.LastRunTime)
|
||||||
|
.ToList();
|
||||||
|
return new PagedResultDto<TaskGetListOutput>(items.Count(), output.Adapt<List<TaskGetListOutput>>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建job
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task CreateAsync(TaskCreateInput input)
|
||||||
|
{
|
||||||
|
var scheduler = await _schedulerFactory.GetScheduler();
|
||||||
|
|
||||||
|
//设置启动时执行一次,然后最大只执行一次
|
||||||
|
|
||||||
|
|
||||||
|
//jobBuilder
|
||||||
|
var jobClassType = Assembly.Load(input.AssemblyName).GetTypes().Where(x => x.Name == input.JobType).FirstOrDefault();
|
||||||
|
|
||||||
|
if (jobClassType is null)
|
||||||
|
{
|
||||||
|
throw new UserFriendlyException($"程序集:{input.AssemblyName},{input.JobType} 不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
var jobBuilder = JobBuilder.Create(jobClassType).WithIdentity(new JobKey(input.JobId, input.GroupName))
|
||||||
|
.WithDescription(input.Description);
|
||||||
|
if (!input.Concurrent)
|
||||||
|
{
|
||||||
|
jobBuilder.DisallowConcurrentExecution();
|
||||||
|
}
|
||||||
|
|
||||||
|
//triggerBuilder
|
||||||
|
TriggerBuilder triggerBuilder = null;
|
||||||
|
switch (input.Type)
|
||||||
|
{
|
||||||
|
case JobTypeEnum.Cron:
|
||||||
|
triggerBuilder =
|
||||||
|
TriggerBuilder.Create()
|
||||||
|
.WithCronSchedule(input.Cron);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case JobTypeEnum.Millisecond:
|
||||||
|
triggerBuilder =
|
||||||
|
TriggerBuilder.Create().StartNow()
|
||||||
|
.WithSimpleSchedule(x => x
|
||||||
|
.WithInterval(TimeSpan.FromMilliseconds(input.Millisecond ?? 10000))
|
||||||
|
.RepeatForever()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//作业计划,单个jobBuilder与多个triggerBuilder组合
|
||||||
|
await scheduler.ScheduleJob(jobBuilder.Build(), triggerBuilder.Build());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除job
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task DeleteAsync(IEnumerable<string> id)
|
||||||
|
{
|
||||||
|
var scheduler = await _schedulerFactory.GetScheduler();
|
||||||
|
await scheduler.DeleteJobs(id.Select(x => new JobKey(x)).ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 暂停job
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="jobId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPut]
|
||||||
|
public async Task PauseAsync(string jobId)
|
||||||
|
{
|
||||||
|
var scheduler = await _schedulerFactory.GetScheduler();
|
||||||
|
await scheduler.PauseJob(new JobKey(jobId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始job
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="jobId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPut]
|
||||||
|
public async Task StartAsync(string jobId)
|
||||||
|
{
|
||||||
|
var scheduler = await _schedulerFactory.GetScheduler();
|
||||||
|
await scheduler.ResumeJob(new JobKey(jobId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新job
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task UpdateAsync(string id, TaskUpdateInput input)
|
||||||
|
{
|
||||||
|
await DeleteAsync(new List<string>() { id });
|
||||||
|
await CreateAsync(input.Adapt<TaskCreateInput>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("task/run-once/{id}")]
|
||||||
|
public async Task RunOnceAsync([FromRoute] string id)
|
||||||
|
{
|
||||||
|
var scheduler = await _schedulerFactory.GetScheduler();
|
||||||
|
var jobDetail = await scheduler.GetJobDetail(new JobKey(id));
|
||||||
|
|
||||||
|
var jobBuilder = JobBuilder.Create(jobDetail.JobType).WithIdentity(new JobKey(Guid.NewGuid().ToString()));
|
||||||
|
//设置启动时执行一次,然后最大只执行一次
|
||||||
|
var trigger = TriggerBuilder.Create().WithIdentity(Guid.NewGuid().ToString()).StartNow()
|
||||||
|
.WithSimpleSchedule(x => x
|
||||||
|
.WithIntervalInHours(1)
|
||||||
|
.WithRepeatCount(1))
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
await scheduler.ScheduleJob(jobBuilder.Build(), trigger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,15 +10,13 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Lazy.Captcha.Core" Version="2.0.7" />
|
<PackageReference Include="Lazy.Captcha.Core" Version="2.0.7" />
|
||||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.7" />
|
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.7" />
|
||||||
<PackageReference Include="Volo.Abp.BackgroundJobs.Hangfire" Version="$(AbpVersion)" />
|
<PackageReference Include="Volo.Abp.BackgroundWorkers.Quartz" Version="$(AbpVersion)" />
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\framework\Yi.Framework.Ddd.Application\Yi.Framework.Ddd.Application.csproj" />
|
<ProjectReference Include="..\..\..\framework\Yi.Framework.Ddd.Application\Yi.Framework.Ddd.Application.csproj" />
|
||||||
<ProjectReference Include="..\Yi.Framework.Rbac.Application.Contracts\Yi.Framework.Rbac.Application.Contracts.csproj" />
|
<ProjectReference Include="..\Yi.Framework.Rbac.Application.Contracts\Yi.Framework.Rbac.Application.Contracts.csproj" />
|
||||||
<ProjectReference Include="..\Yi.Framework.Rbac.Domain\Yi.Framework.Rbac.Domain.csproj" />
|
<ProjectReference Include="..\Yi.Framework.Rbac.Domain\Yi.Framework.Rbac.Domain.csproj" />
|
||||||
<ProjectReference Include="..\..\..\framework\Yi.Framework.BackgroundWorkers.Hangfire\Yi.Framework.BackgroundWorkers.Hangfire.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
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.Hangfire;
|
using Volo.Abp.BackgroundWorkers.Quartz;
|
||||||
using Volo.Abp.Modularity;
|
using Volo.Abp.Modularity;
|
||||||
using Yi.Framework.Ddd.Application;
|
using Yi.Framework.Ddd.Application;
|
||||||
using Yi.Framework.Rbac.Application.Contracts;
|
using Yi.Framework.Rbac.Application.Contracts;
|
||||||
@@ -16,7 +16,8 @@ namespace Yi.Framework.Rbac.Application
|
|||||||
typeof(YiFrameworkRbacDomainModule),
|
typeof(YiFrameworkRbacDomainModule),
|
||||||
|
|
||||||
|
|
||||||
typeof(YiFrameworkDddApplicationModule)
|
typeof(YiFrameworkDddApplicationModule),
|
||||||
|
typeof(AbpBackgroundWorkersQuartzModule)
|
||||||
)]
|
)]
|
||||||
public class YiFrameworkRbacApplicationModule : AbpModule
|
public class YiFrameworkRbacApplicationModule : AbpModule
|
||||||
{
|
{
|
||||||
@@ -27,6 +28,7 @@ namespace Yi.Framework.Rbac.Application
|
|||||||
service.AddCaptcha(options =>
|
service.AddCaptcha(options =>
|
||||||
{
|
{
|
||||||
options.CaptchaType = CaptchaType.ARITHMETIC;
|
options.CaptchaType = CaptchaType.ARITHMETIC;
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ namespace Yi.Framework.Rbac.Domain
|
|||||||
{
|
{
|
||||||
var service = context.Services;
|
var service = context.Services;
|
||||||
var configuration = context.Services.GetConfiguration();
|
var configuration = context.Services.GetConfiguration();
|
||||||
service.AddControllers(options =>
|
// service.AddControllers(options =>
|
||||||
{
|
// {
|
||||||
options.Filters.Add<PermissionGlobalAttribute>();
|
// options.Filters.Add<PermissionGlobalAttribute>();
|
||||||
options.Filters.Add<OperLogGlobalAttribute>();
|
// // options.Filters.Add<OperLogGlobalAttribute>();
|
||||||
});
|
// });
|
||||||
|
|
||||||
//配置阿里云短信
|
//配置阿里云短信
|
||||||
Configure<AliyunOptions>(configuration.GetSection(nameof(AliyunOptions)));
|
Configure<AliyunOptions>(configuration.GetSection(nameof(AliyunOptions)));
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
|
|||||||
OrderNum = 100
|
OrderNum = 100
|
||||||
};
|
};
|
||||||
entities.Add(system);
|
entities.Add(system);
|
||||||
|
|
||||||
//系统监控
|
//系统监控
|
||||||
MenuAggregateRoot monitoring = new MenuAggregateRoot(_guidGenerator.Create())
|
MenuAggregateRoot monitoring = new MenuAggregateRoot(_guidGenerator.Create())
|
||||||
{
|
{
|
||||||
@@ -64,7 +64,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
|
|||||||
};
|
};
|
||||||
entities.Add(online);
|
entities.Add(online);
|
||||||
|
|
||||||
|
|
||||||
//Yi框架
|
//Yi框架
|
||||||
MenuAggregateRoot guide = new MenuAggregateRoot(_guidGenerator.Create())
|
MenuAggregateRoot guide = new MenuAggregateRoot(_guidGenerator.Create())
|
||||||
{
|
{
|
||||||
@@ -77,7 +77,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
|
|||||||
Component = null
|
Component = null
|
||||||
};
|
};
|
||||||
entities.Add(guide);
|
entities.Add(guide);
|
||||||
|
|
||||||
//用户管理
|
//用户管理
|
||||||
MenuAggregateRoot user = new MenuAggregateRoot(_guidGenerator.Create())
|
MenuAggregateRoot user = new MenuAggregateRoot(_guidGenerator.Create())
|
||||||
{
|
{
|
||||||
@@ -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 = "重置密码",
|
||||||
@@ -408,7 +408,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
|
|||||||
IsDeleted = false
|
IsDeleted = false
|
||||||
};
|
};
|
||||||
entities.Add(postRemove);
|
entities.Add(postRemove);
|
||||||
|
|
||||||
|
|
||||||
//操作日志
|
//操作日志
|
||||||
MenuAggregateRoot operationLog = new MenuAggregateRoot(_guidGenerator.Create())
|
MenuAggregateRoot operationLog = new MenuAggregateRoot(_guidGenerator.Create())
|
||||||
@@ -491,78 +491,10 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
|
|||||||
OrderNum = 100,
|
OrderNum = 100,
|
||||||
ParentId = loginLog.Id,
|
ParentId = loginLog.Id,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
|
|
||||||
};
|
};
|
||||||
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 =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using Volo.Abp.Modularity;
|
||||||
|
using Volo.Abp.TenantManagement;
|
||||||
|
|
||||||
|
namespace YiFrameworkTenantManagementDomain.Shared
|
||||||
|
{
|
||||||
|
[DependsOn(typeof(AbpTenantManagementDomainSharedModule))]
|
||||||
|
public class YiFrameworkTenantManagementDomainSharedModule : AbpModule
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
@@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
37
Yi.Abp.Net8/sample/Acme.BookStore.Web/Program.cs
Normal 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();
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
198
Yi.Abp.Net8/sample/Acme.BookStore.Web/YiAbpWebModule.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
73
Yi.Abp.Net8/sample/Acme.BookStore.Web/appsettings.json
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/ip2region.db
Normal file
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/0.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/1.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/10.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/11.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/12.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/13.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/14.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/2.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/3.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/4.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/5.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/6.png
Normal file
|
After Width: | Height: | Size: 119 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/8.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/icon/9.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
Yi.Abp.Net8/sample/Acme.BookStore.Web/wwwroot/logo.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
@@ -1,13 +1,15 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Volo.Abp.BackgroundWorkers.Hangfire;
|
using Quartz;
|
||||||
|
using Quartz.Logging;
|
||||||
|
using Volo.Abp.BackgroundWorkers.Quartz;
|
||||||
using Volo.Abp.Data;
|
using Volo.Abp.Data;
|
||||||
using Yi.Framework.Rbac.Domain.Entities;
|
using Yi.Framework.Rbac.Domain.Entities;
|
||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||||
|
|
||||||
namespace Yi.Abp.Application.Jobs
|
namespace Yi.Abp.Application.Jobs
|
||||||
{
|
{
|
||||||
public class DemoResetJob : HangfireBackgroundWorkerBase
|
public class DemoResetJob : QuartzBackgroundWorkerBase
|
||||||
{
|
{
|
||||||
private ISqlSugarDbContext _dbContext;
|
private ISqlSugarDbContext _dbContext;
|
||||||
private ILogger<DemoResetJob> _logger => LoggerFactory.CreateLogger<DemoResetJob>();
|
private ILogger<DemoResetJob> _logger => LoggerFactory.CreateLogger<DemoResetJob>();
|
||||||
@@ -16,15 +18,15 @@ namespace Yi.Abp.Application.Jobs
|
|||||||
public DemoResetJob(ISqlSugarDbContext dbContext, IDataSeeder dataSeeder, IConfiguration configuration)
|
public DemoResetJob(ISqlSugarDbContext dbContext, IDataSeeder dataSeeder, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
_dbContext = dbContext;
|
||||||
RecurringJobId = "重置demo环境";
|
JobDetail = JobBuilder.Create<DemoResetJob>().WithIdentity(nameof(DemoResetJob)).Build();
|
||||||
//每天1点和13点进行重置demo环境
|
|
||||||
CronExpression = "0 0 1,13 * * ?";
|
//每天01点与13点,演示环境进行重置
|
||||||
|
Trigger = TriggerBuilder.Create().WithIdentity(nameof(DemoResetJob)).WithCronSchedule("0 0 1,13 * * ? ").Build();
|
||||||
|
// Trigger = TriggerBuilder.Create().WithIdentity(nameof(DemoResetJob)).WithSimpleSchedule(x=>x.WithIntervalInSeconds(10)).Build();
|
||||||
_dataSeeder = dataSeeder;
|
_dataSeeder = dataSeeder;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
}
|
}
|
||||||
|
public override async Task Execute(IJobExecutionContext context)
|
||||||
public override async Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken())
|
|
||||||
{
|
{
|
||||||
//开启演示环境重置功能
|
//开启演示环境重置功能
|
||||||
if (_configuration.GetSection("EnableDemoReset").Get<bool>())
|
if (_configuration.GetSection("EnableDemoReset").Get<bool>())
|
||||||
@@ -48,6 +50,7 @@ namespace Yi.Abp.Application.Jobs
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Hangfire;
|
using Quartz;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using Volo.Abp.BackgroundWorkers.Hangfire;
|
using Volo.Abp.BackgroundWorkers.Quartz;
|
||||||
using Volo.Abp.Domain.Repositories;
|
using Volo.Abp.Domain.Repositories;
|
||||||
using Volo.Abp.Uow;
|
using Volo.Abp.Uow;
|
||||||
using Yi.Framework.Rbac.Domain.Entities;
|
using Yi.Framework.Rbac.Domain.Entities;
|
||||||
@@ -11,21 +11,26 @@ namespace Yi.Abp.Application.Jobs
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 定时任务
|
/// 定时任务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TestJob : HangfireBackgroundWorkerBase
|
public class TestJob : QuartzBackgroundWorkerBase
|
||||||
{
|
{
|
||||||
private ISqlSugarRepository<UserAggregateRoot> _repository;
|
private ISqlSugarRepository<UserAggregateRoot> _repository;
|
||||||
public TestJob(ISqlSugarRepository<UserAggregateRoot> repository)
|
public TestJob(ISqlSugarRepository<UserAggregateRoot> repository)
|
||||||
{
|
{
|
||||||
_repository = repository;
|
_repository = repository;
|
||||||
RecurringJobId = "测试";
|
JobDetail = JobBuilder.Create<TestJob>().WithIdentity(nameof(TestJob)).Build();
|
||||||
//每天一次
|
Trigger = TriggerBuilder.Create().WithIdentity(nameof(TestJob)).StartNow()
|
||||||
CronExpression = Cron.Daily();
|
.WithSimpleSchedule(x => x
|
||||||
|
.WithIntervalInSeconds(1000 * 60)
|
||||||
|
.RepeatForever())
|
||||||
|
.Build();
|
||||||
}
|
}
|
||||||
public override Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken())
|
public override async Task Execute(IJobExecutionContext context)
|
||||||
{
|
{
|
||||||
//定时任务,非常简单
|
//定时任务,非常简单
|
||||||
Console.WriteLine("你好,世界");
|
Console.WriteLine("你好,世界");
|
||||||
return Task.CompletedTask;
|
// var eneities= await _repository.GetListAsync();
|
||||||
|
//var entities= await _sqlSugarClient.Queryable<UserEntity>().ToListAsync();
|
||||||
|
//await Console.Out.WriteLineAsync(entities.Count().ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ using Volo.Abp.Application.Services;
|
|||||||
using Volo.Abp.Settings;
|
using Volo.Abp.Settings;
|
||||||
using Volo.Abp.Uow;
|
using Volo.Abp.Uow;
|
||||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.Banner;
|
using Yi.Framework.Bbs.Application.Contracts.Dtos.Banner;
|
||||||
|
using Yi.Framework.Bbs.Application.Contracts.Dtos.Comment;
|
||||||
|
using Yi.Framework.Bbs.Application.Contracts.IServices;
|
||||||
using Yi.Framework.Bbs.Domain.Entities.Forum;
|
using Yi.Framework.Bbs.Domain.Entities.Forum;
|
||||||
using Yi.Framework.Rbac.Domain.Authorization;
|
using Yi.Framework.Rbac.Domain.Authorization;
|
||||||
using Yi.Framework.Rbac.Domain.Extensions;
|
using Yi.Framework.Rbac.Domain.Extensions;
|
||||||
@@ -19,160 +21,15 @@ namespace Yi.Abp.Application.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class TestService : ApplicationService
|
public class TestService : ApplicationService
|
||||||
{
|
{
|
||||||
/// <summary>
|
[HttpGet("hello-world/string")]
|
||||||
/// 属性注入
|
public async Task<string> GetHelloWorld1(string? name)
|
||||||
/// 不推荐,坑太多,容易把自己玩死,简单的东西可以用一用
|
|
||||||
/// </summary>
|
|
||||||
public ISqlSugarRepository<BannerAggregateRoot> sqlSugarRepository { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 动态Api
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="name"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("hello-world")]
|
|
||||||
public string GetHelloWorld(string? name)
|
|
||||||
{
|
{
|
||||||
//会自动添加前缀,而不是重置,更符合习惯
|
return "1";
|
||||||
//如果需要重置以"/"根目录开头即可
|
|
||||||
//你好世界
|
|
||||||
return name ?? "HelloWord";
|
|
||||||
}
|
}
|
||||||
|
[HttpGet("hello-world/dto")]
|
||||||
/// <summary>
|
public async Task<CommentGetOutputDto> GetHelloWorld2(string? name)
|
||||||
/// 异常处理
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("error")]
|
|
||||||
public string GetError()
|
|
||||||
{
|
{
|
||||||
throw new UserFriendlyException("业务异常");
|
return new CommentGetOutputDto();
|
||||||
throw new Exception("系统异常");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SqlSugar
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<object> GetSqlSugarDbAsync()
|
|
||||||
{
|
|
||||||
//用户体验优先,可直接使用Db操作,依赖抽象
|
|
||||||
return await sqlSugarRepository._DbQueryable.ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 工作单元
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task GetUowAsync()
|
|
||||||
{
|
|
||||||
//魔改
|
|
||||||
// 用户体验优先,万金油模式,支持高并发。支持单、多线程并发安全,支持多线程工作单元,支持多线程无工作单元,支持。。。
|
|
||||||
// 请注意,如果requiresNew: true只有在没有工作单元内使用,嵌套子工作单元,默认值false即可
|
|
||||||
// 自动在各个情况处理db客户端最优解之一
|
|
||||||
int i = 3;
|
|
||||||
List<Task> tasks = new List<Task>();
|
|
||||||
await sqlSugarRepository.GetListAsync();
|
|
||||||
await sqlSugarRepository.GetListAsync();
|
|
||||||
while (i > 0)
|
|
||||||
{
|
|
||||||
tasks.Add(Task.Run(async () =>
|
|
||||||
{
|
|
||||||
await sqlSugarRepository.InsertAsync(new BannerAggregateRoot { Name = "插入2" });
|
|
||||||
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true))
|
|
||||||
{
|
|
||||||
await sqlSugarRepository.InsertAsync(new BannerAggregateRoot { Name = "插入1" });
|
|
||||||
await uow.CompleteAsync();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
await sqlSugarRepository.InsertAsync(new BannerAggregateRoot { Name = "插入3" });
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.WhenAll(tasks);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当前用户
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public void GetCurrentUser()
|
|
||||||
{
|
|
||||||
//当token鉴权之后,可以直接获取
|
|
||||||
if (CurrentUser.Id is not null)
|
|
||||||
{
|
|
||||||
//权限
|
|
||||||
CurrentUser.GetPermissions();
|
|
||||||
|
|
||||||
//角色信息
|
|
||||||
CurrentUser.GetRoleInfo();
|
|
||||||
|
|
||||||
//部门id
|
|
||||||
CurrentUser.GetDeptId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 数据权限
|
|
||||||
/// </summary>
|
|
||||||
public void GetDataFilter()
|
|
||||||
{
|
|
||||||
//这里会数据权限过滤
|
|
||||||
using (DataFilter.DisablePermissionHandler())
|
|
||||||
{
|
|
||||||
//这里不会数据权限过滤
|
|
||||||
}
|
|
||||||
//这里会数据权限过滤
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 对象映射
|
|
||||||
/// </summary>
|
|
||||||
public void GetMapper()
|
|
||||||
{
|
|
||||||
//直接无脑Adapt,无需配置
|
|
||||||
var entity = new BannerAggregateRoot();
|
|
||||||
var dto = entity.Adapt<BannerGetListOutputDto>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int RequestNumber { get; set; } = 0;
|
|
||||||
/// <summary>
|
|
||||||
/// 速率限制
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
// [DisableRateLimiting]
|
|
||||||
//[EnableRateLimiting("sliding")]
|
|
||||||
public int GetRateLimiting()
|
|
||||||
{
|
|
||||||
RequestNumber++;
|
|
||||||
return RequestNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ISettingProvider _settingProvider { get; set; }
|
|
||||||
|
|
||||||
public ISettingManager _settingManager { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 系统配置模块
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<string> GetSettingAsync()
|
|
||||||
{
|
|
||||||
//DDD需要提前定义
|
|
||||||
//默认来说,不提供修改操作,配置应该独立
|
|
||||||
var enableOrNull = await _settingProvider.GetOrNullAsync("DDD");
|
|
||||||
|
|
||||||
//如果要进行修改,可使用yi.framework下的ISettingManager
|
|
||||||
await _settingManager.SetGlobalAsync("DDD", "false");
|
|
||||||
|
|
||||||
var enableOrNull2 = await _settingManager.GetOrNullGlobalAsync("DDD");
|
|
||||||
|
|
||||||
//当然,他的独特地方,是支持来自多个模块,例如配置文件?
|
|
||||||
var result = await _settingManager.GetOrNullConfigurationAsync("Test");
|
|
||||||
|
|
||||||
|
|
||||||
return result ?? string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\framework\Yi.Framework.BackgroundWorkers.Hangfire\Yi.Framework.BackgroundWorkers.Hangfire.csproj" />
|
|
||||||
<ProjectReference Include="..\..\framework\Yi.Framework.Ddd.Application\Yi.Framework.Ddd.Application.csproj" />
|
<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\bbs\Yi.Framework.Bbs.Application\Yi.Framework.Bbs.Application.csproj" />
|
||||||
<ProjectReference Include="..\..\module\chat-hub\Yi.Framework.ChatHub.Application\Yi.Framework.ChatHub.Application.csproj" />
|
<ProjectReference Include="..\..\module\chat-hub\Yi.Framework.ChatHub.Application\Yi.Framework.ChatHub.Application.csproj" />
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Volo.Abp.SettingManagement;
|
using Volo.Abp.SettingManagement;
|
||||||
using Yi.Abp.Application.Contracts;
|
using Yi.Abp.Application.Contracts;
|
||||||
using Yi.Abp.Domain;
|
using Yi.Abp.Domain;
|
||||||
using Yi.Framework.BackgroundWorkers.Hangfire;
|
|
||||||
using Yi.Framework.Bbs.Application;
|
using Yi.Framework.Bbs.Application;
|
||||||
using Yi.Framework.ChatHub.Application;
|
using Yi.Framework.ChatHub.Application;
|
||||||
using Yi.Framework.CodeGen.Application;
|
using Yi.Framework.CodeGen.Application;
|
||||||
@@ -24,8 +23,7 @@ namespace Yi.Abp.Application
|
|||||||
typeof(YiFrameworkCodeGenApplicationModule),
|
typeof(YiFrameworkCodeGenApplicationModule),
|
||||||
typeof (YiFrameworkSettingManagementApplicationModule),
|
typeof (YiFrameworkSettingManagementApplicationModule),
|
||||||
|
|
||||||
typeof(YiFrameworkDddApplicationModule),
|
typeof(YiFrameworkDddApplicationModule)
|
||||||
typeof(YiFrameworkBackgroundWorkersHangfireModule)
|
|
||||||
)]
|
)]
|
||||||
public class YiAbpApplicationModule : AbpModule
|
public class YiAbpApplicationModule : AbpModule
|
||||||
{
|
{
|
||||||
|
|||||||
65
Yi.Abp.Net8/src/Yi.Abp.Web/AbpUnitOfWorkMiddleware2.cs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
// Decompiled with JetBrains decompiler
|
||||||
|
// Type: Volo.Abp.AspNetCore.Uow.AbpUnitOfWorkMiddleware
|
||||||
|
// Assembly: Volo.Abp.AspNetCore, Version=8.2.0.0, Culture=neutral, PublicKeyToken=null
|
||||||
|
// MVID: E24BDAEE-E92D-4420-84F7-3DD088C817A4
|
||||||
|
// Assembly location: C:\Users\Administrator\.nuget\packages\volo.abp.aspnetcore\8.2.0\lib\net8.0\Volo.Abp.AspNetCore.dll
|
||||||
|
// XML documentation location: C:\Users\Administrator\.nuget\packages\volo.abp.aspnetcore\8.2.0\lib\net8.0\Volo.Abp.AspNetCore.xml
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Components.Endpoints;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Volo.Abp.AspNetCore.Middleware;
|
||||||
|
using Volo.Abp.DependencyInjection;
|
||||||
|
using Volo.Abp.Uow;
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
namespace Volo.Abp.AspNetCore.Uow
|
||||||
|
{
|
||||||
|
public class AbpUnitOfWorkMiddleware2 : AbpMiddlewareBase, ITransientDependency
|
||||||
|
{
|
||||||
|
private readonly IUnitOfWorkManager _unitOfWorkManager;
|
||||||
|
private readonly AbpAspNetCoreUnitOfWorkOptions _options;
|
||||||
|
|
||||||
|
public AbpUnitOfWorkMiddleware2(
|
||||||
|
IUnitOfWorkManager unitOfWorkManager,
|
||||||
|
IOptions<AbpAspNetCoreUnitOfWorkOptions> options)
|
||||||
|
{
|
||||||
|
this._unitOfWorkManager = unitOfWorkManager;
|
||||||
|
this._options = options.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task InvokeAsync(HttpContext context, RequestDelegate next)
|
||||||
|
{
|
||||||
|
// await next(context);
|
||||||
|
// await next(context).ConfigureAwait(false);
|
||||||
|
if (await ShouldSkipAsync(context, next).ConfigureAwait(false) || IsIgnoredUrl(context))
|
||||||
|
{
|
||||||
|
await next(context).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using (IUnitOfWork uow = _unitOfWorkManager.Reserve("_AbpActionUnitOfWork"))
|
||||||
|
{
|
||||||
|
await next(context).ConfigureAwait(false);
|
||||||
|
await uow.CompleteAsync(context.RequestAborted).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsIgnoredUrl(HttpContext context)
|
||||||
|
{
|
||||||
|
return context.Request.Path.Value != null && this._options.IgnoredUrls.Any<string>(
|
||||||
|
(Func<string, bool>)(x =>
|
||||||
|
context.Request.Path.Value.StartsWith(x, StringComparison.OrdinalIgnoreCase)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task<bool> ShouldSkipAsync(HttpContext context, RequestDelegate next)
|
||||||
|
{
|
||||||
|
return context.GetEndpoint()?.Metadata?.GetMetadata<RootComponentMetadata>() != null ||
|
||||||
|
await base.ShouldSkipAsync(context, next).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,28 +4,30 @@ using Yi.Abp.Web;
|
|||||||
|
|
||||||
//创建日志,可使用{SourceContext}记录
|
//创建日志,可使用{SourceContext}记录
|
||||||
Log.Logger = new LoggerConfiguration()
|
Log.Logger = new LoggerConfiguration()
|
||||||
.MinimumLevel.Debug()
|
.MinimumLevel.Debug()
|
||||||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
||||||
.MinimumLevel.Override("Microsoft.AspNetCore.Hosting.Diagnostics", LogEventLevel.Error)
|
.MinimumLevel.Override("Microsoft.AspNetCore.Hosting.Diagnostics", LogEventLevel.Error)
|
||||||
.MinimumLevel.Override("Quartz", LogEventLevel.Warning)
|
.MinimumLevel.Override("Quartz", LogEventLevel.Warning)
|
||||||
.Enrich.FromLogContext()
|
.Enrich.FromLogContext()
|
||||||
.WriteTo.Async(c => c.File("logs/all/log-.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Debug))
|
.WriteTo.Async(c => c.File("logs/all/log-.txt", rollingInterval: RollingInterval.Day,
|
||||||
.WriteTo.Async(c => c.File("logs/error/errorlog-.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Error))
|
restrictedToMinimumLevel: LogEventLevel.Debug))
|
||||||
.WriteTo.Async(c => c.Console())
|
.WriteTo.Async(c => c.File("logs/error/errorlog-.txt", rollingInterval: RollingInterval.Day,
|
||||||
.CreateLogger();
|
restrictedToMinimumLevel: LogEventLevel.Error))
|
||||||
|
.WriteTo.Async(c => c.Console())
|
||||||
|
.CreateLogger();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log.Information("""
|
Log.Information("""
|
||||||
|
|
||||||
|
__ ___ ______ _
|
||||||
|
\ \ / (_) | ____| | |
|
||||||
|
\ \_/ / _ | |__ _ __ __ _ _ __ ___ _____ _____ _ __| | __
|
||||||
|
\ / | | | __| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
|
||||||
|
| | | | | | | | | (_| | | | | | | __/\ V V / (_) | | | <
|
||||||
|
|_| |_| |_| |_| \__,_|_| |_| |_|\___| \_/\_/ \___/|_| |_|\_\
|
||||||
|
|
||||||
__ ___ ______ _
|
""");
|
||||||
\ \ / (_) | ____| | |
|
|
||||||
\ \_/ / _ | |__ _ __ __ _ _ __ ___ _____ _____ _ __| | __
|
|
||||||
\ / | | | __| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
|
|
||||||
| | | | | | | | | (_| | | | | | | __/\ V V / (_) | | | <
|
|
||||||
|_| |_| |_| |_| \__,_|_| |_| |_|\___| \_/\_/ \___/|_| |_|\_\
|
|
||||||
|
|
||||||
""");
|
|
||||||
Log.Information("Yi框架-Abp.vNext,启动!");
|
Log.Information("Yi框架-Abp.vNext,启动!");
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
@@ -36,6 +38,22 @@ try
|
|||||||
builder.Host.UseSerilog();
|
builder.Host.UseSerilog();
|
||||||
await builder.Services.AddApplicationAsync<YiAbpWebModule>();
|
await builder.Services.AddApplicationAsync<YiAbpWebModule>();
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
app.Use(async (http, next) =>
|
||||||
|
{
|
||||||
|
var id = Guid.NewGuid();
|
||||||
|
Console.WriteLine("之前-----" + id);
|
||||||
|
http.Response.OnStarting(() =>
|
||||||
|
{
|
||||||
|
Console.WriteLine("之中-----" + id);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
});
|
||||||
|
await next();
|
||||||
|
if (http.Request.Path.Value.Contains("hello-world"))
|
||||||
|
{
|
||||||
|
Console.WriteLine("之后-----" + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
await app.InitializeApplicationAsync();
|
await app.InitializeApplicationAsync();
|
||||||
await app.RunAsync();
|
await app.RunAsync();
|
||||||
}
|
}
|
||||||
|
|||||||
42
Yi.Abp.Net8/src/Yi.Abp.Web/TestService.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Volo.Abp.Application.Services;
|
||||||
|
|
||||||
|
namespace Yi.Abp.Application.Services
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 常用魔改及扩展示例
|
||||||
|
/// </summary>
|
||||||
|
public class TestService : ApplicationService
|
||||||
|
{
|
||||||
|
[HttpGet("hello-world/string")]
|
||||||
|
public async Task<string> GetHelloWorld1(string? name)
|
||||||
|
{
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
|
[HttpGet("hello-world/dto")]
|
||||||
|
public async Task<CommentGetOutputDto> GetHelloWorld2(string? name)
|
||||||
|
{
|
||||||
|
return new CommentGetOutputDto();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CommentGetOutputDto
|
||||||
|
{
|
||||||
|
|
||||||
|
public DateTime? CreateTime { get; set; }
|
||||||
|
public string Content { get; set; }
|
||||||
|
|
||||||
|
public Guid DiscussId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根节点的评论id
|
||||||
|
/// </summary>
|
||||||
|
public Guid RootId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 被回复的CommentId
|
||||||
|
/// </summary>
|
||||||
|
public Guid ParentId { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,8 +8,6 @@
|
|||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Hangfire.MemoryStorage" Version="1.8.1.1" />
|
|
||||||
<PackageReference Include="Hangfire.Redis.StackExchange" Version="1.9.4" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.3" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.3" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" />
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" />
|
||||||
|
|||||||
@@ -1,29 +1,22 @@
|
|||||||
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 Hangfire;
|
|
||||||
using Hangfire.MemoryStorage;
|
|
||||||
using Hangfire.Redis.StackExchange;
|
|
||||||
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.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
using StackExchange.Redis;
|
using Newtonsoft.Json.Converters;
|
||||||
using Volo.Abp.AspNetCore.Auditing;
|
|
||||||
using Volo.Abp.AspNetCore.Authentication.JwtBearer;
|
using Volo.Abp.AspNetCore.Authentication.JwtBearer;
|
||||||
using Volo.Abp.AspNetCore.ExceptionHandling;
|
using Volo.Abp.AspNetCore.ExceptionHandling;
|
||||||
using Volo.Abp.AspNetCore.MultiTenancy;
|
using Volo.Abp.AspNetCore.MultiTenancy;
|
||||||
using Volo.Abp.AspNetCore.Mvc;
|
using Volo.Abp.AspNetCore.Mvc;
|
||||||
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
|
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
|
||||||
|
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
|
||||||
using Volo.Abp.AspNetCore.Serilog;
|
using Volo.Abp.AspNetCore.Serilog;
|
||||||
using Volo.Abp.Auditing;
|
using Volo.Abp.Auditing;
|
||||||
using Volo.Abp.Autofac;
|
using Volo.Abp.Autofac;
|
||||||
using Volo.Abp.BackgroundJobs.Hangfire;
|
|
||||||
using Volo.Abp.BackgroundWorkers;
|
|
||||||
using Volo.Abp.BackgroundWorkers.Hangfire;
|
|
||||||
using Volo.Abp.Caching;
|
using Volo.Abp.Caching;
|
||||||
using Volo.Abp.MultiTenancy;
|
using Volo.Abp.MultiTenancy;
|
||||||
using Volo.Abp.Swashbuckle;
|
using Volo.Abp.Swashbuckle;
|
||||||
@@ -35,12 +28,11 @@ using Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
|
|||||||
using Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
|
using Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
|
||||||
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.BackgroundWorkers.Hangfire;
|
using Yi.Framework.AspNetCore.UnifyResult;
|
||||||
using Yi.Framework.Bbs.Application;
|
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;
|
||||||
@@ -50,16 +42,14 @@ using Yi.Framework.TenantManagement.Application;
|
|||||||
namespace Yi.Abp.Web
|
namespace Yi.Abp.Web
|
||||||
{
|
{
|
||||||
[DependsOn(
|
[DependsOn(
|
||||||
typeof(YiAbpSqlSugarCoreModule),
|
// typeof(YiAbpSqlSugarCoreModule),
|
||||||
typeof(YiAbpApplicationModule),
|
// typeof(YiAbpApplicationModule),
|
||||||
typeof(AbpAspNetCoreMultiTenancyModule),
|
// typeof(AbpAspNetCoreMultiTenancyModule),
|
||||||
typeof(AbpAspNetCoreMvcModule),
|
typeof(AbpAspNetCoreMvcModule),
|
||||||
typeof(AbpAutofacModule),
|
typeof(AbpAutofacModule),
|
||||||
typeof(AbpSwashbuckleModule),
|
typeof(AbpSwashbuckleModule),
|
||||||
typeof(AbpAspNetCoreSerilogModule),
|
typeof(AbpAspNetCoreSerilogModule),
|
||||||
typeof(AbpAuditingModule),
|
// typeof(AbpAuditingModule),
|
||||||
typeof(YiFrameworkBackgroundWorkersHangfireModule),
|
|
||||||
typeof(AbpBackgroundJobsHangfireModule),
|
|
||||||
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
|
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
|
||||||
typeof(YiFrameworkAspNetCoreModule),
|
typeof(YiFrameworkAspNetCoreModule),
|
||||||
typeof(YiFrameworkAspNetCoreAuthenticationOAuthModule)
|
typeof(YiFrameworkAspNetCoreAuthenticationOAuthModule)
|
||||||
@@ -73,247 +63,48 @@ namespace Yi.Abp.Web
|
|||||||
var configuration = context.Services.GetConfiguration();
|
var configuration = context.Services.GetConfiguration();
|
||||||
var host = context.Services.GetHostingEnvironment();
|
var host = context.Services.GetHostingEnvironment();
|
||||||
var service = context.Services;
|
var service = context.Services;
|
||||||
|
|
||||||
//请求日志
|
|
||||||
Configure<AbpAuditingOptions>(optios =>
|
|
||||||
|
//动态Api
|
||||||
|
Configure<AbpAspNetCoreMvcOptions>(options =>
|
||||||
{
|
{
|
||||||
//默认关闭,开启会有大量的审计日志
|
options.ConventionalControllers.Create(typeof(YiAbpWebModule).Assembly,
|
||||||
optios.IsEnabled = true;
|
options => options.RemoteServiceName = "default");
|
||||||
|
|
||||||
|
|
||||||
|
//统一前缀
|
||||||
|
options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app");
|
||||||
});
|
});
|
||||||
//忽略审计日志路径
|
|
||||||
Configure<AbpAspNetCoreAuditingOptions>(options =>
|
//设置api格式
|
||||||
|
// service.AddControllers().AddNewtonsoftJson(options =>
|
||||||
|
// {
|
||||||
|
// options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Configure<AbpAntiForgeryOptions>(options => { options.AutoValidate = false; });
|
||||||
|
|
||||||
|
//Swagger
|
||||||
|
context.Services.AddYiSwaggerGen<YiAbpWebModule>(options =>
|
||||||
{
|
{
|
||||||
options.IgnoredUrls.Add("/api/app/file/");
|
options.SwaggerDoc("default",
|
||||||
options.IgnoredUrls.Add("/hangfire");
|
new OpenApiInfo { Title = "Yi.Framework.Abp", Version = "v1", Description = "集大成者" });
|
||||||
});
|
});
|
||||||
|
|
||||||
//采用furion格式的规范化api,默认不开启,使用abp优雅的方式
|
|
||||||
//你没看错。。。
|
|
||||||
//service.AddFurionUnifyResultApi();
|
|
||||||
|
|
||||||
//配置错误处理显示详情
|
|
||||||
Configure<AbpExceptionHandlingOptions>(options => { options.SendExceptionsDetailsToClients = true; });
|
|
||||||
|
|
||||||
//动态Api
|
|
||||||
Configure<AbpAspNetCoreMvcOptions>(options =>
|
return Task.CompletedTask;
|
||||||
{
|
}
|
||||||
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");
|
|
||||||
options.ConventionalControllers.Create(typeof(YiFrameworkChatHubApplicationModule).Assembly,
|
|
||||||
options => options.RemoteServiceName = "chat-hub");
|
|
||||||
options.ConventionalControllers.Create(
|
|
||||||
typeof(YiFrameworkTenantManagementApplicationModule).Assembly,
|
|
||||||
options => options.RemoteServiceName = "tenant-management");
|
|
||||||
options.ConventionalControllers.Create(typeof(YiFrameworkCodeGenApplicationModule).Assembly,
|
|
||||||
options => options.RemoteServiceName = "code-gen");
|
|
||||||
|
|
||||||
//统一前缀
|
|
||||||
options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app");
|
|
||||||
});
|
|
||||||
|
|
||||||
//【NewtonsoftJson严重问题!!!!!逆天】设置api格式,留给后人铭记
|
|
||||||
// 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.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter());
|
|
||||||
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
|
||||||
});
|
|
||||||
|
|
||||||
//设置缓存不要过期,默认滑动20分钟
|
|
||||||
Configure<AbpDistributedCacheOptions>(cacheOptions =>
|
|
||||||
{
|
|
||||||
cacheOptions.GlobalCacheEntryOptions.SlidingExpiration = null;
|
|
||||||
//缓存key前缀
|
|
||||||
cacheOptions.KeyPrefix = "Yi:";
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Configure<AbpAntiForgeryOptions>(options => { options.AutoValidate = false; });
|
public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
|
||||||
|
|
||||||
//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();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//配置多租户
|
|
||||||
Configure<AbpTenantResolveOptions>(options =>
|
|
||||||
{
|
|
||||||
//基于cookie jwt不好用,有坑
|
|
||||||
options.TenantResolvers.Clear();
|
|
||||||
options.TenantResolvers.Add(new HeaderTenantResolveContributor());
|
|
||||||
//options.TenantResolvers.Add(new HeaderTenantResolveContributor());
|
|
||||||
//options.TenantResolvers.Add(new CookieTenantResolveContributor());
|
|
||||||
//options.TenantResolvers.RemoveAll(x => x.Name == CookieTenantResolveContributor.ContributorName);
|
|
||||||
});
|
|
||||||
|
|
||||||
//配置Hangfire定时任务存储,开启redis后,优先使用redis
|
|
||||||
var redisConfiguration = configuration["Redis:Configuration"];
|
|
||||||
var redisEnabled = configuration["Redis:IsEnabled"];
|
|
||||||
context.Services.AddHangfire(config =>
|
|
||||||
{
|
|
||||||
if (redisEnabled.IsNullOrEmpty() || bool.Parse(redisEnabled))
|
|
||||||
{
|
|
||||||
config.UseRedisStorage(
|
|
||||||
ConnectionMultiplexer.Connect(redisConfiguration),
|
|
||||||
new RedisStorageOptions()
|
|
||||||
{
|
|
||||||
InvisibilityTimeout = TimeSpan.FromHours(1), //JOB允许执行1小时
|
|
||||||
Prefix = "Yi:HangfireJob:"
|
|
||||||
}).WithJobExpirationTimeout(TimeSpan.FromHours(1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
config.UseMemoryStorage();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//速率限制
|
|
||||||
//每60秒限制100个请求,滑块添加,分6段
|
|
||||||
service.AddRateLimiter(_ =>
|
|
||||||
{
|
|
||||||
_.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
|
|
||||||
_.OnRejected = (context, _) =>
|
|
||||||
{
|
|
||||||
if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter))
|
|
||||||
{
|
|
||||||
context.HttpContext.Response.Headers.RetryAfter =
|
|
||||||
((int)retryAfter.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
|
|
||||||
context.HttpContext.Response.WriteAsync("Too many requests. Please try again later.");
|
|
||||||
|
|
||||||
return new ValueTask();
|
|
||||||
};
|
|
||||||
|
|
||||||
//全局使用,链式表达式
|
|
||||||
_.GlobalLimiter = PartitionedRateLimiter.CreateChained(
|
|
||||||
PartitionedRateLimiter.Create<HttpContext, string>(httpContext =>
|
|
||||||
{
|
|
||||||
var userAgent = httpContext.Request.Headers.UserAgent.ToString();
|
|
||||||
|
|
||||||
return RateLimitPartition.GetSlidingWindowLimiter
|
|
||||||
(userAgent, _ =>
|
|
||||||
new SlidingWindowRateLimiterOptions
|
|
||||||
{
|
|
||||||
PermitLimit = 1000,
|
|
||||||
Window = TimeSpan.FromSeconds(60),
|
|
||||||
SegmentsPerWindow = 6,
|
|
||||||
QueueProcessingOrder = QueueProcessingOrder.OldestFirst
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//jwt鉴权
|
|
||||||
var jwtOptions = configuration.GetSection(nameof(JwtOptions)).Get<JwtOptions>();
|
|
||||||
var refreshJwtOptions = configuration.GetSection(nameof(RefreshJwtOptions)).Get<RefreshJwtOptions>();
|
|
||||||
|
|
||||||
context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
|
||||||
.AddJwtBearer(options =>
|
|
||||||
{
|
|
||||||
options.TokenValidationParameters = new TokenValidationParameters
|
|
||||||
{
|
|
||||||
ClockSkew = TimeSpan.Zero,
|
|
||||||
ValidateIssuerSigningKey = true,
|
|
||||||
ValidIssuer = jwtOptions.Issuer,
|
|
||||||
ValidAudience = jwtOptions.Audience,
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.AddJwtBearer(TokenTypeConst.Refresh, options =>
|
|
||||||
{
|
|
||||||
options.TokenValidationParameters = new TokenValidationParameters
|
|
||||||
{
|
|
||||||
ClockSkew = TimeSpan.Zero,
|
|
||||||
ValidateIssuerSigningKey = true,
|
|
||||||
ValidIssuer = refreshJwtOptions.Issuer,
|
|
||||||
ValidAudience = refreshJwtOptions.Audience,
|
|
||||||
IssuerSigningKey =
|
|
||||||
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(refreshJwtOptions.SecurityKey))
|
|
||||||
};
|
|
||||||
options.Events = new JwtBearerEvents
|
|
||||||
{
|
|
||||||
OnMessageReceived = context =>
|
|
||||||
{
|
|
||||||
var refresh_token = context.Request.Headers["refresh_token"];
|
|
||||||
if (!string.IsNullOrEmpty(refresh_token))
|
|
||||||
{
|
|
||||||
context.Token = refresh_token;
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
var refreshToken = context.Request.Query["refresh_token"];
|
|
||||||
if (!string.IsNullOrEmpty(refreshToken))
|
|
||||||
{
|
|
||||||
context.Token = refreshToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 async 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();
|
||||||
|
|
||||||
@@ -322,30 +113,17 @@ namespace Yi.Abp.Web
|
|||||||
//跨域
|
//跨域
|
||||||
app.UseCors(DefaultCorsPolicyName);
|
app.UseCors(DefaultCorsPolicyName);
|
||||||
|
|
||||||
if (!env.IsDevelopment())
|
|
||||||
{
|
|
||||||
//速率限制
|
|
||||||
app.UseRateLimiter();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//无感token,先刷新再鉴权
|
|
||||||
app.UseRefreshToken();
|
|
||||||
|
|
||||||
//鉴权
|
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
|
|
||||||
//多租户
|
|
||||||
app.UseMultiTenancy();
|
|
||||||
|
|
||||||
//swagger
|
//swagger
|
||||||
app.UseYiSwagger();
|
app.UseYiSwagger();
|
||||||
|
|
||||||
//流量访问统计,需redis支持,否则不生效
|
|
||||||
app.UseAccessLog();
|
|
||||||
|
|
||||||
//请求处理
|
|
||||||
app.UseYiApiHandlinge();
|
|
||||||
|
|
||||||
//静态资源
|
//静态资源
|
||||||
app.UseStaticFiles("/api/app/wwwroot");
|
app.UseStaticFiles("/api/app/wwwroot");
|
||||||
@@ -353,27 +131,20 @@ namespace Yi.Abp.Web
|
|||||||
app.UseDirectoryBrowser("/api/app/wwwroot");
|
app.UseDirectoryBrowser("/api/app/wwwroot");
|
||||||
|
|
||||||
|
|
||||||
// app.Properties.Add("_AbpExceptionHandlingMiddleware_Added",false);
|
|
||||||
//工作单元
|
//工作单元
|
||||||
app.UseUnitOfWork();
|
app.UseUnitOfWork();
|
||||||
|
|
||||||
//授权
|
//授权
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
//审计日志
|
|
||||||
app.UseAuditing();
|
|
||||||
|
|
||||||
//日志记录
|
//日志记录
|
||||||
app.UseAbpSerilogEnrichers();
|
app.UseAbpSerilogEnrichers();
|
||||||
|
|
||||||
//Hangfire定时任务面板,可配置授权
|
|
||||||
app.UseAbpHangfireDashboard("/hangfire", options =>
|
|
||||||
{
|
|
||||||
// options.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() };
|
|
||||||
});
|
|
||||||
|
|
||||||
//终节点
|
//终节点
|
||||||
app.UseConfiguredEndpoints();
|
app.UseConfiguredEndpoints();
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
using Volo.Abp.Auditing;
|
using Volo.Abp.Auditing;
|
||||||
using Volo.Abp.Autofac;
|
using Volo.Abp.Autofac;
|
||||||
using Volo.Abp.BackgroundWorkers;
|
using Volo.Abp.BackgroundWorkers;
|
||||||
|
using Volo.Abp.BackgroundWorkers.Quartz;
|
||||||
|
using Volo.Abp.Domain.Repositories;
|
||||||
using Yi.Framework.Rbac.Application;
|
using Yi.Framework.Rbac.Application;
|
||||||
using Yi.Framework.Rbac.Domain.Entities;
|
using Yi.Framework.Rbac.Domain.Entities;
|
||||||
using Yi.Framework.Rbac.Domain.Managers;
|
using Yi.Framework.Rbac.Domain.Managers;
|
||||||
@@ -22,11 +24,10 @@ namespace Yi.Framework.Rbac.Test
|
|||||||
{
|
{
|
||||||
public override void ConfigureServices(ServiceConfigurationContext context)
|
public override void ConfigureServices(ServiceConfigurationContext context)
|
||||||
{
|
{
|
||||||
|
Configure<AbpBackgroundWorkerQuartzOptions>(options =>
|
||||||
// Configure<AbpBackgroundWorkerQuartzOptions>(options =>
|
{
|
||||||
// {
|
options.IsAutoRegisterEnabled = false;
|
||||||
// options.IsAutoRegisterEnabled = false;
|
});
|
||||||
// });
|
|
||||||
Configure<AbpBackgroundWorkerOptions> (options =>
|
Configure<AbpBackgroundWorkerOptions> (options =>
|
||||||
{
|
{
|
||||||
options.IsEnabled = false; //禁用作业执行
|
options.IsEnabled = false; //禁用作业执行
|
||||||
@@ -34,6 +35,7 @@ namespace Yi.Framework.Rbac.Test
|
|||||||
Configure<DbConnOptions>(options =>
|
Configure<DbConnOptions>(options =>
|
||||||
{
|
{
|
||||||
options.Url = $"DataSource=yi-rbac-test-{DateTime.Now.ToString("yyyyMMdd_HHmmss")}.db";
|
options.Url = $"DataSource=yi-rbac-test-{DateTime.Now.ToString("yyyyMMdd_HHmmss")}.db";
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
/// 数据库提供者
|
/// 数据库提供者
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
/// 数据库提供者
|
/// 数据库提供者
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||