Merge branch 'refs/heads/abp' into digital-collectibles
1
.gitignore
vendored
@@ -269,6 +269,7 @@ dist
|
||||
/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.Production.json
|
||||
/Yi.Abp.Net8/tool/Yi.Abp.Tool.Web/appsettings.Development.json
|
||||
database_backup
|
||||
/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.Staging.json
|
||||
/Yi.Abp.Net8/src/Yi.Abp.Web/logs/
|
||||
|
||||
@@ -80,20 +80,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AuditLogging.S
|
||||
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}"
|
||||
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}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tenant-management", "tenant-management", "{499A8C71-7892-42D0-A77E-48756E1EFF16}"
|
||||
@@ -290,30 +276,6 @@ Global
|
||||
{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.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.Build.0 = Debug|Any CPU
|
||||
{68627BC2-F049-4C69-AD17-81DF9478E8CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -499,12 +461,6 @@ Global
|
||||
{73CCF2C4-B9FD-44AB-8D4B-0A421805B094} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853}
|
||||
{48806510-8E18-4E1E-9BAF-5B97E88C5FC3} = {73CCF2C4-B9FD-44AB-8D4B-0A421805B094}
|
||||
{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}
|
||||
{499A8C71-7892-42D0-A77E-48756E1EFF16} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853}
|
||||
{FA5BBAA1-08DC-472F-BB2C-5314E59D1556} = {499A8C71-7892-42D0-A77E-48756E1EFF16}
|
||||
|
||||
@@ -36,15 +36,18 @@ namespace Yi.Framework.SqlSugarCore
|
||||
|
||||
protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled<ISoftDelete>() ?? false;
|
||||
|
||||
private IEntityChangeEventHelper EntityChangeEventHelper => LazyServiceProvider.LazyGetService<IEntityChangeEventHelper>(NullEntityChangeEventHelper.Instance);
|
||||
private IEntityChangeEventHelper EntityChangeEventHelper =>
|
||||
LazyServiceProvider.LazyGetService<IEntityChangeEventHelper>(NullEntityChangeEventHelper.Instance);
|
||||
|
||||
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)
|
||||
{
|
||||
SqlSugarClient = sqlSugarClient;
|
||||
}
|
||||
|
||||
public SqlSugarDbContext(IAbpLazyServiceProvider lazyServiceProvider)
|
||||
{
|
||||
LazyServiceProvider = lazyServiceProvider;
|
||||
@@ -73,12 +76,14 @@ namespace Yi.Framework.SqlSugarCore
|
||||
protected virtual string GetCurrentConnectionString()
|
||||
{
|
||||
var connectionStringResolver = LazyServiceProvider.LazyGetRequiredService<IConnectionStringResolver>();
|
||||
var connectionString = connectionStringResolver.ResolveAsync().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
var connectionString =
|
||||
connectionStringResolver.ResolveAsync().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(connectionString))
|
||||
{
|
||||
Check.NotNull(Options.Url, "dbUrl未配置");
|
||||
}
|
||||
|
||||
return connectionString!;
|
||||
}
|
||||
|
||||
@@ -92,6 +97,7 @@ namespace Yi.Framework.SqlSugarCore
|
||||
return dbTypeFromTenantName.Value;
|
||||
}
|
||||
}
|
||||
|
||||
Check.NotNull(Options.DbType, "默认DbType未配置!");
|
||||
return Options.DbType!.Value;
|
||||
}
|
||||
@@ -126,7 +132,6 @@ namespace Yi.Framework.SqlSugarCore
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 上下文对象扩展
|
||||
/// </summary>
|
||||
@@ -138,21 +143,23 @@ namespace Yi.Framework.SqlSugarCore
|
||||
{
|
||||
sqlSugarClient.QueryFilter.AddTableFilter<ISoftDelete>(u => u.IsDeleted == false);
|
||||
}
|
||||
|
||||
if (IsMultiTenantFilterEnabled)
|
||||
{
|
||||
//表达式里只能有具体值,不能运算
|
||||
var expressionCurrentTenant = CurrentTenant.Id ?? null;
|
||||
sqlSugarClient.QueryFilter.AddTableFilter<IMultiTenant>(u => u.TenantId == expressionCurrentTenant);
|
||||
}
|
||||
|
||||
CustomDataFilter(sqlSugarClient);
|
||||
}
|
||||
|
||||
protected virtual void CustomDataFilter(ISqlSugarClient sqlSugarClient)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void DataExecuted(object oldValue, DataAfterModel entityInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -174,16 +181,24 @@ namespace Yi.Framework.SqlSugarCore
|
||||
entityInfo.SetValue(DateTime.Now);
|
||||
}
|
||||
}
|
||||
if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.LastModifierId)))
|
||||
else if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.LastModifierId)))
|
||||
{
|
||||
if (typeof(Guid?) == entityInfo.EntityColumnInfo.PropertyInfo.PropertyType)
|
||||
{
|
||||
if (CurrentUser.Id != null)
|
||||
{
|
||||
entityInfo.SetValue(CurrentUser.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case DataFilterType.InsertByObject:
|
||||
|
||||
if (entityInfo.PropertyName.Equals(nameof(IEntity<Guid>.Id)))
|
||||
{
|
||||
//类型为guid
|
||||
if (typeof(Guid) == entityInfo.EntityColumnInfo.PropertyInfo.PropertyType)
|
||||
{
|
||||
//主键为空或者为默认最小值
|
||||
if (Guid.Empty.Equals(oldValue))
|
||||
@@ -191,8 +206,9 @@ namespace Yi.Framework.SqlSugarCore
|
||||
entityInfo.SetValue(GuidGenerator.Create());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreationTime)))
|
||||
else if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreationTime)))
|
||||
{
|
||||
//为空或者为默认最小值
|
||||
if (DateTime.MinValue.Equals(oldValue))
|
||||
@@ -200,21 +216,26 @@ namespace Yi.Framework.SqlSugarCore
|
||||
entityInfo.SetValue(DateTime.Now);
|
||||
}
|
||||
}
|
||||
if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreatorId)))
|
||||
else if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreatorId)))
|
||||
{
|
||||
//类型为guid
|
||||
if (typeof(Guid?) == entityInfo.EntityColumnInfo.PropertyInfo.PropertyType)
|
||||
{
|
||||
if (CurrentUser.Id is not null)
|
||||
{
|
||||
entityInfo.SetValue(CurrentUser.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entityInfo.PropertyName.Equals(nameof(IMultiTenant.TenantId)))
|
||||
else if (entityInfo.PropertyName.Equals(nameof(IMultiTenant.TenantId)))
|
||||
{
|
||||
if (CurrentTenant.Id is not null)
|
||||
{
|
||||
entityInfo.SetValue(CurrentTenant.Id);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -227,6 +248,7 @@ namespace Yi.Framework.SqlSugarCore
|
||||
{
|
||||
EntityChangeEventHelper.PublishEntityCreatedEvent(entityInfo.EntityValue);
|
||||
}
|
||||
|
||||
break;
|
||||
case DataFilterType.UpdateByObject:
|
||||
if (entityInfo.PropertyName == nameof(IEntity<object>.Id))
|
||||
@@ -243,8 +265,8 @@ namespace Yi.Framework.SqlSugarCore
|
||||
{
|
||||
EntityChangeEventHelper.PublishEntityUpdatedEvent(entityInfo.EntityValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case DataFilterType.DeleteByObject:
|
||||
if (entityInfo.PropertyName == nameof(IEntity<object>.Id))
|
||||
@@ -254,14 +276,13 @@ namespace Yi.Framework.SqlSugarCore
|
||||
{
|
||||
foreach (var entityValue in entityValues)
|
||||
{
|
||||
|
||||
EntityChangeEventHelper.PublishEntityDeletedEvent(entityValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -280,7 +301,6 @@ namespace Yi.Framework.SqlSugarCore
|
||||
sb.AppendLine("===============================");
|
||||
Logger.CreateLogger<SqlSugarDbContext>().LogDebug(sb.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -306,14 +326,14 @@ namespace Yi.Framework.SqlSugarCore
|
||||
{
|
||||
if (property.Name == nameof(IHasConcurrencyStamp.ConcurrencyStamp)) //带版本号并发更新
|
||||
{
|
||||
// column.IsOnlyIgnoreInsert = true;
|
||||
// column.IsOnlyIgnoreUpdate = true;
|
||||
column.IsEnableUpdateVersionValidation = true;
|
||||
}
|
||||
|
||||
if (property.PropertyType == typeof(ExtraPropertyDictionary))
|
||||
{
|
||||
column.IsIgnore = true;
|
||||
}
|
||||
|
||||
if (property.Name == nameof(Entity<object>.Id))
|
||||
{
|
||||
column.IsPrimarykey = true;
|
||||
@@ -328,11 +348,13 @@ namespace Yi.Framework.SqlSugarCore
|
||||
{
|
||||
Directory.CreateDirectory(directoryName);
|
||||
}
|
||||
|
||||
switch (Options.DbType)
|
||||
{
|
||||
case DbType.MySql:
|
||||
//MySql
|
||||
SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database, $"{Path.Combine(directoryName, fileName)}.sql");//mysql 只支持.net core
|
||||
SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database,
|
||||
$"{Path.Combine(directoryName, fileName)}.sql"); //mysql 只支持.net core
|
||||
break;
|
||||
|
||||
|
||||
@@ -344,19 +366,14 @@ namespace Yi.Framework.SqlSugarCore
|
||||
|
||||
case DbType.SqlServer:
|
||||
//SqlServer
|
||||
SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database, $"{Path.Combine(directoryName, fileName)}.bak"/*服务器路径*/);//第一个参数库名
|
||||
SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database,
|
||||
$"{Path.Combine(directoryName, fileName)}.bak" /*服务器路径*/); //第一个参数库名
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
throw new NotImplementedException("其他数据库备份未实现");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<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>
|
||||
@@ -1,24 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<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>
|
||||
@@ -1,36 +0,0 @@
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
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";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<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>
|
||||
@@ -1,21 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
<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>
|
||||
@@ -1,24 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<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>
|
||||
@@ -1,50 +0,0 @@
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
<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>
|
||||
@@ -1,37 +0,0 @@
|
||||
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();
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"$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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 9.9 KiB |
@@ -14,6 +14,10 @@ namespace Yi.Abp.Tool.Application.Contracts.Dtos
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模块类型
|
||||
/// </summary>
|
||||
public string ModuleSoure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据库提供者
|
||||
|
||||
@@ -7,6 +7,6 @@ namespace Yi.Abp.Tool.Application.Contracts
|
||||
public interface ITemplateGenService: IApplicationService
|
||||
{
|
||||
Task<byte[]> CreateModuleAsync(TemplateGenCreateInputDto moduleCreateInputDto);
|
||||
Task<byte[]> CreateProjectAsync(TemplateGenCreateInputDto moduleCreateInputDto);
|
||||
Task<List<string>> GetAllTemplatesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,14 @@ using Yi.Framework.Core.Helper;
|
||||
|
||||
namespace Yi.Abp.Tool.Application
|
||||
{
|
||||
public class TemplateGenService : ApplicationService,ITemplateGenService
|
||||
public class TemplateGenService : ApplicationService, ITemplateGenService
|
||||
{
|
||||
private readonly TemplateGenManager _templateGenManager;
|
||||
public TemplateGenService(TemplateGenManager templateGenManager) { _templateGenManager = templateGenManager; }
|
||||
|
||||
public TemplateGenService(TemplateGenManager templateGenManager)
|
||||
{
|
||||
_templateGenManager = templateGenManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载模块文件
|
||||
@@ -29,8 +33,10 @@ namespace Yi.Abp.Tool.Application
|
||||
{
|
||||
moduleCreateInputDto.SetNameReplace();
|
||||
|
||||
//模块类型,就是分支小写
|
||||
var input = moduleCreateInputDto.Adapt<TemplateGenCreateDto>();
|
||||
input.SetTemplateFilePath(_templateGenManager._toolOptions.ModuleTemplateFilePath);
|
||||
input.SetTemplateGiteeRef(moduleCreateInputDto.ModuleSoure);
|
||||
|
||||
var filePath = await _templateGenManager.CreateTemplateAsync(input);
|
||||
|
||||
////考虑从路径中获取
|
||||
@@ -39,22 +45,15 @@ namespace Yi.Abp.Tool.Application
|
||||
return await File.ReadAllBytesAsync(filePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 下载模块文件
|
||||
/// 获取全部模板列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<byte[]> CreateProjectAsync(TemplateGenCreateInputDto moduleCreateInputDto)
|
||||
[HttpGet("template-gen/template")]
|
||||
public async Task<List<string>> 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);
|
||||
return await _templateGenManager.GetAllTemplatesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,21 +9,19 @@ namespace Yi.Abp.Tool.Domain.Shared.Dtos
|
||||
{
|
||||
public class TemplateGenCreateDto
|
||||
{
|
||||
public void SetTemplateFilePath(string templateFilePath)
|
||||
public void SetTemplateGiteeRef(string moduleType)
|
||||
{
|
||||
this.TemplateFilePath = templateFilePath;
|
||||
this.GiteeRef = moduleType.ToLower();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 模板文件路径
|
||||
/// </summary>
|
||||
public string TemplateFilePath { get; set; }
|
||||
/// <summary>
|
||||
/// 模块名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模块所属gitee分支
|
||||
/// </summary>
|
||||
public string GiteeRef { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据库提供者
|
||||
|
||||
@@ -8,17 +8,6 @@ namespace Yi.Abp.Tool.Domain.Shared.Options
|
||||
{
|
||||
public class ToolOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 模块模板zip文件路径
|
||||
/// </summary>
|
||||
public string ModuleTemplateFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 项目模板zip文件路径
|
||||
/// </summary>
|
||||
public string ProjectTemplateFilePath { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 临时文件目录
|
||||
/// </summary>
|
||||
|
||||
@@ -9,5 +9,8 @@
|
||||
<ProjectReference Include="..\..\framework\Yi.Framework.Core\Yi.Framework.Core.csproj" />
|
||||
<ProjectReference Include="..\..\framework\Yi.Framework.Mapster\Yi.Framework.Mapster.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Options\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
85
Yi.Abp.Net8/tool/Yi.Abp.Tool.Domain/GiteeManager.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
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();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -13,14 +13,23 @@ namespace Yi.Abp.Tool.Domain
|
||||
{
|
||||
public class TemplateGenManager : ITransientDependency
|
||||
{
|
||||
public readonly ToolOptions _toolOptions;
|
||||
public TemplateGenManager(IOptionsMonitor<ToolOptions> toolOptions) { _toolOptions = toolOptions.CurrentValue; }
|
||||
private readonly ToolOptions _toolOptions;
|
||||
private readonly GiteeManager _giteeManager;
|
||||
|
||||
public TemplateGenManager(IOptionsMonitor<ToolOptions> toolOptions, GiteeManager giteeManager)
|
||||
{
|
||||
_giteeManager = giteeManager;
|
||||
_toolOptions = toolOptions.CurrentValue;
|
||||
}
|
||||
|
||||
public async Task<string> CreateTemplateAsync(TemplateGenCreateDto input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input.TemplateFilePath))
|
||||
//这里判断gitee上是否有这个分支
|
||||
if (!await _giteeManager.IsExsitBranchAsync(input.GiteeRef))
|
||||
{
|
||||
throw new UserFriendlyException($"模板路径无法找到,请检查,[{input.TemplateFilePath}]路径");
|
||||
throw new UserFriendlyException($"Gitee分支未找到{input.GiteeRef},请检查,[{input.GiteeRef}]分支是否存在");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(_toolOptions.TempDirPath))
|
||||
{
|
||||
throw new UserFriendlyException($"临时目录路径无法找到,请检查,[{_toolOptions.TempDirPath}]路径");
|
||||
@@ -33,25 +42,56 @@ namespace Yi.Abp.Tool.Domain
|
||||
Directory.CreateDirectory(tempFileDirPath);
|
||||
}
|
||||
|
||||
//文件解压覆盖
|
||||
ZipFile.ExtractToDirectory(input.TemplateFilePath, tempFileDirPath, true);
|
||||
|
||||
await ReplaceContentAsync(tempFileDirPath, input.ReplaceStrData);
|
||||
//下载的模板存放文件路径
|
||||
var downloadPath = Path.Combine(_toolOptions.TempDirPath, "download");
|
||||
if (!Directory.Exists(downloadPath))
|
||||
{
|
||||
Directory.CreateDirectory(downloadPath);
|
||||
}
|
||||
|
||||
var downloadFilePath = Path.Combine(downloadPath, $"{id}.zip");
|
||||
var gitSteam = await _giteeManager.DownLoadFileAsync(input.GiteeRef);
|
||||
using (FileStream fileStream = new FileStream(downloadFilePath, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
await gitSteam.CopyToAsync(fileStream);
|
||||
}
|
||||
|
||||
//文件解压覆盖,将刚刚下载的模板,解压即可
|
||||
ZipFile.ExtractToDirectory(downloadFilePath, tempFileDirPath, true);
|
||||
|
||||
|
||||
//注意,这里下载的zip包,其实多了一层,我们进行操作的时候,要将操作目录进一步
|
||||
var operPath = Directory.GetDirectories(tempFileDirPath)[0];
|
||||
await ReplaceContentAsync(operPath, input.ReplaceStrData);
|
||||
var tempFilePath = Path.Combine(_toolOptions.TempDirPath, $"{id}.zip");
|
||||
ZipFile.CreateFromDirectory(operPath, tempFilePath);
|
||||
|
||||
ZipFile.CreateFromDirectory(tempFileDirPath, tempFilePath);
|
||||
//创建压缩包后删除临时目录
|
||||
Directory.Delete(tempFileDirPath, true);
|
||||
return tempFilePath;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取全部模板列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<string>> GetAllTemplatesAsync()
|
||||
{
|
||||
var refs = await _giteeManager.GetAllBranchAsync();
|
||||
|
||||
//移除主分支
|
||||
refs.Remove("master");
|
||||
return refs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 替换内容,key为要替换的内容,value为替换成的内容
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task ReplaceContentAsync(string rootDirectory, Dictionary<string, string> dic)
|
||||
{
|
||||
|
||||
foreach (var dicEntry in dic)
|
||||
{
|
||||
await ReplaceInDirectory(rootDirectory, dicEntry.Key, dicEntry.Value);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\" />
|
||||
<Folder Include="wwwroot\temp\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -33,4 +34,8 @@
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_ContentIncludedByDefault Remove="wwwroot\temp\download\d5bb6f4c5ca24da29ebe1b67e1e4595d.zip" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using System.Globalization;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
using System.Threading.RateLimiting;
|
||||
using Microsoft.AspNetCore.Cors;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Newtonsoft.Json.Converters;
|
||||
@@ -12,6 +15,7 @@ using Yi.Abp.Tool.Application;
|
||||
using Yi.Framework.AspNetCore;
|
||||
using Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
|
||||
using Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection;
|
||||
using Yi.Framework.Core.Json;
|
||||
|
||||
namespace Yi.Abp.Tool.Web
|
||||
{
|
||||
@@ -41,15 +45,17 @@ namespace Yi.Abp.Tool.Web
|
||||
});
|
||||
|
||||
//设置api格式
|
||||
service.AddControllers().AddNewtonsoftJson(options =>
|
||||
Configure<JsonOptions>(options =>
|
||||
{
|
||||
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
|
||||
options.SerializerSettings.Converters.Add(new StringEnumConverter());
|
||||
options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver();
|
||||
options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter());
|
||||
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Configure<AbpAntiForgeryOptions>(options =>
|
||||
{
|
||||
options.AutoValidate = false;
|
||||
@@ -81,7 +87,7 @@ namespace Yi.Abp.Tool.Web
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
service.AddHttpClient();
|
||||
//速率限制
|
||||
//每60秒限制100个请求,滑块添加,分6段
|
||||
service.AddRateLimiter(_ =>
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
"GiteeAccession": "8d9f05faec154475f121079579a0abf0"
|
||||
}
|
||||
|
||||
@@ -15,5 +15,6 @@
|
||||
"TempDirPath": "wwwroot/temp",
|
||||
"ModuleTemplateFilePath": "wwwroot/ModuleTemplate.zip",
|
||||
"ProjectTemplateFilePath": "wwwroot/ProjectTemplate.zip"
|
||||
}
|
||||
},
|
||||
"GiteeAccession": ""
|
||||
}
|
||||
|
||||
47
Yi.Abp.Net8/tool/Yi.Abp.Tool/CommandInvoker.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace Yi.Abp.Tool
|
||||
{
|
||||
public class CommandInvoker : ISingletonDependency
|
||||
{
|
||||
private readonly IEnumerable<ICommand> _commands;
|
||||
private CommandLineApplication Application { get; }
|
||||
|
||||
public CommandInvoker(IEnumerable<ICommand> commands)
|
||||
{
|
||||
_commands = commands;
|
||||
Application = new CommandLineApplication();
|
||||
InitCommand();
|
||||
}
|
||||
|
||||
private void InitCommand()
|
||||
{
|
||||
Application.HelpOption("-h|--help");
|
||||
Application.VersionOption("-v|--versions", Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||||
foreach (var command in _commands)
|
||||
{
|
||||
CommandLineApplication childrenCommandLineApplication = new CommandLineApplication(true)
|
||||
{
|
||||
Name = command.Command,
|
||||
Parent = Application,
|
||||
Description =command.Description
|
||||
};
|
||||
Application.Commands.Add(childrenCommandLineApplication);
|
||||
command.CommandLineApplication(childrenCommandLineApplication);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task InvokerAsync(string[] args)
|
||||
{
|
||||
Application.Execute(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace Yi.Abp.Tool
|
||||
{
|
||||
public class CommandSelector : ITransientDependency
|
||||
{
|
||||
private readonly IEnumerable<ICommand> _commands;
|
||||
public CommandSelector(IEnumerable<ICommand> commands)
|
||||
{
|
||||
_commands = commands;
|
||||
}
|
||||
public async Task SelectorAsync(string[] args)
|
||||
{
|
||||
//不指定命令,默认给help
|
||||
if (args.Length == 0)
|
||||
{
|
||||
await SelectorDefaultCommandAsync();
|
||||
return;
|
||||
}
|
||||
var commandStr = args[0];
|
||||
|
||||
var commandOrNull = _commands.Where(x => x.CommandStrs.Select(x => x.ToUpper()).Contains(commandStr.ToUpper())).FirstOrDefault();
|
||||
|
||||
//没有匹配到命令,,默认给help
|
||||
if (commandOrNull == null)
|
||||
{
|
||||
await SelectorDefaultCommandAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
var options = new Dictionary<string, string?>();
|
||||
|
||||
//去除命令,剩下进行参数装载
|
||||
string[] commonArgs = args.Skip(1).ToArray();
|
||||
for (var i = 0; i < commonArgs.Length; i++)
|
||||
{
|
||||
var currentArg = commonArgs[i];
|
||||
//命令参数以-或者--开头
|
||||
if (IsCommandArg(currentArg))
|
||||
{
|
||||
string? commonValue = null;
|
||||
//参数值在他的下一位
|
||||
if (i + 1 < commonArgs.Length)
|
||||
{
|
||||
var nextArg = commonArgs[i + 1];
|
||||
if (!IsCommandArg(nextArg))
|
||||
{
|
||||
commonValue = nextArg;
|
||||
}
|
||||
|
||||
}
|
||||
//删除-就是参数名
|
||||
options.Add(ArgToCommandMap(currentArg), commonValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
await commandOrNull.InvokerAsync(options,args);
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 判断是否为命令参数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool IsCommandArg(string arg)
|
||||
{
|
||||
if (arg.StartsWith("-") || arg.StartsWith("--"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 参数到命令的转换
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string ArgToCommandMap(string arg)
|
||||
{
|
||||
return arg.TrimStart('-').TrimStart('-');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选择默认命令
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task SelectorDefaultCommandAsync()
|
||||
{
|
||||
await SelectorAsync(["-h", "-error"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,40 +4,38 @@ using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
|
||||
namespace Yi.Abp.Tool.Commands
|
||||
{
|
||||
public class AddModuleCommand : ICommand
|
||||
{
|
||||
public List<string> CommandStrs => new List<string> { "add-module" };
|
||||
|
||||
public async Task InvokerAsync(Dictionary<string, string> options, string[] args)
|
||||
public string Command => "add-module";
|
||||
public string? Description => "将内容添加到当前解决方案` yi-abp add-module <moduleName> [-p <path>] [-s <solution>] ";
|
||||
public void CommandLineApplication(CommandLineApplication application)
|
||||
{
|
||||
//只有一个add-module
|
||||
if (args.Length <= 1)
|
||||
application.HelpOption("-h|--help");
|
||||
var modulePathOption= application.Option("-p|--modulePath", "模块路径",CommandOptionType.SingleValue);
|
||||
var solutionOption= application.Option("-s|--solution", "解决方案路径",CommandOptionType.SingleValue);
|
||||
var moduleNameArgument = application.Argument("moduleName", "模块名", (_) => { });
|
||||
application.OnExecute(() =>
|
||||
{
|
||||
throw new UserFriendlyException("命令错误,add-module命令后必须添加 模块名");
|
||||
}
|
||||
var moduleName = moduleNameArgument.Value;
|
||||
|
||||
//需要添加名称
|
||||
var moduleName = args[1];
|
||||
options.TryGetValue("modulePath", out var modulePath);
|
||||
|
||||
//模块路径默认按小写规则,当前路径
|
||||
if (string.IsNullOrEmpty(modulePath))
|
||||
//模块路径默认按小写规则,默认在模块路径下一层
|
||||
var modulePath =moduleName.ToLower().Replace(".", "-");
|
||||
if (modulePathOption.HasValue())
|
||||
{
|
||||
modulePath = moduleName.ToLower().Replace(".", "-");
|
||||
modulePath = modulePathOption.Value();
|
||||
}
|
||||
|
||||
|
||||
//解决方案默认在模块文件夹上一级,也可以通过s进行指定
|
||||
var slnPath = string.Empty;
|
||||
options.TryGetValue("s", out var slnPath1);
|
||||
options.TryGetValue("solution", out var slnPath2);
|
||||
slnPath = string.IsNullOrEmpty(slnPath1) ? slnPath2 : slnPath1;
|
||||
if (string.IsNullOrEmpty(slnPath))
|
||||
var slnPath = "../";
|
||||
|
||||
if (solutionOption.HasValue())
|
||||
{
|
||||
slnPath = "../";
|
||||
slnPath = solutionOption.Value();
|
||||
}
|
||||
|
||||
CheckFirstSlnPath(slnPath);
|
||||
@@ -49,7 +47,10 @@ namespace Yi.Abp.Tool.Commands
|
||||
var cmdCommands = dotnetSlnCommandPart2.Select(x => dotnetSlnCommandPart1 + x+"\"").ToArray();
|
||||
StartCmd(cmdCommands);
|
||||
|
||||
await Console.Out.WriteLineAsync("恭喜~模块添加成功!");
|
||||
Console.WriteLine("恭喜~模块添加成功!");
|
||||
return 0;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -117,5 +118,7 @@ namespace Yi.Abp.Tool.Commands
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
|
||||
namespace Yi.Abp.Tool.Commands
|
||||
{
|
||||
@@ -10,17 +11,27 @@ namespace Yi.Abp.Tool.Commands
|
||||
{
|
||||
public List<string> CommandStrs => ["clear"];
|
||||
|
||||
public Task InvokerAsync(Dictionary<string, string> options, string[] args)
|
||||
{
|
||||
List<string> delDirBlacklist = ["obj", "bin"];
|
||||
options.TryGetValue("path", out var path);
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
public string Command => "clear";
|
||||
public string? Description => "清除当前目录及子目录下的obj、bin文件夹` yi-abp clear `";
|
||||
|
||||
public void CommandLineApplication(CommandLineApplication application)
|
||||
{
|
||||
path = "./";
|
||||
application.HelpOption("-h|--help");
|
||||
List<string> delDirBlacklist = ["obj", "bin"];
|
||||
var pathOption= application.Option("-path", "路径",CommandOptionType.SingleValue);
|
||||
|
||||
|
||||
application.OnExecute(() =>
|
||||
{
|
||||
var path = "./";
|
||||
if (pathOption.HasValue())
|
||||
{
|
||||
path = pathOption.Value();
|
||||
}
|
||||
DeleteObjBinFolders(path, delDirBlacklist);
|
||||
return Task.CompletedTask;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,20 +4,28 @@ using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
|
||||
namespace Yi.Abp.Tool.Commands
|
||||
{
|
||||
public class CloneCommand : ICommand
|
||||
{
|
||||
public List<string> CommandStrs => new List<string> { "clone"};
|
||||
private const string CloneAddress= "https://gitee.com/ccnetcore/Yi";
|
||||
|
||||
private const string cloneAddress= "https://gitee.com/ccnetcore/Yi";
|
||||
public Task InvokerAsync(Dictionary<string, string> options, string[] args)
|
||||
|
||||
public string Command => "clone";
|
||||
public string? Description => "克隆最新YiFramework源代码,需依赖git";
|
||||
|
||||
public void CommandLineApplication(CommandLineApplication application)
|
||||
{
|
||||
StartCmd($"git clone {cloneAddress}");
|
||||
return Task.CompletedTask;
|
||||
application.OnExecute(() =>
|
||||
{
|
||||
StartCmd($"git clone {CloneAddress}");
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 执行cmd命令
|
||||
/// </summary>
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yi.Abp.Tool.Commands
|
||||
{
|
||||
public class HelpCommand : ICommand
|
||||
{
|
||||
public List<string> CommandStrs => new List<string> { "h", "help", "-h", "-help" };
|
||||
|
||||
public Task InvokerAsync(Dictionary<string, string> options, string[] args)
|
||||
{
|
||||
string? errorMsg = null;
|
||||
if (options.TryGetValue("error", out _))
|
||||
{
|
||||
errorMsg = "您输入的命令有误,请检查,以下帮助命令提示:";
|
||||
}
|
||||
Console.WriteLine($"""
|
||||
{errorMsg}
|
||||
使用:
|
||||
|
||||
yi-abp <command> <target> [options]
|
||||
|
||||
命令列表:
|
||||
|
||||
> v: 查看yi-abp工具版本号
|
||||
> help: 查看帮助列表,写下命令` yi-abp help <command> `
|
||||
> new: 创建模块模板` yi-abp new <name> -t module -csf `
|
||||
> new: 创建项目模板` yi-abp new <name> -csf `
|
||||
> add-module: 将内容添加到当前解决方案` yi-abp add-module <moduleName> [-modulePath <path>] [-s <slnPath>] `
|
||||
> clear: 清除当前目录及子目录下的obj、bin文件夹` yi-abp clear `
|
||||
|
||||
""");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
// using System;
|
||||
// using System.Collections.Generic;
|
||||
// using System.Linq;
|
||||
// using System.Reflection;
|
||||
// using System.Text;
|
||||
// using System.Threading.Tasks;
|
||||
//
|
||||
// namespace Yi.Abp.Tool.Commands
|
||||
// {
|
||||
// public class HelpCommand : ICommand
|
||||
// {
|
||||
// public List<string> CommandStrs => new List<string> { "h", "help", "-h", "-help" };
|
||||
//
|
||||
// public Task InvokerAsync(Dictionary<string, string> options, string[] args)
|
||||
// {
|
||||
// string? errorMsg = null;
|
||||
// if (options.TryGetValue("error", out _))
|
||||
// {
|
||||
// errorMsg = "您输入的命令有误,请检查,以下帮助命令提示:";
|
||||
// }
|
||||
// Console.WriteLine($"""
|
||||
// {errorMsg}
|
||||
// 使用:
|
||||
//
|
||||
// yi-abp <command> <target> [options]
|
||||
//
|
||||
// 命令列表:
|
||||
//
|
||||
// > v: 查看yi-abp工具版本号
|
||||
// > help: 查看帮助列表,写下命令` yi-abp help <command> `
|
||||
// > new: 创建模块模板` yi-abp new <name> -t module -csf `
|
||||
// > new: 创建项目模板` yi-abp new <name> -csf `
|
||||
// > add-module: 将内容添加到当前解决方案` yi-abp add-module <moduleName> [-modulePath <path>] [-s <slnPath>] `
|
||||
// > clear: 清除当前目录及子目录下的obj、bin文件夹` yi-abp clear `
|
||||
//
|
||||
// """);
|
||||
// return Task.CompletedTask;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using Yi.Abp.Tool.Application.Contracts;
|
||||
using Yi.Abp.Tool.Application.Contracts.Dtos;
|
||||
|
||||
@@ -13,72 +14,126 @@ namespace Yi.Abp.Tool.Commands
|
||||
public class NewCommand : ICommand
|
||||
{
|
||||
private readonly ITemplateGenService _templateGenService;
|
||||
|
||||
public NewCommand(ITemplateGenService templateGenService)
|
||||
{
|
||||
_templateGenService = templateGenService;
|
||||
}
|
||||
|
||||
public List<string> CommandStrs => new List<string>() { "new" };
|
||||
|
||||
public string Command => "new";
|
||||
public string? Description => "创建项目模板` yi-abp new <name> -csf `";
|
||||
|
||||
public async Task InvokerAsync(Dictionary<string, string> options, string[] args)
|
||||
public void CommandLineApplication(CommandLineApplication application)
|
||||
{
|
||||
var id = Guid.NewGuid().ToString("N");
|
||||
//只有一个new
|
||||
if (args.Length <= 1)
|
||||
application.HelpOption("-h|--help");
|
||||
|
||||
var templateTypeOption = application.Option("-t|--template", "模板类型:`module`|`porject`",
|
||||
CommandOptionType.SingleValue);
|
||||
var pathOption = application.Option("-p|--path", "创建路径", CommandOptionType.SingleValue);
|
||||
var csfOption = application.Option("-csf", "是否创建解决方案文件夹", CommandOptionType.NoValue);
|
||||
|
||||
var soureOption = application.Option("-s|--soure", "模板来源,gitee模板库分支名称: 默认值`default`",
|
||||
CommandOptionType.SingleValue);
|
||||
|
||||
var moduleNameArgument = application.Argument("moduleName", "模块名", (_) => { });
|
||||
|
||||
//子命令,new list
|
||||
application.Command("list",(applicationlist) =>
|
||||
{
|
||||
throw new UserFriendlyException("命令错误,new命令后必须添加 名称");
|
||||
applicationlist.OnExecute(() =>
|
||||
{
|
||||
Console.WriteLine("正在远程搜索中...");
|
||||
var list=_templateGenService.GetAllTemplatesAsync().Result;
|
||||
var tip = $"""
|
||||
全部模板包括:
|
||||
模板名称
|
||||
----------------
|
||||
{list.JoinAsString("\n")}
|
||||
""";
|
||||
Console.WriteLine(tip);
|
||||
return 0;
|
||||
});
|
||||
});
|
||||
|
||||
application.OnExecute(() =>
|
||||
{
|
||||
var path = string.Empty;
|
||||
if (pathOption.HasValue())
|
||||
{
|
||||
path = pathOption.Value();
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
return 0;
|
||||
}
|
||||
string name = args[1];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region 处理生成类型
|
||||
|
||||
options.TryGetValue("t", out var templateType);
|
||||
var id = Guid.NewGuid().ToString("N");
|
||||
var zipPath = string.Empty;
|
||||
byte[] fileByteArray;
|
||||
|
||||
var soure= soureOption.HasValue() ? soureOption.Value() : "default";
|
||||
|
||||
var templateType = templateTypeOption.HasValue() ? templateTypeOption.Value() : "module";
|
||||
if (templateType == "module")
|
||||
{
|
||||
//代表模块生成
|
||||
fileByteArray = await _templateGenService.CreateModuleAsync(new TemplateGenCreateInputDto
|
||||
fileByteArray = (_templateGenService.CreateModuleAsync(new TemplateGenCreateInputDto
|
||||
{
|
||||
Name = name,
|
||||
});
|
||||
Name = moduleNameArgument.Value,
|
||||
ModuleSoure = soure
|
||||
}).Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
//代表模块生成
|
||||
fileByteArray = await _templateGenService.CreateProjectAsync(new TemplateGenCreateInputDto
|
||||
//还是代表模块生成
|
||||
fileByteArray = _templateGenService.CreateModuleAsync(new TemplateGenCreateInputDto
|
||||
{
|
||||
Name = name,
|
||||
});
|
||||
Name = moduleNameArgument.Value,
|
||||
}).Result;
|
||||
}
|
||||
zipPath = $"{id}.zip";
|
||||
await File.WriteAllBytesAsync(zipPath, fileByteArray);
|
||||
|
||||
|
||||
|
||||
zipPath = Path.Combine(path, $"{id}.zip");
|
||||
File.WriteAllBytes(zipPath, fileByteArray);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 处理解决方案文件夹
|
||||
|
||||
//默认是当前目录
|
||||
var unzipDirPath = "./";
|
||||
//如果创建解决方案文件夹
|
||||
if (options.TryGetValue("csf", out _))
|
||||
if (csfOption.HasValue())
|
||||
{
|
||||
var moduleName = name.ToLower().Replace(".", "-");
|
||||
var moduleName = moduleNameArgument.Value.ToLower().Replace(".", "-");
|
||||
|
||||
if (Directory.Exists(moduleName))
|
||||
unzipDirPath = Path.Combine(path, moduleName);
|
||||
if (Directory.Exists(unzipDirPath))
|
||||
{
|
||||
throw new UserFriendlyException($"文件夹[{moduleName}]已存在,请删除后重试");
|
||||
throw new UserFriendlyException($"文件夹[{unzipDirPath}]已存在,请删除后重试");
|
||||
}
|
||||
Directory.CreateDirectory(moduleName);
|
||||
unzipDirPath = moduleName;
|
||||
|
||||
Directory.CreateDirectory(unzipDirPath);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
ZipFile.ExtractToDirectory(zipPath, unzipDirPath);
|
||||
//创建压缩包后删除临时目录
|
||||
File.Delete(zipPath);
|
||||
|
||||
|
||||
await Console.Out.WriteLineAsync("恭喜~模块已生成!");
|
||||
Console.WriteLine("恭喜~模块已生成!");
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
namespace Yi.Abp.Tool.Commands
|
||||
{
|
||||
public class VersionCommand : ICommand
|
||||
{
|
||||
public List<string> CommandStrs => new List<string> { "version", "v", "-version", "-v" };
|
||||
|
||||
public Task InvokerAsync(Dictionary<string, string> options, string[] args)
|
||||
{
|
||||
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
|
||||
Console.WriteLine($"Yi-ABP TOOL {version}");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,21 +3,17 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
|
||||
namespace Yi.Abp.Tool
|
||||
{
|
||||
public interface ICommand:ITransientDependency
|
||||
public interface ICommand:ISingletonDependency
|
||||
{
|
||||
/// <summary>
|
||||
/// 命令串
|
||||
/// </summary>
|
||||
public List<string> CommandStrs { get; }
|
||||
public string Command { get; }
|
||||
|
||||
public string? Description { get; }
|
||||
void CommandLineApplication(CommandLineApplication application);
|
||||
|
||||
/// <summary>
|
||||
/// 执行
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task InvokerAsync(Dictionary<string,string> options, string[] args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,33 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Yi.Abp.Tool;
|
||||
|
||||
class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
|
||||
#if DEBUG
|
||||
//args = ["v"];
|
||||
//args = ["-v"];
|
||||
//args = ["h"];
|
||||
|
||||
//帮助
|
||||
//args = ["-h"];
|
||||
//args = [];
|
||||
//args = ["12312"];
|
||||
//args = ["new", "Acme.Book", "-t", "module", "-csf"];
|
||||
//args = ["new", "Acme.Book", "-t", "module"];
|
||||
//args = ["add-module", "Acme.Demo", "-s", "D:\\code\\csharp\\source\\Yi\\Yi.Abp.Net8", "-modulePath", "D:\\code\\csharp\\source\\Yi\\Yi.Abp.Net8\\module\\acme-demo"];
|
||||
args = ["clear", "-path", "D:\\code\\csharp\\source\\Yi\\Yi.Abp.Net8\\src"];
|
||||
|
||||
//版本
|
||||
// args = ["-v"];
|
||||
|
||||
//清理
|
||||
// args = ["clear"];
|
||||
|
||||
//创建模块
|
||||
//args = ["new","oooo", "-t","module","-p","D:\\temp","-csf"];
|
||||
|
||||
//查看模板列表
|
||||
//args = ["new","list"];
|
||||
//查看子命令帮组
|
||||
// args = ["new","-h"];
|
||||
|
||||
//添加模块
|
||||
//args = ["add-module", "kkk"];
|
||||
#endif
|
||||
try
|
||||
{
|
||||
@@ -32,8 +42,8 @@ class Program
|
||||
//})
|
||||
.UseAutofac()
|
||||
.Build();
|
||||
var commandSelector = host.Services.GetRequiredService<CommandSelector>();
|
||||
await commandSelector.SelectorAsync(args);
|
||||
var commandSelector = host.Services.GetRequiredService<CommandInvoker>();
|
||||
await commandSelector.InvokerAsync(args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>1.1.0</Version>
|
||||
<Version>2.0.4</Version>
|
||||
<Authors>橙子老哥</Authors>
|
||||
<Description>yi-framework框架配套工具</Description>
|
||||
<PackageProjectUrl>https://ccnetcore.com</PackageProjectUrl>
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.1" />
|
||||
<PackageReference Include="Volo.Abp.Autofac" Version="$(AbpVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace Yi.Abp.Tool
|
||||
{
|
||||
options.RemoteServices.Default =
|
||||
new RemoteServiceConfiguration("https://ccnetcore.com:19009");
|
||||
// new RemoteServiceConfiguration("http://localhost:19002");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@ const form = reactive({
|
||||
});
|
||||
const installText = "> dotnet tool install -g Yi.Abp.Tool";
|
||||
const cloneText = "> yi-abp clone ";
|
||||
|
||||
const listText="> yi-abp new list ";
|
||||
const helpText="> yi-abp -h ";
|
||||
const nugetData=reactive({
|
||||
versions:"0.0.0",
|
||||
downloadNumber:0
|
||||
@@ -40,7 +41,9 @@ const dbData = [
|
||||
|
||||
|
||||
const typeData = [{ name: '模块', key: 'module', value: 'module' },
|
||||
{ name: '模块', key: 'project', value: 'project' }]
|
||||
{ name: '模块', key: 'module', value: 'module' },
|
||||
{ name: '模块', key: 'module', value: 'module' },
|
||||
{ name: '模块', key: 'module', value: 'module' }]
|
||||
const addModuleComputed=computed(()=>{
|
||||
|
||||
return `> yi-abp add-module ${form.name}`;
|
||||
@@ -139,6 +142,19 @@ onUnmounted(() => {
|
||||
|
||||
|
||||
<LableCheck v-model="form.isCsf" title="创建解决方案文件夹" text="指定项目是放在输出文件夹中的新文件夹中,还是直接放在输出文件夹中。" />
|
||||
<p>默认勾选</p>
|
||||
|
||||
<h4>模板库</h4>
|
||||
<p>现在已经支持公开模板库,地址:https://gitee.com/ccnetcore/yi-template</p>
|
||||
<p>每个分支代表一个模板,你可以通过提交pr,或联系管理员上传你自定义的模板</p>
|
||||
<CodeBox v-model="listText" />
|
||||
<p>通过以上命令,可查询当前可用模板</p>
|
||||
|
||||
|
||||
<h4>帮助</h4>
|
||||
<p>更详细的实时帮助,可执行帮助命令</p>
|
||||
<CodeBox v-model="helpText" />
|
||||
<p>如还有疑惑,或错误,可在社区对应板块发布问题</p>
|
||||
</div>
|
||||
<div class="content-body-right">
|
||||
|
||||
@@ -191,7 +207,7 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
&-body {
|
||||
height: 1400px;
|
||||
height: 1800px;
|
||||
padding: 48px;
|
||||
background-color: #fff;
|
||||
border-radius: 12px;
|
||||
|
||||
@@ -61,11 +61,11 @@ export function addDateRange(params, dateRange, propName) {
|
||||
if (typeof (propName) === 'undefined') {
|
||||
// search.params['beginTime'] = dateRange[0];
|
||||
// search.params['endTime'] = dateRange[1];
|
||||
search.startTime=dateRange[0];
|
||||
search.endTime=dateRange[1];
|
||||
search.startTime=parseTime(dateRange[0]);
|
||||
search.endTime=parseTime(dateRange[1]);
|
||||
} else {
|
||||
search.params['start' + propName] = dateRange[0];
|
||||
search.params['end' + propName] = dateRange[1];
|
||||
search.params['start' + propName] = parseTime(dateRange[0]);
|
||||
search.params['end' + propName] = parseTime(dateRange[1]);
|
||||
}
|
||||
return search;
|
||||
}
|
||||
|
||||