From b9dad93c9d66232dd4f40d9aba307f688cfa671a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com>
Date: Thu, 13 Apr 2023 21:12:06 +0800
Subject: [PATCH] =?UTF-8?q?feat:furion=20rbac=E6=90=AD=E5=BB=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../AspNetCore/HttpContextExtensions.cs | 99 +++
.../Data/Auditing/AuditedObject.cs | 19 +
.../Data/Auditing/IAuditedObject.cs | 18 +
.../Data/Auditing/ICreationAuditedObject.cs | 19 +
.../Data/Auditing/IDeletionAuditedObject.cs | 19 +
.../Data/Auditing/IFullAuditedObject.cs | 19 +
.../Data/Auditing/IHasCreationTime.cs | 10 +
.../Data/Auditing/IHasDeletionTime.cs | 14 +
.../Data/Auditing/IHasEntityVersion.cs | 13 +
.../Data/Auditing/IHasModificationTime.cs | 8 +
.../Data/Auditing/IMayHaveCreator.cs | 13 +
.../Auditing/IModificationAuditedObject.cs | 19 +
.../Data/Auditing/IMustHaveCreator.cs | 13 +
.../Data/Entities/IMultiTenant.cs | 13 +
.../Data/Entities/IOrderNum.cs | 13 +
.../Data/Entities/ISoftDelete.cs | 13 +
.../Data/Entities/IState.cs | 13 +
.../Ddd/Dtos/Abstract/IEntityDto.cs | 17 +
.../Ddd/Dtos/Abstract/IHasTotalCount.cs | 13 +
.../Ddd/Dtos/Abstract/IListResult.cs | 13 +
.../Abstract/IPagedAllResultRequestDto.cs | 13 +
.../IPagedAndSortedResultRequestDto.cs | 15 +
.../Ddd/Dtos/Abstract/IPagedResult.cs | 12 +
.../Ddd/Dtos/EntityDto.cs | 32 +
.../Ddd/Dtos/ListResultDto.cs | 30 +
.../Ddd/Dtos/PagedAllResultRequestDto.cs | 23 +
.../Dtos/PagedAndSortedResultRequestDto.cs | 33 +
.../Ddd/Dtos/PagedDto.cs | 20 +
.../Ddd/Dtos/PagedResultDto.cs | 25 +
.../Ddd/Entities/AggregateRoot.cs | 15 +
.../Ddd/Entities/Entity.cs | 58 ++
.../Ddd/Entities/IAggregateRoot.cs | 16 +
.../Ddd/Entities/IEntity.cs | 23 +
.../Ddd/Repositories/IRepository.cs | 57 ++
.../Services/Abstract/IApplicationService.cs | 12 +
.../Services/Abstract/ICreateAppService.cs | 20 +
.../Abstract/ICreateUpdateAppService.cs | 27 +
.../Ddd/Services/Abstract/ICrudAppService.cs | 42 ++
.../Services/Abstract/IDeleteAppService.cs | 13 +
.../Abstract/IPageTimeResultRequestDto.cs | 15 +
.../Services/Abstract/IReadOnlyAppService.cs | 24 +
.../Services/Abstract/IUpdateAppService.cs | 21 +
.../Ddd/Services/ApplicationService.cs | 11 +
.../Ddd/Services/CrudAppService.cs | 176 +++++
.../Ddd/Services/ReadOnlyAppService.cs | 128 ++++
.../Enums/FileTypeEnum.cs | 20 +
.../Enums/OrderByEnum.cs | 14 +
.../Enums/QueryOperatorEnum.cs | 72 ++
.../Enums/ResultCodeEnum.cs | 31 +
.../Exceptions/AuthException.cs | 48 ++
.../Exceptions/BusinessException.cs | 47 ++
.../Exceptions/ExceptionExtensions.cs | 41 ++
.../Exceptions/IHasErrorCode.cs | 7 +
.../Exceptions/IHasErrorDetails.cs | 13 +
.../Exceptions/IHasLogLevel.cs | 14 +
.../Exceptions/UserFriendlyException.cs | 34 +
.../Helper/AssemblyHelper.cs | 94 +++
.../Helper/Base32Helper.cs | 101 +++
.../Helper/ConsoleHelper.cs | 54 ++
.../Helper/DateHelper.cs | 58 ++
.../Helper/DistinctHelper.cs | 42 ++
.../Helper/EnumHelper.cs | 25 +
.../Helper/ExpressionHelper.cs | 98 +++
.../Helper/FileHelper.cs | 490 ++++++++++++++
.../Helper/HtmlHelper.cs | 24 +
.../Helper/HttpHelper.cs | 122 ++++
.../Helper/IdHelper.cs | 16 +
.../Helper/IpHelper.cs | 56 ++
.../Helper/JsonHelper.cs | 518 +++++++++++++++
.../Helper/MD5Hepler.cs | 132 ++++
.../Helper/MimeHelper.cs | 260 ++++++++
.../Helper/RSAFileHelper.cs | 34 +
.../Helper/RSAHelper.cs | 390 +++++++++++
.../Helper/RandomHelper.cs | 99 +++
.../Helper/ReflexHelper.cs | 63 ++
.../Helper/SnowflakeHelper.cs | 102 +++
.../Helper/StringHelper.cs | 113 ++++
.../Helper/TreeHelper.cs | 68 ++
.../Helper/UnicodeHelper.cs | 47 ++
.../Helper/UrlHelper.cs | 24 +
.../Helper/XmlHelper.cs | 51 ++
.../Repositories/SqlsugarRepository.cs | 147 +++++
.../Sqlsugar/Uow/SqlsugarUnitOfWork.cs | 51 ++
.../Sqlsugar/Uow/SqlsugarUnitOfWorkManager.cs | 38 ++
.../Uow/DefaultUnitOfWork.cs | 26 +
.../Uow/DefaultUnitOfWorkManager.cs | 10 +
.../Uow/IUnitOfWork.cs | 14 +
.../Uow/IUnitOfWorkManager.cs | 8 +
.../Yi.Framework.Infrastructure.csproj | 14 +-
.../HeiCaptcha/HeiCaptchaExtension.cs | 26 +
.../HeiCaptcha/ImageRgba32Extension.cs | 32 +
.../HeiCaptcha/ImageSharpExtension.cs | 216 ++++++
.../HeiCaptcha/SecurityCodeHelper.cs | 182 ++++++
.../ImageSharp/HeiCaptcha/fonts/Candara.ttf | Bin 0 -> 219524 bytes
.../ImageSharp/HeiCaptcha/fonts/STCAIYUN.ttf | Bin 0 -> 5673836 bytes
.../ImageSharp/HeiCaptcha/fonts/impact.ttf | Bin 0 -> 214808 bytes
.../ImageSharp/HeiCaptcha/fonts/monbaiti.ttf | Bin 0 -> 290236 bytes
.../ImageSharp/ImageSharpManager.cs | 65 ++
.../OperLogManager/GlobalOperLogAttribute.cs | 93 +++
.../OperLogManager/IOperationLogService.cs | 12 +
.../OperLogManager/OperEnum.cs | 21 +
.../OperLogManager/OperLogAttribute.cs | 38 ++
.../OperLogManager/OperationLogEntity.cs | 65 ++
.../OperationLogGetListInputVo.cs | 10 +
.../OperationLogGetListOutputDto.cs | 19 +
.../OperLogManager/OperationLogService.cs | 36 +
.../Sms/Aliyun/SmsAliyunManager.cs | 66 ++
.../Sms/Aliyun/SmsAliyunOptions.cs | 14 +
Yi.Furion.Rbac/Yi.Framework.Module/Startup.cs | 26 +
.../Yi.Framework.Module.csproj | 19 +
.../System/Domain/AccountManager.cs | 140 ++++
.../System/Domain/RoleManager.cs | 42 ++
.../System/Domain/UserManager.cs | 77 +++
.../System/Dtos/Account/CaptchaImageDto.cs | 15 +
.../System/Dtos/Account/LoginInputVo.cs | 18 +
.../Dtos/Account/PhoneCaptchaImageDto.cs | 13 +
.../System/Dtos/Account/RegisterDto.cs | 39 ++
.../System/Dtos/Account/RestPasswordDto.cs | 13 +
.../System/Dtos/Account/UpdateIconDto.cs | 13 +
.../System/Dtos/Account/UpdatePasswordDto.cs | 14 +
.../System/Dtos/Dept/DeptCreateInputVo.cs | 24 +
.../System/Dtos/Dept/DeptGetListInputVo.cs | 16 +
.../System/Dtos/Dept/DeptGetListOutputDto.cs | 19 +
.../System/Dtos/Dept/DeptGetOutputDto.cs | 20 +
.../System/Dtos/Dept/DeptUpdateInputVo.cs | 21 +
.../System/Dtos/Mapper.cs | 8 -
.../System/Dtos/Menu/MenuCreateInputVo.cs | 27 +
.../System/Dtos/Menu/MenuGetListInputVo.cs | 12 +
.../System/Dtos/Menu/MenuGetListOutputDto.cs | 28 +
.../System/Dtos/Menu/MenuGetOutputDto.cs | 29 +
.../System/Dtos/Menu/MenuUpdateInputVo.cs | 25 +
.../System/Dtos/Post/PostCreateInputVo.cs | 22 +
.../System/Dtos/Post/PostGetListInputVo.cs | 11 +
.../System/Dtos/Post/PostGetListOutputDto.cs | 16 +
.../System/Dtos/Post/PostGetOutputDto.cs | 17 +
.../System/Dtos/Post/PostUpdateInputVo.cs | 13 +
.../System/Dtos/Role/RoleCreateInputVo.cs | 22 +
.../System/Dtos/Role/RoleGetListInputVo.cs | 12 +
.../System/Dtos/Role/RoleGetListOutputDto.cs | 19 +
.../System/Dtos/Role/RoleGetOutputDto.cs | 19 +
.../System/Dtos/Role/RoleUpdateInputVo.cs | 19 +
.../System/Dtos/User/ProfileUpdateInputVo.cs | 17 +
.../System/Dtos/User/UserCreateInputVo.cs | 27 +
.../System/Dtos/User/UserGetListInputVo.cs | 18 +
.../System/Dtos/User/UserGetListOutputDto.cs | 30 +
.../System/Dtos/User/UserGetOutputDto.cs | 35 +
.../System/Dtos/User/UserUpdateInputVo.cs | 28 +
.../System/Event/LoginEventHandler.cs | 77 +++
.../System/Services/IDeptService.cs | 13 +
.../System/Services/IMenuService.cs | 13 +
.../System/Services/IPostService.cs | 13 +
.../System/Services/IRoleService.cs | 13 +
.../System/Services/ISystemService.cs | 6 -
.../System/Services/IUserService.cs | 12 +
.../System/Services/Impl/AccountService.cs | 375 +++++++++++
.../System/Services/Impl/DeptService.cs | 47 ++
.../System/Services/Impl/MenuService.cs | 41 ++
.../System/Services/Impl/PostService.cs | 27 +
.../System/Services/Impl/RoleService.cs | 103 +++
.../System/Services/Impl/UserService.cs | 190 ++++++
.../System/Services/SystemService.cs | 16 -
.../System/SystemAppService.cs | 22 -
.../Yi.Furion.Rbac.Application.csproj | 3 +-
.../Yi.Furion.Rbac.Application.xml | 11 -
.../ConstClasses/DeptConst.cs | 16 +
.../ConstClasses/MenuConst.cs | 16 +
.../ConstClasses/PostConst.cs | 16 +
.../ConstClasses/RoleConst.cs | 16 +
.../ConstClasses/UserConst.cs | 29 +
.../Dtos/UserRoleMenuDto.cs | 15 +
.../Yi.Furion.Rbac.Core/Dtos/Vue3RouterDto.cs | 30 +
.../Entities/DeptEntity.cs | 85 +++
.../Entities/LoginLogEntity.cs | 48 ++
.../Entities/MenuEntity.cs | 196 ++++++
.../Entities/PostEntity.cs | 74 +++
.../Entities/RoleDeptEntity.cs | 34 +
.../Entities/RoleEntity.cs | 88 +++
.../Entities/RoleMenuEntity.cs | 32 +
.../Entities/UserEntity.cs | 211 ++++++
.../Entities/UserPostEntity.cs | 31 +
.../Entities/UserRoleEntity.cs | 31 +
.../EnumClasses/DataScopeEnum.cs | 17 +
.../EnumClasses/MenuTypeEnum.cs | 15 +
.../EnumClasses/SexEnum.cs | 28 +
.../Etos/LoginEventSource.cs | 31 +
.../Yi.Furion.Rbac.Core.csproj | 15 +-
.../Yi.Furion.Rbac.Core.xml | 614 ++++++++++++++++++
.../Repositories/IUserRepository.cs | 18 +
.../Repositories/Impl/UserRepository.cs | 82 +++
.../Startup.cs | 2 +-
.../Handlers/JwtHandler.cs | 2 +-
.../Yi.Furion.Rbac.Web.Core/Startup.cs | 3 +
.../yi-sqlsugar-dev.db | 0
Yi.Furion.Rbac/Yi.Furion.Rbac.sln | 8 +-
194 files changed, 9557 insertions(+), 75 deletions(-)
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/AspNetCore/HttpContextExtensions.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/AuditedObject.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IAuditedObject.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/ICreationAuditedObject.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IDeletionAuditedObject.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IFullAuditedObject.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasCreationTime.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasDeletionTime.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasEntityVersion.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasModificationTime.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IMayHaveCreator.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IModificationAuditedObject.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IMustHaveCreator.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/IMultiTenant.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/IOrderNum.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/ISoftDelete.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/IState.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IEntityDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IHasTotalCount.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IListResult.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IPagedAllResultRequestDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IPagedAndSortedResultRequestDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IPagedResult.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/EntityDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/ListResultDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedAllResultRequestDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedAndSortedResultRequestDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedResultDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/AggregateRoot.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/Entity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/IAggregateRoot.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/IEntity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Repositories/IRepository.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IApplicationService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/ICreateAppService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/ICreateUpdateAppService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/ICrudAppService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IDeleteAppService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IPageTimeResultRequestDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IReadOnlyAppService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IUpdateAppService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/ApplicationService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/CrudAppService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/ReadOnlyAppService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/FileTypeEnum.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/OrderByEnum.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/QueryOperatorEnum.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/ResultCodeEnum.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/AuthException.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/BusinessException.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/ExceptionExtensions.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/IHasErrorCode.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/IHasErrorDetails.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/IHasLogLevel.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/UserFriendlyException.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/AssemblyHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/Base32Helper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/ConsoleHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/DateHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/DistinctHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/EnumHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/ExpressionHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/FileHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/HtmlHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/HttpHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/IdHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/IpHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/JsonHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/MD5Hepler.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/MimeHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/RSAFileHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/RSAHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/RandomHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/ReflexHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/SnowflakeHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/StringHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/TreeHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/UnicodeHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/UrlHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/XmlHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Sqlsugar/Repositories/SqlsugarRepository.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Sqlsugar/Uow/SqlsugarUnitOfWork.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Sqlsugar/Uow/SqlsugarUnitOfWorkManager.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Uow/DefaultUnitOfWork.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Uow/DefaultUnitOfWorkManager.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Uow/IUnitOfWork.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Infrastructure/Uow/IUnitOfWorkManager.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/ImageSharp/HeiCaptcha/HeiCaptchaExtension.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/ImageSharp/HeiCaptcha/ImageRgba32Extension.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/ImageSharp/HeiCaptcha/ImageSharpExtension.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/ImageSharp/HeiCaptcha/SecurityCodeHelper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/ImageSharp/HeiCaptcha/fonts/Candara.ttf
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/ImageSharp/HeiCaptcha/fonts/STCAIYUN.ttf
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/ImageSharp/HeiCaptcha/fonts/impact.ttf
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/ImageSharp/HeiCaptcha/fonts/monbaiti.ttf
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/ImageSharp/ImageSharpManager.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/OperLogManager/GlobalOperLogAttribute.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/OperLogManager/IOperationLogService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/OperLogManager/OperEnum.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/OperLogManager/OperLogAttribute.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/OperLogManager/OperationLogEntity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/OperLogManager/OperationLogGetListInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/OperLogManager/OperationLogGetListOutputDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/OperLogManager/OperationLogService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/Sms/Aliyun/SmsAliyunManager.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/Sms/Aliyun/SmsAliyunOptions.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/Startup.cs
create mode 100644 Yi.Furion.Rbac/Yi.Framework.Module/Yi.Framework.Module.csproj
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Domain/AccountManager.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Domain/RoleManager.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Domain/UserManager.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Account/CaptchaImageDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Account/LoginInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Account/PhoneCaptchaImageDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Account/RegisterDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Account/RestPasswordDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Account/UpdateIconDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Account/UpdatePasswordDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Dept/DeptCreateInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Dept/DeptGetListInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Dept/DeptGetListOutputDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Dept/DeptGetOutputDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Dept/DeptUpdateInputVo.cs
delete mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Mapper.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Menu/MenuCreateInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Menu/MenuGetListInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Menu/MenuGetListOutputDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Menu/MenuGetOutputDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Menu/MenuUpdateInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Post/PostCreateInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Post/PostGetListInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Post/PostGetListOutputDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Post/PostGetOutputDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Post/PostUpdateInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Role/RoleCreateInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Role/RoleGetListInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Role/RoleGetListOutputDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Role/RoleGetOutputDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/Role/RoleUpdateInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/User/ProfileUpdateInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/User/UserCreateInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/User/UserGetListInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/User/UserGetListOutputDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/User/UserGetOutputDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Dtos/User/UserUpdateInputVo.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Event/LoginEventHandler.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/IDeptService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/IMenuService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/IPostService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/IRoleService.cs
delete mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/ISystemService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/IUserService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/Impl/AccountService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/Impl/DeptService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/Impl/MenuService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/Impl/PostService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/Impl/RoleService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/Impl/UserService.cs
delete mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/Services/SystemService.cs
delete mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Application/System/SystemAppService.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/ConstClasses/DeptConst.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/ConstClasses/MenuConst.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/ConstClasses/PostConst.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/ConstClasses/RoleConst.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/ConstClasses/UserConst.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Dtos/UserRoleMenuDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Dtos/Vue3RouterDto.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Entities/DeptEntity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Entities/LoginLogEntity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Entities/MenuEntity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Entities/PostEntity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Entities/RoleDeptEntity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Entities/RoleEntity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Entities/RoleMenuEntity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Entities/UserEntity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Entities/UserPostEntity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Entities/UserRoleEntity.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/EnumClasses/DataScopeEnum.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/EnumClasses/MenuTypeEnum.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/EnumClasses/SexEnum.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Core/Etos/LoginEventSource.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.EntityFramework.Core/Repositories/IUserRepository.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.EntityFramework.Core/Repositories/Impl/UserRepository.cs
create mode 100644 Yi.Furion.Rbac/Yi.Furion.Rbac.Web.Entry/yi-sqlsugar-dev.db
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/AspNetCore/HttpContextExtensions.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/AspNetCore/HttpContextExtensions.cs
new file mode 100644
index 00000000..10aff64b
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/AspNetCore/HttpContextExtensions.cs
@@ -0,0 +1,99 @@
+using Microsoft.AspNetCore.Http;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.AspNetCore
+{
+ public static class HttpContextExtensions
+ {
+ ///
+ /// 设置文件下载名称
+ ///
+ ///
+ ///
+ public static void FileInlineHandle(this HttpContext httpContext, string fileName)
+ {
+ string encodeFilename = System.Web.HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));
+ httpContext.Response.Headers.Add("Content-Disposition", "inline;filename=" + encodeFilename);
+
+ }
+
+ ///
+ /// 设置文件附件名称
+ ///
+ ///
+ ///
+ public static void FileAttachmentHandle(this HttpContext httpContext, string fileName)
+ {
+ string encodeFilename = System.Web.HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));
+ httpContext.Response.Headers.Add("Content-Disposition", "attachment;filename=" + encodeFilename);
+
+ }
+
+ ///
+ /// 获取语言种类
+ ///
+ ///
+ ///
+ public static string GetLanguage(this HttpContext httpContext)
+ {
+ string res = "zh-CN";
+ var str = httpContext.Request.Headers["Accept-Language"].FirstOrDefault();
+ if (str is not null)
+ {
+ res = str.Split(",")[0];
+ }
+ return res;
+
+ }
+
+ ///
+ /// 判断是否为异步请求
+ ///
+ ///
+ ///
+ public static bool IsAjaxRequest(this HttpRequest request)
+ {
+ string header = request.Headers["X-Requested-With"];
+ return "XMLHttpRequest".Equals(header);
+ }
+ ///
+ /// 获取客户端IP
+ ///
+ ///
+ ///
+ public static string GetClientIp(this HttpContext context)
+ {
+ if (context == null) return "";
+ var result = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
+ if (string.IsNullOrEmpty(result))
+ {
+ result = context.Connection.RemoteIpAddress?.ToString();
+ }
+ if (string.IsNullOrEmpty(result) || result.Contains("::1"))
+ result = "127.0.0.1";
+
+ result = result.Replace("::ffff:", "127.0.0.1");
+
+ //Ip规则效验
+ var regResult = Regex.IsMatch(result, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
+
+ result = regResult ? result : "127.0.0.1";
+ return result;
+ }
+
+ ///
+ /// 获取浏览器标识
+ ///
+ ///
+ ///
+ public static string GetUserAgent(this HttpContext context)
+ {
+ return context.Request.Headers["User-Agent"];
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/AuditedObject.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/AuditedObject.cs
new file mode 100644
index 00000000..8f298ce9
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/AuditedObject.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Data.Auditing
+{
+ public class AuditedObject : IAuditedObject
+ {
+ public DateTime CreationTime { get; set; } = DateTime.Now;
+
+ public long? CreatorId { get; set; }
+
+ public long? LastModifierId { get; set; }
+
+ public DateTime? LastModificationTime { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IAuditedObject.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IAuditedObject.cs
new file mode 100644
index 00000000..ef152e59
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IAuditedObject.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Data.Auditing
+{
+ public interface IAuditedObject : ICreationAuditedObject, IModificationAuditedObject
+ {
+ }
+
+ public interface IAuditedObject : IAuditedObject, ICreationAuditedObject, IModificationAuditedObject
+ {
+
+ }
+
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/ICreationAuditedObject.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/ICreationAuditedObject.cs
new file mode 100644
index 00000000..163abfd1
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/ICreationAuditedObject.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Data.Auditing
+{
+ public interface ICreationAuditedObject : IHasCreationTime, IMayHaveCreator
+ {
+
+ }
+
+ public interface ICreationAuditedObject : ICreationAuditedObject, IMayHaveCreator
+ {
+
+ }
+
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IDeletionAuditedObject.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IDeletionAuditedObject.cs
new file mode 100644
index 00000000..7cfa8cd8
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IDeletionAuditedObject.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Data.Auditing
+{
+ public interface IDeletionAuditedObject : IHasDeletionTime
+ {
+ long? DeleterId { get; }
+ }
+
+ public interface IDeletionAuditedObject : IDeletionAuditedObject
+ {
+
+ TUser Deleter { get; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IFullAuditedObject.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IFullAuditedObject.cs
new file mode 100644
index 00000000..d2e490cb
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IFullAuditedObject.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Data.Auditing
+{
+ public interface IFullAuditedObject : IAuditedObject, IDeletionAuditedObject
+ {
+
+ }
+
+ public interface IFullAuditedObject : IAuditedObject, IFullAuditedObject, IDeletionAuditedObject
+ {
+
+ }
+
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasCreationTime.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasCreationTime.cs
new file mode 100644
index 00000000..3c295f18
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasCreationTime.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Yi.Framework.Infrastructure.Data.Auditing;
+
+
+public interface IHasCreationTime
+{
+
+ DateTime CreationTime { get; set; }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasDeletionTime.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasDeletionTime.cs
new file mode 100644
index 00000000..08546e2e
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasDeletionTime.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Yi.Framework.Infrastructure.Data.Entities;
+
+namespace Yi.Framework.Infrastructure.Data.Auditing
+{
+ public interface IHasDeletionTime : ISoftDelete
+ {
+ DateTime? DeletionTime { get; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasEntityVersion.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasEntityVersion.cs
new file mode 100644
index 00000000..ec25e44f
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasEntityVersion.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Data.Auditing
+{
+ public interface IHasEntityVersion
+ {
+ int EntityVersion { get; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasModificationTime.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasModificationTime.cs
new file mode 100644
index 00000000..561b138b
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IHasModificationTime.cs
@@ -0,0 +1,8 @@
+namespace Yi.Framework.Infrastructure.Data.Auditing;
+
+
+public interface IHasModificationTime
+{
+
+ DateTime? LastModificationTime { get; }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IMayHaveCreator.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IMayHaveCreator.cs
new file mode 100644
index 00000000..828b8255
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IMayHaveCreator.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace Yi.Framework.Infrastructure.Data.Auditing;
+
+public interface IMayHaveCreator
+{
+ TCreator Creator { get; }
+}
+
+public interface IMayHaveCreator
+{
+ long? CreatorId { get; }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IModificationAuditedObject.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IModificationAuditedObject.cs
new file mode 100644
index 00000000..5699ed89
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IModificationAuditedObject.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Data.Auditing
+{
+ public interface IModificationAuditedObject : IHasModificationTime
+ {
+ long? LastModifierId { get; }
+ }
+
+ public interface IModificationAuditedObject : IModificationAuditedObject
+ {
+ TUser LastModifier { get; }
+ }
+
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IMustHaveCreator.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IMustHaveCreator.cs
new file mode 100644
index 00000000..6fa8440f
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Auditing/IMustHaveCreator.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace Yi.Framework.Infrastructure.Data.Auditing;
+
+public interface IMustHaveCreator : IMustHaveCreator
+{
+ TCreator Creator { get; }
+}
+
+public interface IMustHaveCreator
+{
+ long CreatorId { get; }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/IMultiTenant.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/IMultiTenant.cs
new file mode 100644
index 00000000..9da9a648
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/IMultiTenant.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Data.Entities
+{
+ public interface IMultiTenant
+ {
+ public Guid TenantId { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/IOrderNum.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/IOrderNum.cs
new file mode 100644
index 00000000..4da6f86e
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/IOrderNum.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Data.Entities
+{
+ public interface IOrderNum
+ {
+ int OrderNum { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/ISoftDelete.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/ISoftDelete.cs
new file mode 100644
index 00000000..552dfadf
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/ISoftDelete.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Data.Entities
+{
+ public interface ISoftDelete
+ {
+ public bool IsDeleted { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/IState.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/IState.cs
new file mode 100644
index 00000000..2f393315
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Data/Entities/IState.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Data.Entities
+{
+ public interface IState
+ {
+ public bool State { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IEntityDto.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IEntityDto.cs
new file mode 100644
index 00000000..1897dbe2
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IEntityDto.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Dtos.Abstract
+{
+ public interface IEntityDto
+ {
+ }
+
+ public interface IEntityDto : IEntityDto
+ {
+ TKey Id { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IHasTotalCount.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IHasTotalCount.cs
new file mode 100644
index 00000000..5330e350
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IHasTotalCount.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Dtos.Abstract
+{
+ public interface IHasTotalCount
+ {
+ long Total { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IListResult.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IListResult.cs
new file mode 100644
index 00000000..c772a35d
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IListResult.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Dtos.Abstract
+{
+ public interface IListResult
+ {
+ IReadOnlyList Items { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IPagedAllResultRequestDto.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IPagedAllResultRequestDto.cs
new file mode 100644
index 00000000..03efe9bc
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IPagedAllResultRequestDto.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Yi.Framework.Infrastructure.Ddd.Services.Abstract;
+
+namespace Yi.Framework.Infrastructure.Ddd.Dtos.Abstract
+{
+ public interface IPagedAllResultRequestDto : IPageTimeResultRequestDto, IPagedAndSortedResultRequestDto
+ {
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IPagedAndSortedResultRequestDto.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IPagedAndSortedResultRequestDto.cs
new file mode 100644
index 00000000..a616fa2f
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IPagedAndSortedResultRequestDto.cs
@@ -0,0 +1,15 @@
+
+
+using Yi.Framework.Infrastructure.Enums;
+
+namespace Yi.Framework.Infrastructure.Ddd.Dtos.Abstract
+{
+ public interface IPagedAndSortedResultRequestDto
+ {
+ int PageNum { get; set; }
+ int PageSize { get; set; }
+ string? SortBy { get; set; }
+
+ OrderByEnum SortType { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IPagedResult.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IPagedResult.cs
new file mode 100644
index 00000000..7547fd91
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/Abstract/IPagedResult.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Dtos.Abstract
+{
+ public interface IPagedResult : IListResult, IHasTotalCount
+ {
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/EntityDto.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/EntityDto.cs
new file mode 100644
index 00000000..73ccf3b9
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/EntityDto.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Yi.Framework.Infrastructure.Ddd.Dtos.Abstract;
+
+namespace Yi.Framework.Infrastructure.Ddd.Dtos
+{
+ [Serializable]
+ public abstract class EntityDto : EntityDto, IEntityDto, IEntityDto
+ {
+ //
+ // 摘要:
+ // Id of the entity.
+ public TKey Id { get; set; }
+
+ public override string ToString()
+ {
+ return $"[DTO: {GetType().Name}] Id = {Id}";
+ }
+ }
+
+ [Serializable]
+ public abstract class EntityDto : IEntityDto
+ {
+ public override string ToString()
+ {
+ return "[DTO: " + GetType().Name + "]";
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/ListResultDto.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/ListResultDto.cs
new file mode 100644
index 00000000..bb35ef6a
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/ListResultDto.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Yi.Framework.Infrastructure.Ddd.Dtos.Abstract;
+
+namespace Yi.Framework.Infrastructure.Ddd.Dtos
+{
+ [Serializable]
+ public class ListResultDto : IListResult
+ {
+ public IReadOnlyList Items
+ {
+ get { return _items ?? (_items = new List()); }
+ set { _items = value; }
+ }
+ private IReadOnlyList _items;
+
+ public ListResultDto()
+ {
+
+ }
+
+ public ListResultDto(IReadOnlyList items)
+ {
+ Items = items;
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedAllResultRequestDto.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedAllResultRequestDto.cs
new file mode 100644
index 00000000..f92781a6
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedAllResultRequestDto.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Yi.Framework.Infrastructure.Ddd.Dtos.Abstract;
+using Yi.Framework.Infrastructure.Ddd.Services.Abstract;
+
+namespace Yi.Framework.Infrastructure.Ddd.Dtos
+{
+ public class PagedAllResultRequestDto : PagedAndSortedResultRequestDto, IPagedAllResultRequestDto, IPagedAndSortedResultRequestDto, IPageTimeResultRequestDto
+ {
+ ///
+ /// 查询开始时间条件
+ ///
+ public DateTime? StartTime { get; set; }
+
+ ///
+ /// 查询结束时间条件
+ ///
+ public DateTime? EndTime { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedAndSortedResultRequestDto.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedAndSortedResultRequestDto.cs
new file mode 100644
index 00000000..1a9d685a
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedAndSortedResultRequestDto.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Yi.Framework.Infrastructure.Ddd.Dtos.Abstract;
+using Yi.Framework.Infrastructure.Enums;
+
+namespace Yi.Framework.Infrastructure.Ddd.Dtos
+{
+ public class PagedAndSortedResultRequestDto : IPagedAndSortedResultRequestDto
+ {
+ ///
+ /// 查询当前页条件
+ ///
+ public int PageNum { get; set; } = 1;
+
+ ///
+ /// 查询分页大小条件
+ ///
+ public int PageSize { get; set; } = int.MaxValue;
+
+ ///
+ /// 查询排序字段条件
+ ///
+ public string? SortBy { get; set; }
+
+ ///
+ /// 查询排序类别条件
+ ///
+ public OrderByEnum SortType { get; set; } = OrderByEnum.Desc;
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedDto.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedDto.cs
new file mode 100644
index 00000000..b36e5683
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedDto.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Dtos
+{
+ public class PagedDto
+ {
+ public PagedDto(long totalCount, List items)
+ {
+ Total = totalCount;
+ Items = items;
+ }
+ public long Total { get; set; }
+
+ public List Items { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedResultDto.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedResultDto.cs
new file mode 100644
index 00000000..030cb957
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Dtos/PagedResultDto.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Yi.Framework.Infrastructure.Ddd.Dtos.Abstract;
+
+namespace Yi.Framework.Infrastructure.Ddd.Dtos
+{
+ public class PagedResultDto : ListResultDto, IPagedResult
+ {
+ public long Total { get; set; }
+
+ public PagedResultDto()
+ {
+
+ }
+
+ public PagedResultDto(long totalCount, IReadOnlyList items)
+ : base(items)
+ {
+ Total = totalCount;
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/AggregateRoot.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/AggregateRoot.cs
new file mode 100644
index 00000000..bae304e0
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/AggregateRoot.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Entities
+{
+ public class AggregateRoot : IEntity, IAggregateRoot
+ {
+ }
+ public class AggregateRoot : Entity, IEntity
+ {
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/Entity.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/Entity.cs
new file mode 100644
index 00000000..9fc1f0ed
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/Entity.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Principal;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Entities
+{
+ [Serializable]
+ public abstract class Entity : IEntity
+ {
+ protected Entity()
+ {
+ }
+
+ public override string ToString()
+ {
+ return "[ENTITY: " + GetType().Name + "] Keys = " + GetKeys();
+ }
+
+ public abstract object[] GetKeys();
+
+ //实体比较简化
+ //public bool EntityEquals(IEntity other)
+ //{
+ // return this.GetKeys().Equals(other.GetKeys());
+ //}
+
+ }
+
+ [Serializable]
+ public abstract class Entity : Entity, IEntity, IEntity
+ {
+ public virtual TKey Id { get; set; }
+
+ protected Entity()
+ {
+ }
+
+ protected Entity(TKey id)
+ {
+ Id = id;
+ }
+
+ public override object[] GetKeys()
+ {
+ return new object[1] { Id };
+ }
+
+ public override string ToString()
+ {
+ return $"[ENTITY: {GetType().Name}] Id = {Id}";
+ }
+
+
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/IAggregateRoot.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/IAggregateRoot.cs
new file mode 100644
index 00000000..b0d7cd17
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/IAggregateRoot.cs
@@ -0,0 +1,16 @@
+using Microsoft.AspNetCore.DataProtection.KeyManagement;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Entities
+{
+ public interface IAggregateRoot : IEntity
+ {
+ }
+ public interface IAggregateRoot : IEntity
+ {
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/IEntity.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/IEntity.cs
new file mode 100644
index 00000000..7e31d1a8
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Entities/IEntity.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Entities
+{
+ public interface IEntity
+ {
+ //
+ // 摘要:
+ // Returns an array of ordered keys for this entity.
+
+ }
+ public interface IEntity : IEntity
+ {
+ //
+ // 摘要:
+ // Unique identifier for this entity.
+ TKey Id { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Repositories/IRepository.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Repositories/IRepository.cs
new file mode 100644
index 00000000..032b920a
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Repositories/IRepository.cs
@@ -0,0 +1,57 @@
+using System.Linq.Expressions;
+using SqlSugar;
+using Yi.Framework.Infrastructure.Ddd.Dtos.Abstract;
+using Yi.Framework.Infrastructure.Enums;
+
+namespace Yi.Framework.Infrastructure.Ddd.Repositories
+{
+ public interface IRepository
+ {
+ ///
+ /// 注释一下,严格意义这里应该protected,但是我认为 简易程度 与 耦合程度 中是需要进行衡量的
+ ///
+ ISugarQueryable _DbQueryable { get; }
+ //单查
+ Task GetByIdAsync(dynamic id);
+ Task GetSingleAsync(Expression> whereExpression);
+ Task GetFirstAsync(Expression> whereExpression);
+ Task IsAnyAsync(Expression> whereExpression);
+ Task CountAsync(Expression> whereExpression);
+
+ //多查
+ Task> GetListAsync();
+ Task> GetListAsync(Expression> whereExpression);
+
+ //分页查
+ Task> GetPageListAsync(Expression> whereExpression, int pageNum, int pageSize);
+ Task> GetPageListAsync(Expression> whereExpression, int pageNum, int pageSize, Expression>? orderByExpression = null, OrderByEnum orderByType = OrderByEnum.Asc);
+ Task> GetPageListAsync(Expression> whereExpression, int pageNum, int pageSize, string? orderBy, OrderByEnum orderByType = OrderByEnum.Asc);
+ Task> GetPageListAsync(Expression> whereExpression, IPagedAndSortedResultRequestDto page);
+ Task> GetPageListAsync(Expression> whereExpression, IPagedAndSortedResultRequestDto page, Expression>? orderByExpression = null, OrderByEnum orderByType = OrderByEnum.Asc);
+ Task> GetPageListAsync(Expression> whereExpression, IPagedAndSortedResultRequestDto page, string? orderBy, OrderByEnum orderByType = OrderByEnum.Asc);
+
+ //插入
+ Task InsertAsync(T insertObj);
+ Task InsertOrUpdateAsync(T data);
+ Task InsertOrUpdateAsync(List datas);
+ Task InsertReturnIdentityAsync(T insertObj);
+ Task InsertReturnBigIdentityAsync(T insertObj);
+ Task InsertReturnSnowflakeIdAsync(T insertObj);
+ Task InsertReturnEntityAsync(T insertObj);
+ Task InsertRangeAsync(List insertObjs);
+
+ //更新
+ Task UpdateAsync(T updateObj);
+ Task UpdateRangeAsync(List updateObjs);
+ Task UpdateAsync(Expression> columns, Expression> whereExpression);
+ Task UpdateIgnoreNullAsync(T updateObj);
+
+ //删除
+ Task DeleteAsync(T deleteObj);
+ Task DeleteAsync(List deleteObjs);
+ Task DeleteAsync(Expression> whereExpression);
+ Task DeleteByIdAsync(dynamic id);
+ Task DeleteByIdsAsync(dynamic[] ids);
+
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IApplicationService.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IApplicationService.cs
new file mode 100644
index 00000000..e4b422af
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IApplicationService.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Services.Abstract
+{
+ public interface IApplicationService
+ {
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/ICreateAppService.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/ICreateAppService.cs
new file mode 100644
index 00000000..8880e9ef
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/ICreateAppService.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Services.Abstract
+{
+ public interface ICreateAppService
+ : ICreateAppService
+ {
+
+ }
+
+ public interface ICreateAppService
+ : IApplicationService
+ {
+ Task CreateAsync(TCreateInput input);
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/ICreateUpdateAppService.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/ICreateUpdateAppService.cs
new file mode 100644
index 00000000..dab0842c
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/ICreateUpdateAppService.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Services.Abstract
+{
+ public interface ICreateUpdateAppService
+ : ICreateUpdateAppService
+ {
+
+ }
+
+ public interface ICreateUpdateAppService
+ : ICreateUpdateAppService
+ {
+
+ }
+
+ public interface ICreateUpdateAppService
+ : ICreateAppService,
+ IUpdateAppService
+ {
+
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/ICrudAppService.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/ICrudAppService.cs
new file mode 100644
index 00000000..e161a12a
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/ICrudAppService.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Yi.Framework.Infrastructure.Ddd.Dtos;
+
+namespace Yi.Framework.Infrastructure.Ddd.Services.Abstract
+{
+
+ public interface ICrudAppService
+ : ICrudAppService
+ {
+
+ }
+
+ public interface ICrudAppService
+ : ICrudAppService
+ {
+
+ }
+
+ public interface ICrudAppService
+ : ICrudAppService
+ {
+
+ }
+
+ public interface ICrudAppService
+ : ICrudAppService
+ {
+
+ }
+
+ public interface ICrudAppService
+ : IReadOnlyAppService,
+ ICreateUpdateAppService,
+ IDeleteAppService
+ {
+
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IDeleteAppService.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IDeleteAppService.cs
new file mode 100644
index 00000000..87517a59
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IDeleteAppService.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Services.Abstract
+{
+ public interface IDeleteAppService : IApplicationService
+ {
+ Task DeleteAsync(string id);
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IPageTimeResultRequestDto.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IPageTimeResultRequestDto.cs
new file mode 100644
index 00000000..e565557c
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IPageTimeResultRequestDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Yi.Framework.Infrastructure.Ddd.Dtos.Abstract;
+
+namespace Yi.Framework.Infrastructure.Ddd.Services.Abstract
+{
+ public interface IPageTimeResultRequestDto : IPagedAndSortedResultRequestDto
+ {
+ DateTime? StartTime { get; set; }
+ DateTime? EndTime { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IReadOnlyAppService.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IReadOnlyAppService.cs
new file mode 100644
index 00000000..55e81ccf
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IReadOnlyAppService.cs
@@ -0,0 +1,24 @@
+using Yi.Framework.Infrastructure.Ddd.Dtos;
+
+namespace Yi.Framework.Infrastructure.Ddd.Services.Abstract
+{
+ public interface IReadOnlyAppService
+ : IReadOnlyAppService
+ {
+
+ }
+
+ public interface IReadOnlyAppService
+ : IReadOnlyAppService
+ {
+
+ }
+
+ public interface IReadOnlyAppService
+ : IApplicationService
+ {
+ Task GetAsync(TKey id);
+
+ Task> GetListAsync(TGetListInput input);
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IUpdateAppService.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IUpdateAppService.cs
new file mode 100644
index 00000000..4c19a06c
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/Abstract/IUpdateAppService.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Ddd.Services.Abstract
+{
+ public interface IUpdateAppService
+ : IUpdateAppService
+ {
+
+ }
+
+ public interface IUpdateAppService
+ : IApplicationService
+ {
+ Task UpdateAsync(TKey id, TUpdateInput input);
+ }
+
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/ApplicationService.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/ApplicationService.cs
new file mode 100644
index 00000000..b9cb74d6
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/ApplicationService.cs
@@ -0,0 +1,11 @@
+using Furion;
+using MapsterMapper;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Yi.Framework.Infrastructure.Ddd.Services
+{
+ public abstract class ApplicationService
+ {
+ public IMapper _mapper { get => App.GetRequiredService(); }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/CrudAppService.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/CrudAppService.cs
new file mode 100644
index 00000000..cca23a49
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/CrudAppService.cs
@@ -0,0 +1,176 @@
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Yi.Framework.Infrastructure.Ddd.Dtos;
+using Yi.Framework.Infrastructure.Ddd.Dtos.Abstract;
+using Yi.Framework.Infrastructure.Ddd.Entities;
+using Yi.Framework.Infrastructure.Ddd.Services.Abstract;
+using Yi.Framework.Infrastructure.Helper;
+
+namespace Yi.Framework.Infrastructure.Ddd.Services
+{
+
+ public abstract class CrudAppService
+ : CrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ {
+ }
+
+ public abstract class CrudAppService
+ : CrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ {
+ }
+
+ public abstract class CrudAppService
+ : CrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ {
+ }
+
+
+
+
+ public abstract class CrudAppService
+ : CrudAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ {
+ protected override Task MapToGetListOutputDtoAsync(TEntity entity)
+ {
+ return MapToGetOutputDtoAsync(entity);
+ }
+
+ }
+
+ public abstract class CrudAppService
+ : ReadOnlyAppService,
+ ICrudAppService
+ where TEntity : class, IEntity
+ where TGetOutputDto : IEntityDto
+ where TGetListOutputDto : IEntityDto
+
+ {
+ protected virtual Task MapToEntityAsync(TGetListInput getListinput)
+ {
+ return Task.FromResult(_mapper.Map(getListinput));
+ }
+
+
+ protected virtual Task MapToEntityAsync(TCreateInput createInput)
+ {
+ var entity = _mapper.Map(createInput);
+
+ //这里判断实体的T,给id赋值
+
+ //雪花id
+ if (entity is IEntity entityForlongId)
+ {
+ if (entityForlongId.Id is default(long))
+ {
+ //使用反射,暂时先使用sqlsuga的雪花id提供
+ //ps: linshi
+ ReflexHelper.SetModelValue(nameof(IEntity.Id), SnowflakeHelper.NextId, entity);
+ }
+ }
+ if (entity is IEntity entityForGuidId)
+ {
+ if (entityForGuidId.Id == Guid.Empty)
+ {
+ ReflexHelper.SetModelValue(nameof(IEntity.Id), new Guid(), entity);
+ }
+ }
+
+ return Task.FromResult(entity);
+ }
+ protected virtual Task MapToEntityAsync(TUpdateInput updateInput, TEntity entity)
+ {
+ _mapper.Map(updateInput, entity);
+ return Task.CompletedTask;
+ }
+
+ protected virtual Task MapToEntityAsync(TUpdateInput updateInput)
+ {
+ var entity = _mapper.Map(updateInput);
+ return Task.FromResult(entity);
+ }
+
+ ///
+ /// 增
+ ///
+ ///
+ ///
+ public virtual async Task CreateAsync(TCreateInput input)
+ {
+ var entity = await MapToEntityAsync(input);
+
+ //这里还可以设置租户
+ await _repository.InsertAsync(entity);
+
+ return await MapToGetOutputDtoAsync(entity);
+ }
+
+ ///
+ /// 单、多删
+ ///
+ ///
+ ///
+ ///
+ public virtual async Task DeleteAsync(string id)
+ {
+ if (id is null)
+ {
+ throw new ArgumentNullException(nameof(id));
+ }
+ var idsValue = id.Split(',');
+ if (idsValue is null || idsValue.Length == 0)
+ {
+ throw new ArgumentNullException(nameof(id));
+ }
+ return await _repository.DeleteByIdsAsync(idsValue.Select(x => (object)x!).ToArray());
+ }
+
+ /////
+ ///// 删
+ /////
+ /////
+ /////
+ /////
+ //public async Task DeleteAsync(TKey id)
+ //{
+ // if (id is null)
+ // {
+ // throw new ArgumentNullException(nameof(id));
+ // }
+ // return await _repository.DeleteByIdAsync(id);
+ //}
+
+ ///
+ /// 改
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual async Task UpdateAsync(TKey id, TUpdateInput input)
+ {
+ if (id is null)
+ {
+ throw new ArgumentNullException(nameof(id));
+ }
+
+ var entity = await _repository.GetByIdAsync(id);
+ await MapToEntityAsync(input, entity);
+ await _repository.UpdateAsync(entity);
+
+ return await MapToGetOutputDtoAsync(entity);
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/ReadOnlyAppService.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/ReadOnlyAppService.cs
new file mode 100644
index 00000000..33afc5c6
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Ddd/Services/ReadOnlyAppService.cs
@@ -0,0 +1,128 @@
+using Furion;
+using Microsoft.Extensions.DependencyInjection;
+using SqlSugar;
+using Yi.Framework.Infrastructure.Ddd.Dtos;
+using Yi.Framework.Infrastructure.Ddd.Dtos.Abstract;
+using Yi.Framework.Infrastructure.Ddd.Entities;
+using Yi.Framework.Infrastructure.Ddd.Repositories;
+using Yi.Framework.Infrastructure.Ddd.Services.Abstract;
+
+namespace Yi.Framework.Infrastructure.Ddd.Services
+{
+
+ public abstract class ReadOnlyAppService
+ : ReadOnlyAppService
+ where TEntity : class, IEntity
+ where TEntityDto : IEntityDto
+ {
+ }
+
+ public abstract class ReadOnlyAppService
+: ReadOnlyAppService
+where TEntity : class, IEntity
+where TEntityDto : IEntityDto
+ {
+ }
+
+
+ public abstract class ReadOnlyAppService : ApplicationService,
+ IReadOnlyAppService
+ where TEntity : class, IEntity
+ {
+ ///
+ /// 先暂时用服务定位的方式,之后将更改为属性注入
+ ///
+ protected IRepository _repository { get => App.GetRequiredService>(); }
+
+ protected ISugarQueryable _DbQueryable => _repository._DbQueryable;
+
+ //Mapper
+ protected virtual Task MapToGetOutputDtoAsync(TEntity entity)
+ {
+ return Task.FromResult(_mapper.Map(entity));
+ }
+ protected virtual Task> MapToGetListOutputDtosAsync(List entities)
+ {
+ var dtos = _mapper.Map>(entities);
+
+ return Task.FromResult(dtos);
+ }
+ protected virtual Task MapToGetListOutputDtoAsync(TEntity entity)
+ {
+ var dto = _mapper.Map(entity);
+ return Task.FromResult(dto);
+ }
+
+ ///
+ /// 单查
+ ///
+ ///
+ ///
+ ///
+ public virtual async Task GetAsync(TKey id)
+ {
+ if (id is null)
+ {
+ throw new ArgumentNullException(nameof(id));
+ }
+
+ var entity = await _repository.GetByIdAsync(id);
+
+ return await MapToGetOutputDtoAsync(entity);
+ }
+
+ ///
+ /// 多查
+ ///
+ ///
+ ///
+ public virtual async Task> GetListAsync(TGetListInput input)
+ {
+ var totalCount = -1;
+
+ var entities = new List();
+ var entityDtos = new List();
+
+ bool isPageList = true;
+
+ //if (totalCount > 0)
+ //{
+
+ //这里还可以追加如果是审计日志,继续拼接条件即可
+ if (input is IPageTimeResultRequestDto timeInput)
+ {
+ if (timeInput.StartTime is not null)
+ {
+ timeInput.EndTime = timeInput.EndTime ?? DateTime.Now;
+ }
+ }
+
+
+
+
+ if (input is IPagedAndSortedResultRequestDto sortInput)
+ {
+ entities = await _repository.GetPageListAsync(_ => true, sortInput, sortInput.SortBy, sortInput.SortType);
+ }
+
+
+ else
+ {
+ isPageList = false;
+ entities = await _repository.GetListAsync();
+ }
+ entityDtos = await MapToGetListOutputDtosAsync(entities);
+ //}
+
+ //如果是分页查询,还需要统计数量
+ if (isPageList)
+ {
+ totalCount = await _repository.CountAsync(_ => true);
+ }
+ return new PagedResultDto(
+ totalCount,
+ entityDtos
+ );
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/FileTypeEnum.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/FileTypeEnum.cs
new file mode 100644
index 00000000..1885e14a
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/FileTypeEnum.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Enums
+{
+ ///
+ /// 定义公共文件路径
+ ///
+ public enum FileTypeEnum
+ {
+ File,
+ Image,
+ Thumbnail,
+ Excel,
+ Temp
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/OrderByEnum.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/OrderByEnum.cs
new file mode 100644
index 00000000..5856cf3b
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/OrderByEnum.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Enums
+{
+ public enum OrderByEnum
+ {
+ Asc,
+ Desc
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/QueryOperatorEnum.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/QueryOperatorEnum.cs
new file mode 100644
index 00000000..7f959c2f
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/QueryOperatorEnum.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Enums
+{
+ public enum QueryOperatorEnum
+ {
+ ///
+ /// 相等
+ ///
+ Equal,
+ ///
+ /// 匹配
+ ///
+ Like,
+ ///
+ /// 大于
+ ///
+ GreaterThan,
+ ///
+ /// 大于或等于
+ ///
+ GreaterThanOrEqual,
+ ///
+ /// 小于
+ ///
+ LessThan,
+ ///
+ /// 小于或等于
+ ///
+ LessThanOrEqual,
+ ///
+ /// 等于集合
+ ///
+ In,
+ ///
+ /// 不等于集合
+ ///
+ NotIn,
+ ///
+ /// 左边匹配
+ ///
+ LikeLeft,
+ ///
+ /// 右边匹配
+ ///
+ LikeRight,
+ ///
+ /// 不相等
+ ///
+ NoEqual,
+ ///
+ /// 为空或空
+ ///
+ IsNullOrEmpty,
+ ///
+ /// 不为空
+ ///
+ IsNot,
+ ///
+ /// 不匹配
+ ///
+ NoLike,
+ ///
+ /// 时间段 值用 "|" 隔开
+ ///
+ DateRange
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/ResultCodeEnum.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/ResultCodeEnum.cs
new file mode 100644
index 00000000..76a76221
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Enums/ResultCodeEnum.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Enums
+{
+ public enum ResultCodeEnum
+ {
+ ///
+ /// 操作成功。
+ ///
+ Success = 200,
+
+ ///
+ /// 操作不成功
+ ///
+ NotSuccess = 500,
+
+ ///
+ /// 无权限
+ ///
+ NoPermission = 401,
+
+ ///
+ /// 被拒绝
+ ///
+ Denied = 403
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/AuthException.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/AuthException.cs
new file mode 100644
index 00000000..b4959d8a
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/AuthException.cs
@@ -0,0 +1,48 @@
+using System.Runtime.Serialization;
+using Microsoft.Extensions.Logging;
+using Yi.Framework.Infrastructure.Enums;
+
+namespace Yi.Framework.Infrastructure.Exceptions
+{
+ public class AuthException : Exception,
+ IHasErrorCode,
+ IHasErrorDetails,
+ IHasLogLevel
+ {
+ public int Code { get; set; }
+
+ public string? Details { get; set; }
+
+ public LogLevel LogLevel { get; set; }
+
+ public AuthException(
+
+ string? message = null,
+ ResultCodeEnum code = ResultCodeEnum.NoPermission,
+ string? details = null,
+ Exception? innerException = null,
+ LogLevel logLevel = LogLevel.Warning)
+ : base(message, innerException)
+ {
+ Code = (int)code;
+ Details = details;
+ LogLevel = logLevel;
+ }
+
+ ///
+ /// 序列化参数的构造函数
+ ///
+ public AuthException(SerializationInfo serializationInfo, StreamingContext context)
+ : base(serializationInfo, context)
+ {
+
+ }
+
+ public AuthException WithData(string name, object value)
+ {
+ Data[name] = value;
+ return this;
+ }
+
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/BusinessException.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/BusinessException.cs
new file mode 100644
index 00000000..2bcc847a
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/BusinessException.cs
@@ -0,0 +1,47 @@
+using System.Runtime.Serialization;
+using Microsoft.Extensions.Logging;
+using Yi.Framework.Infrastructure.Enums;
+
+namespace Yi.Framework.Infrastructure.Exceptions
+{
+ public class BusinessException : Exception,
+ IHasErrorCode,
+ IHasErrorDetails,
+ IHasLogLevel
+ {
+ public int Code { get; set; }
+
+ public string? Details { get; set; }
+
+ public LogLevel LogLevel { get; set; }
+
+ public BusinessException(
+ int code = (int)ResultCodeEnum.Denied,
+ string? message = null,
+ string? details = null,
+ Exception? innerException = null,
+ LogLevel logLevel = LogLevel.Warning)
+ : base(message, innerException)
+ {
+ Code = code;
+ Details = details;
+ LogLevel = logLevel;
+ }
+
+ ///
+ /// 序列化参数的构造函数
+ ///
+ public BusinessException(SerializationInfo serializationInfo, StreamingContext context)
+ : base(serializationInfo, context)
+ {
+
+ }
+
+ public BusinessException WithData(string name, object value)
+ {
+ Data[name] = value;
+ return this;
+ }
+
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/ExceptionExtensions.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/ExceptionExtensions.cs
new file mode 100644
index 00000000..128bb707
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/ExceptionExtensions.cs
@@ -0,0 +1,41 @@
+using System.Runtime.ExceptionServices;
+using Microsoft.Extensions.Logging;
+using Yi.Framework.Infrastructure.Enums;
+
+namespace Yi.Framework.Infrastructure.Exceptions;
+
+///
+/// չ
+///
+public static class ExceptionExtensions
+{
+ ///
+ /// ʹ ٴ׳쳣
+ ///
+ /// Exception to be re-thrown
+ public static void ReThrow(this Exception exception)
+ {
+ ExceptionDispatchInfo.Capture(exception).Throw();
+ }
+
+ ///
+ /// ȡ쳣е־ȼ
+ ///
+ ///
+ ///
+ ///
+ public static LogLevel GetLogLevel(this Exception exception, LogLevel defaultLevel = LogLevel.Error)
+ {
+ return (exception as IHasLogLevel)?.LogLevel ?? defaultLevel;
+ }
+ ///
+ /// ȡ쳣е־
+ ///
+ ///
+ ///
+ ///
+ public static int GetLogErrorCode(this Exception exception, ResultCodeEnum defaultCode = ResultCodeEnum.NotSuccess)
+ {
+ return (exception as IHasErrorCode)?.Code ?? (int)defaultCode;
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/IHasErrorCode.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/IHasErrorCode.cs
new file mode 100644
index 00000000..1484820b
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/IHasErrorCode.cs
@@ -0,0 +1,7 @@
+namespace Yi.Framework.Infrastructure.Exceptions
+{
+ internal interface IHasErrorCode
+ {
+ int Code { get; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/IHasErrorDetails.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/IHasErrorDetails.cs
new file mode 100644
index 00000000..9600afe3
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/IHasErrorDetails.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Exceptions
+{
+ public interface IHasErrorDetails
+ {
+ string? Details { get; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/IHasLogLevel.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/IHasLogLevel.cs
new file mode 100644
index 00000000..f4b02986
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/IHasLogLevel.cs
@@ -0,0 +1,14 @@
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Exceptions
+{
+ public interface IHasLogLevel
+ {
+ LogLevel LogLevel { get; set; }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/UserFriendlyException.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/UserFriendlyException.cs
new file mode 100644
index 00000000..acb22783
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Exceptions/UserFriendlyException.cs
@@ -0,0 +1,34 @@
+using System.Runtime.Serialization;
+using Microsoft.Extensions.Logging;
+using Yi.Framework.Infrastructure.Enums;
+
+namespace Yi.Framework.Infrastructure.Exceptions
+{
+ public class UserFriendlyException : BusinessException
+ {
+ public UserFriendlyException(
+string message,
+int code = (int)ResultCodeEnum.Denied,
+string? details = null,
+Exception? innerException = null,
+LogLevel logLevel = LogLevel.Warning)
+: base(
+ code,
+ message,
+ details,
+ innerException,
+ logLevel)
+ {
+ Details = details;
+ }
+
+ ///
+ /// 序列化参数的构造函数
+ ///
+ public UserFriendlyException(SerializationInfo serializationInfo, StreamingContext context)
+ : base(serializationInfo, context)
+ {
+
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/AssemblyHelper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/AssemblyHelper.cs
new file mode 100644
index 00000000..a88f371e
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/AssemblyHelper.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public static class AssemblyHelper
+ {
+
+ ///
+ /// 此处统一获取程序集,排除微软内部相关
+ ///
+ ///
+ public static Assembly[] GetAllLoadAssembly()
+ {
+ return AppDomain.CurrentDomain.GetAssemblies();
+ }
+
+ public static List GetReferanceAssemblies(this AppDomain domain)
+ {
+ var list = new List();
+ domain.GetAssemblies().ToList().ForEach(i =>
+ {
+ GetReferanceAssemblies(i, list);
+ });
+ return list;
+ }
+ private static void GetReferanceAssemblies(Assembly assembly, List list)
+ {
+ assembly.GetReferencedAssemblies().ToList().ForEach(i =>
+ {
+ var ass = Assembly.Load(i);
+ if (!list.Contains(ass))
+ {
+ list.Add(ass);
+ GetReferanceAssemblies(ass, list);
+ }
+ });
+ }
+
+ public static List GetClass(string assemblyFile, string? className = null, string? spaceName = null)
+ {
+ Assembly assembly = Assembly.Load(assemblyFile);
+ return assembly.GetTypes().Where(m => m.IsClass
+ && className == null ? true : m.Name == className
+ && spaceName == null ? true : m.Namespace == spaceName
+ && !m.Name.StartsWith("<>")
+ ).ToList();
+ }
+
+ public static List GetClassByParentClass(string assemblyFile, Type type)
+ {
+ Assembly assembly = Assembly.Load(assemblyFile);
+
+ List resList = new List();
+
+ List typeList = assembly.GetTypes().Where(m => m.IsClass).ToList();
+ foreach (var t in typeList)
+ {
+ var data = t.BaseType;
+ if (data == type)
+ {
+ resList.Add(t);
+ }
+
+ }
+ return resList;
+ }
+
+
+ public static List GetClassByInterfaces(string assemblyFile, Type type)
+ {
+ Assembly assembly = Assembly.Load(assemblyFile);
+
+ List resList = new List();
+
+ List typeList = assembly.GetTypes().Where(m => m.IsClass).ToList();
+ foreach (var t in typeList)
+ {
+ var data = t.GetInterfaces();
+ if (data.Contains(type))
+ {
+ resList.Add(t);
+ }
+
+ }
+ return resList;
+ }
+
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/Base32Helper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/Base32Helper.cs
new file mode 100644
index 00000000..b503bd3d
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/Base32Helper.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Text;
+
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public sealed class Base32Helper
+ {
+
+ // the valid chars for the encoding
+ private static string ValidChars = "QAZ2WSX3" + "EDC4RFV5" + "TGB6YHN7" + "UJM8K9LP";
+
+ ///
+ /// Converts an array of bytes to a Base32-k string.
+ ///
+ public static string ToString(byte[] bytes)
+ {
+ StringBuilder sb = new StringBuilder(); // holds the base32 chars
+ byte index;
+ int hi = 5;
+ int currentByte = 0;
+
+ while (currentByte < bytes.Length)
+ {
+ // do we need to use the next byte?
+ if (hi > 8)
+ {
+ // get the last piece from the current byte, shift it to the right
+ // and increment the byte counter
+ index = (byte)(bytes[currentByte++] >> hi - 5);
+ if (currentByte != bytes.Length)
+ {
+ // if we are not at the end, get the first piece from
+ // the next byte, clear it and shift it to the left
+ index = (byte)((byte)(bytes[currentByte] << 16 - hi) >> 3 | index);
+ }
+
+ hi -= 3;
+ }
+ else if (hi == 8)
+ {
+ index = (byte)(bytes[currentByte++] >> 3);
+ hi -= 3;
+ }
+ else
+ {
+
+ // simply get the stuff from the current byte
+ index = (byte)((byte)(bytes[currentByte] << 8 - hi) >> 3);
+ hi += 5;
+ }
+
+ sb.Append(ValidChars[index]);
+ }
+
+ return sb.ToString();
+ }
+
+
+ ///
+ /// Converts a Base32-k string into an array of bytes.
+ ///
+ ///
+ /// Input string s contains invalid Base32-k characters.
+ ///
+ public static byte[] FromBase32String(string str)
+ {
+ int numBytes = str.Length * 5 / 8;
+ byte[] bytes = new byte[numBytes];
+
+ // all UPPERCASE chars
+ str = str.ToUpper();
+
+ int bit_buffer;
+ int currentCharIndex;
+ int bits_in_buffer;
+
+ if (str.Length < 3)
+ {
+ bytes[0] = (byte)(ValidChars.IndexOf(str[0]) | ValidChars.IndexOf(str[1]) << 5);
+ return bytes;
+ }
+
+ bit_buffer = ValidChars.IndexOf(str[0]) | ValidChars.IndexOf(str[1]) << 5;
+ bits_in_buffer = 10;
+ currentCharIndex = 2;
+ for (int i = 0; i < bytes.Length; i++)
+ {
+ bytes[i] = (byte)bit_buffer;
+ bit_buffer >>= 8;
+ bits_in_buffer -= 8;
+ while (bits_in_buffer < 8 && currentCharIndex < str.Length)
+ {
+ bit_buffer |= ValidChars.IndexOf(str[currentCharIndex++]) << bits_in_buffer;
+ bits_in_buffer += 5;
+ }
+ }
+
+ return bytes;
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/ConsoleHelper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/ConsoleHelper.cs
new file mode 100644
index 00000000..66c2252c
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/ConsoleHelper.cs
@@ -0,0 +1,54 @@
+using System;
+
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public static class ConsoleHelper
+ {
+ public static void WriteColorLine(string str, ConsoleColor color)
+ {
+ ConsoleColor currentForeColor = Console.ForegroundColor;
+ Console.ForegroundColor = color;
+ Console.WriteLine(str);
+ Console.ForegroundColor = currentForeColor;
+ }
+
+ ///
+ /// 打印错误信息
+ ///
+ /// 待打印的字符串
+ /// 想要打印的颜色
+ public static void WriteErrorLine(this string str, ConsoleColor color = ConsoleColor.Red)
+ {
+ WriteColorLine(str, color);
+ }
+
+ ///
+ /// 打印警告信息
+ ///
+ /// 待打印的字符串
+ /// 想要打印的颜色
+ public static void WriteWarningLine(this string str, ConsoleColor color = ConsoleColor.Yellow)
+ {
+ WriteColorLine(str, color);
+ }
+ ///
+ /// 打印正常信息
+ ///
+ /// 待打印的字符串
+ /// 想要打印的颜色
+ public static void WriteInfoLine(this string str, ConsoleColor color = ConsoleColor.White)
+ {
+ WriteColorLine(str, color);
+ }
+ ///
+ /// 打印成功的信息
+ ///
+ /// 待打印的字符串
+ /// 想要打印的颜色
+ public static void WriteSuccessLine(this string str, ConsoleColor color = ConsoleColor.Green)
+ {
+ WriteColorLine(str, color);
+ }
+
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/DateHelper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/DateHelper.cs
new file mode 100644
index 00000000..44495f82
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/DateHelper.cs
@@ -0,0 +1,58 @@
+using System;
+
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public class DateHelper
+ {
+ public static DateTime StampToDateTime(string time)
+ {
+ time = time.Substring(0, 10);
+ double timestamp = Convert.ToInt64(time);
+ DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
+ dateTime = dateTime.AddSeconds(timestamp).ToLocalTime();
+ return dateTime;
+ }
+
+ public static string TimeSubTract(DateTime time1, DateTime time2)
+ {
+ TimeSpan subTract = time1.Subtract(time2);
+ return $"{subTract.Days} 天 {subTract.Hours} 时 {subTract.Minutes} 分 ";
+ }
+ ///
+ /// 时间戳转本地时间-时间戳精确到秒
+ ///
+ public static DateTime ToLocalTimeDateBySeconds(long unix)
+ {
+ var dto = DateTimeOffset.FromUnixTimeSeconds(unix);
+ return dto.ToLocalTime().DateTime;
+ }
+
+ ///
+ /// 时间转时间戳Unix-时间戳精确到秒
+ ///
+ public static long ToUnixTimestampBySeconds(DateTime dt)
+ {
+ DateTimeOffset dto = new DateTimeOffset(dt);
+ return dto.ToUnixTimeSeconds();
+ }
+
+
+ ///
+ /// 时间戳转本地时间-时间戳精确到毫秒
+ ///
+ public static DateTime ToLocalTimeDateByMilliseconds(long unix)
+ {
+ var dto = DateTimeOffset.FromUnixTimeMilliseconds(unix);
+ return dto.ToLocalTime().DateTime;
+ }
+
+ ///
+ /// 时间转时间戳Unix-时间戳精确到毫秒
+ ///
+ public static long ToUnixTimestampByMilliseconds(DateTime dt)
+ {
+ DateTimeOffset dto = new DateTimeOffset(dt);
+ return dto.ToUnixTimeMilliseconds();
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/DistinctHelper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/DistinctHelper.cs
new file mode 100644
index 00000000..32444dda
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/DistinctHelper.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public class Compare : IEqualityComparer
+ {
+ private Func _getField;
+ public Compare(Func getfield)
+ {
+ _getField = getfield;
+ }
+ public bool Equals(T? x, T? y)
+ {
+ return EqualityComparer.Default.Equals(_getField(x!), _getField(y!));
+ }
+
+ public int GetHashCode(T obj)
+ {
+ return EqualityComparer.Default.GetHashCode(_getField(obj)!);
+ }
+ }
+ public static class DistinctHelper
+ {
+ ///
+ /// 自定义Distinct扩展方法
+ ///
+ /// 要去重的对象类
+ /// 自定义去重的字段类型
+ /// 要去重的对象
+ /// 获取自定义去重字段的委托
+ ///
+ public static IEnumerable DistinctNew(this IEnumerable source, Func getfield)
+ {
+ return source.Distinct(new Compare(getfield));
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/EnumHelper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/EnumHelper.cs
new file mode 100644
index 00000000..af984a8f
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/EnumHelper.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public static class EnumHelper
+ {
+ public static New EnumToEnum(this object oldEnum)
+ {
+ if (oldEnum is null)
+ {
+ throw new ArgumentNullException(nameof(oldEnum));
+ }
+ return (New)Enum.ToObject(typeof(New), oldEnum.GetHashCode());
+ }
+
+ public static TEnum StringToEnum(this string str)
+ {
+ return (TEnum)Enum.Parse(typeof(TEnum), str);
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/ExpressionHelper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/ExpressionHelper.cs
new file mode 100644
index 00000000..734e6e62
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/ExpressionHelper.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public static class ExpressionHelper
+ {
+
+
+ ///
+ /// Expression表达式树lambda参数拼接组合
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Expression Compose(this Expression first, Expression second, Func merge)
+ {
+ var parameterMap = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
+ var secondBody = LambdaParameteRebinder.ReplaceParameter(parameterMap, second.Body);
+ return Expression.Lambda(merge(first.Body, secondBody), first.Parameters);
+ }
+
+ ///
+ /// Expression表达式树lambda参数拼接--false
+ ///
+ ///
+ ///
+ public static Expression> False() => f => false;
+
+ ///
+ /// Expression表达式树lambda参数拼接-true
+ ///
+ ///
+ ///
+ public static Expression> True() => f => true;
+
+ ///
+ /// Expression表达式树lambda参数拼接--and
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Expression> And(this Expression> first, Expression> second) => first.Compose(second, Expression.And);
+
+ ///
+ /// Expression表达式树lambda参数拼接--or
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Expression> Or(this Expression> first, Expression> second) => first.Compose(second, Expression.Or);
+ }
+
+ public class LambdaParameteRebinder : ExpressionVisitor
+ {
+ ///
+ /// 存放表达式树的参数的字典
+ ///
+ private readonly Dictionary map;
+
+ ///
+ /// 构造函数
+ ///
+ ///
+ public LambdaParameteRebinder(Dictionary map)
+ {
+ this.map = map ?? new Dictionary();
+ }
+
+ ///
+ /// 重载参数访问的方法,访问表达式树参数,如果字典中包含,则取出
+ ///
+ /// 表达式树参数
+ ///
+ protected override Expression VisitParameter(ParameterExpression node)
+ {
+ if (map.TryGetValue(node, out ParameterExpression expression))
+ {
+ node = expression;
+ }
+ return base.VisitParameter(node);
+ }
+
+ public static Expression ReplaceParameter(Dictionary map, Expression exp)
+ {
+ return new LambdaParameteRebinder(map).Visit(exp);
+ }
+ }
+
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/FileHelper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/FileHelper.cs
new file mode 100644
index 00000000..80c331ed
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/FileHelper.cs
@@ -0,0 +1,490 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public class FileHelper : IDisposable
+ {
+
+ private bool _alreadyDispose = false;
+
+
+
+ #region 构造函数
+ public FileHelper()
+ {
+ //
+ // TODO: 在此处添加构造函数逻辑
+ //
+ }
+ ~FileHelper()
+ {
+ Dispose(); ;
+ }
+
+ protected virtual void Dispose(bool isDisposing)
+ {
+ if (_alreadyDispose) return;
+ _alreadyDispose = true;
+ }
+ #endregion
+
+ #region IDisposable 成员
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ #endregion
+
+ #region 取得文件后缀名
+ /****************************************
+ * 函数名称:GetPostfixStr
+ * 功能说明:取得文件后缀名
+ * 参 数:filename:文件名称
+ * 调用示列:
+ * string filename = "aaa.aspx";
+ * string s = EC.FileObj.GetPostfixStr(filename);
+ *****************************************/
+ ///
+ /// 取后缀名
+ ///
+ /// 文件名
+ /// .gif|.html格式
+ public static string GetPostfixStr(string filename)
+ {
+ int start = filename.LastIndexOf(".");
+ int length = filename.Length;
+ string postfix = filename.Substring(start, length - start);
+ return postfix;
+ }
+ #endregion
+
+ #region 根据文件大小获取指定前缀的可用文件名
+ ///
+ /// 根据文件大小获取指定前缀的可用文件名
+ ///
+ /// 文件夹
+ /// 文件前缀
+ /// 文件大小(1m)
+ /// 文件后缀(.log)
+ /// 可用文件名
+ //public static string GetAvailableFileWithPrefixOrderSize(string folderPath, string prefix, int size = 1 * 1024 * 1024, string ext = ".log")
+ //{
+ // var allFiles = new DirectoryInfo(folderPath);
+ // var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(prefix.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d=>d.Name).ToList();
+
+ // if (selectFiles.Count > 0)
+ // {
+ // return selectFiles.FirstOrDefault().FullName;
+ // }
+
+ // return Path.Combine(folderPath, $@"{prefix}_{DateTime.Now.DateToTimeStamp()}.log");
+ //}
+ //public static string GetAvailableFileNameWithPrefixOrderSize(string _contentRoot, string prefix, int size = 1 * 1024 * 1024, string ext = ".log")
+ //{
+ // var folderPath = Path.Combine(_contentRoot, "Log");
+ // if (!Directory.Exists(folderPath))
+ // {
+ // Directory.CreateDirectory(folderPath);
+ // }
+
+ // var allFiles = new DirectoryInfo(folderPath);
+ // var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(prefix.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d => d.Name).ToList();
+
+ // if (selectFiles.Count > 0)
+ // {
+ // return selectFiles.FirstOrDefault().Name.Replace(".log","");
+ // }
+
+ // return $@"{prefix}_{DateTime.Now.DateToTimeStamp()}";
+ //}
+ #endregion
+
+ #region 写文件
+ /****************************************
+ * 函数名称:WriteFile
+ * 功能说明:写文件,会覆盖掉以前的内容
+ * 参 数:Path:文件路径,Strings:文本内容
+ * 调用示列:
+ * string Path = Server.MapPath("Default2.aspx");
+ * string Strings = "这是我写的内容啊";
+ * EC.FileObj.WriteFile(Path,Strings);
+ *****************************************/
+ ///
+ /// 写文件
+ ///
+ /// 文件路径
+ /// 文件内容
+ public static void WriteFile(string Path, string Strings)
+ {
+ if (!File.Exists(Path))
+ {
+ FileStream f = File.Create(Path);
+ f.Close();
+ }
+ StreamWriter f2 = new StreamWriter(Path, false, Encoding.GetEncoding("gb2312"));
+ f2.Write(Strings);
+ f2.Close();
+ f2.Dispose();
+ }
+
+ ///
+ /// 写文件
+ ///
+ /// 文件路径
+ /// 文件内容
+ /// 编码格式
+ public static void WriteFile(string Path, string Strings, Encoding encode)
+ {
+ if (!File.Exists(Path))
+ {
+ FileStream f = File.Create(Path);
+ f.Close();
+ }
+ StreamWriter f2 = new StreamWriter(Path, false, encode);
+ f2.Write(Strings);
+ f2.Close();
+ f2.Dispose();
+ }
+ #endregion
+
+ #region 读文件
+ /****************************************
+ * 函数名称:ReadFile
+ * 功能说明:读取文本内容
+ * 参 数:Path:文件路径
+ * 调用示列:
+ * string Path = Server.MapPath("Default2.aspx");
+ * string s = EC.FileObj.ReadFile(Path);
+ *****************************************/
+ ///
+ /// 读文件
+ ///
+ /// 文件路径
+ ///
+ public static string ReadFile(string Path)
+ {
+ string s = "";
+ if (!File.Exists(Path))
+ s = "不存在相应的目录";
+ else
+ {
+ StreamReader f2 = new StreamReader(Path, Encoding.GetEncoding("gb2312"));
+ s = f2.ReadToEnd();
+ f2.Close();
+ f2.Dispose();
+ }
+
+ return s;
+ }
+
+ ///
+ /// 读文件
+ ///
+ /// 文件路径
+ /// 编码格式
+ ///
+ public static string ReadFile(string Path, Encoding encode)
+ {
+ string s = "";
+ if (!File.Exists(Path))
+ s = "不存在相应的目录";
+ else
+ {
+ StreamReader f2 = new StreamReader(Path, encode);
+ s = f2.ReadToEnd();
+ f2.Close();
+ f2.Dispose();
+ }
+
+ return s;
+ }
+ #endregion
+
+ #region 追加文件
+ /****************************************
+ * 函数名称:FileAdd
+ * 功能说明:追加文件内容
+ * 参 数:Path:文件路径,strings:内容
+ * 调用示列:
+ * string Path = Server.MapPath("Default2.aspx");
+ * string Strings = "新追加内容";
+ * EC.FileObj.FileAdd(Path, Strings);
+ *****************************************/
+ ///
+ /// 追加文件
+ ///
+ /// 文件路径
+ /// 内容
+ public static void FileAdd(string Path, string strings)
+ {
+ StreamWriter sw = File.AppendText(Path);
+ sw.Write(strings);
+ sw.Flush();
+ sw.Close();
+ }
+ #endregion
+
+ #region 拷贝文件
+ /****************************************
+ * 函数名称:FileCoppy
+ * 功能说明:拷贝文件
+ * 参 数:OrignFile:原始文件,NewFile:新文件路径
+ * 调用示列:
+ * string orignFile = Server.MapPath("Default2.aspx");
+ * string NewFile = Server.MapPath("Default3.aspx");
+ * EC.FileObj.FileCoppy(OrignFile, NewFile);
+ *****************************************/
+ ///
+ /// 拷贝文件
+ ///
+ /// 原始文件
+ /// 新文件路径
+ public static void FileCoppy(string orignFile, string NewFile)
+ {
+ File.Copy(orignFile, NewFile, true);
+ }
+
+ #endregion
+
+ #region 删除文件
+ /****************************************
+ * 函数名称:FileDel
+ * 功能说明:删除文件
+ * 参 数:Path:文件路径
+ * 调用示列:
+ * string Path = Server.MapPath("Default3.aspx");
+ * EC.FileObj.FileDel(Path);
+ *****************************************/
+ ///
+ /// 删除文件
+ ///
+ /// 路径
+ public static void FileDel(string Path)
+ {
+ File.Delete(Path);
+ }
+ #endregion
+
+ #region 移动文件
+ /****************************************
+ * 函数名称:FileMove
+ * 功能说明:移动文件
+ * 参 数:OrignFile:原始路径,NewFile:新文件路径
+ * 调用示列:
+ * string orignFile = Server.MapPath("../说明.txt");
+ * string NewFile = Server.MapPath("http://www.cnblogs.com/说明.txt");
+ * EC.FileObj.FileMove(OrignFile, NewFile);
+ *****************************************/
+ ///
+ /// 移动文件
+ ///
+ /// 原始路径
+ /// 新路径
+ public static void FileMove(string orignFile, string NewFile)
+ {
+ File.Move(orignFile, NewFile);
+ }
+ #endregion
+
+ #region 在当前目录下创建目录
+ /****************************************
+ * 函数名称:FolderCreate
+ * 功能说明:在当前目录下创建目录
+ * 参 数:OrignFolder:当前目录,NewFloder:新目录
+ * 调用示列:
+ * string orignFolder = Server.MapPath("test/");
+ * string NewFloder = "new";
+ * EC.FileObj.FolderCreate(OrignFolder, NewFloder);
+ *****************************************/
+ ///
+ /// 在当前目录下创建目录
+ ///
+ /// 当前目录
+ /// 新目录
+ public static void FolderCreate(string orignFolder, string NewFloder)
+ {
+ Directory.SetCurrentDirectory(orignFolder);
+ Directory.CreateDirectory(NewFloder);
+ }
+ #endregion
+
+ #region 递归删除文件夹目录及文件
+ /****************************************
+ * 函数名称:DeleteFolder
+ * 功能说明:递归删除文件夹目录及文件
+ * 参 数:dir:文件夹路径
+ * 调用示列:
+ * string dir = Server.MapPath("test/");
+ * EC.FileObj.DeleteFolder(dir);
+ *****************************************/
+ ///
+ /// 递归删除文件夹目录及文件
+ ///
+ ///
+ ///
+ public static void DeleteFolder(string dir)
+ {
+ if (Directory.Exists(dir)) //如果存在这个文件夹删除之
+ {
+ foreach (string d in Directory.GetFileSystemEntries(dir))
+ {
+ if (File.Exists(d))
+ File.Delete(d); //直接删除其中的文件
+ else
+ DeleteFolder(d); //递归删除子文件夹
+ }
+ Directory.Delete(dir); //删除已空文件夹
+ }
+
+ }
+ #endregion
+
+ #region 将指定文件夹下面的所有内容copy到目标文件夹下面 果目标文件夹为只读属性就会报错。
+ /****************************************
+ * 函数名称:CopyDir
+ * 功能说明:将指定文件夹下面的所有内容copy到目标文件夹下面 果目标文件夹为只读属性就会报错。
+ * 参 数:srcPath:原始路径,aimPath:目标文件夹
+ * 调用示列:
+ * string srcPath = Server.MapPath("test/");
+ * string aimPath = Server.MapPath("test1/");
+ * EC.FileObj.CopyDir(srcPath,aimPath);
+ *****************************************/
+ ///
+ /// 指定文件夹下面的所有内容copy到目标文件夹下面
+ ///
+ /// 原始路径
+ /// 目标文件夹
+ public static void CopyDir(string srcPath, string aimPath)
+ {
+ try
+ {
+ // 检查目标目录是否以目录分割字符结束如果不是则添加之
+ if (aimPath[aimPath.Length - 1] != Path.DirectorySeparatorChar)
+ aimPath += Path.DirectorySeparatorChar;
+ // 判断目标目录是否存在如果不存在则新建之
+ if (!Directory.Exists(aimPath))
+ Directory.CreateDirectory(aimPath);
+ // 得到源目录的文件列表,该里面是包含文件以及目录路径的一个数组
+ //如果你指向copy目标文件下面的文件而不包含目录请使用下面的方法
+ //string[] fileList = Directory.GetFiles(srcPath);
+ string[] fileList = Directory.GetFileSystemEntries(srcPath);
+ //遍历所有的文件和目录
+ foreach (string file in fileList)
+ {
+ //先当作目录处理如果存在这个目录就递归Copy该目录下面的文件
+
+ if (Directory.Exists(file))
+ CopyDir(file, aimPath + Path.GetFileName(file));
+ //否则直接Copy文件
+ else
+ File.Copy(file, aimPath + Path.GetFileName(file), true);
+ }
+
+ }
+ catch (Exception ee)
+ {
+ throw new Exception(ee.ToString());
+ }
+ }
+ #endregion
+
+ ///
+ /// 获取目录下全部文件名
+ ///
+ ///
+ ///
+ ///
+ public static List GetAllFileNames(string path, string pattern = "*")
+ {
+ List folder = new DirectoryInfo(path).GetFiles(pattern).ToList();
+
+ return folder.Select(x => x.Name).ToList();
+ }
+ ///
+ /// 文件内容替换
+ ///
+ public static string FileContentReplace(string path, string oldStr, string newStr)
+ {
+ var content = File.ReadAllText(path);
+
+ if (content.Contains(oldStr))
+ {
+ File.Delete(path);
+ File.WriteAllText(path, content.Replace(oldStr, newStr));
+ }
+
+ return path;
+ }
+ ///
+ /// 文件名称
+ ///
+ public static string FileNameReplace(string path, string oldStr, string newStr)
+ {
+ string fileName = Path.GetFileName(path);
+ if (!fileName.Contains(oldStr))
+ {
+ return path;
+ }
+
+ string? directoryName = Path.GetDirectoryName(path);
+ string newFileName = fileName.Replace(oldStr, newStr);
+ string newPath = Path.Combine(directoryName ?? "", newFileName);
+ File.Move(path, newPath);
+
+ return newPath;
+ }
+ ///
+ /// 目录名替换
+ ///
+ public static string DirectoryNameReplace(string path, string oldStr, string newStr)
+ {
+ string fileName = Path.GetFileName(path);
+ if (!fileName.Contains(oldStr))
+ {
+ return path;
+ }
+
+ string? directoryName = Path.GetDirectoryName(path);
+ string newFileName = fileName.Replace(oldStr, newStr);
+ string newPath = Path.Combine(directoryName ?? "", newFileName);
+ Directory.Move(path, newPath);
+ return newPath;
+ }
+
+ ///
+ /// 全部信息递归替换
+ ///
+ ///
+ ///
+ ///
+ public static void AllInfoReplace(string dirPath, string oldStr, string newStr)
+ {
+ var path = DirectoryNameReplace(dirPath, oldStr, newStr);
+ var dirInfo = new DirectoryInfo(path);
+ var files = dirInfo.GetFiles();
+ var dirs = dirInfo.GetDirectories();
+ if (files.Length > 0)
+ {
+ foreach (var f in files)
+ {
+ FileContentReplace(f.FullName, oldStr, newStr);
+ FileNameReplace(f.FullName, oldStr, newStr);
+ }
+ }
+ if (dirs.Length > 0)
+ {
+ foreach (var d in dirs)
+ {
+ AllInfoReplace(d.FullName, oldStr, newStr);
+ }
+ }
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/HtmlHelper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/HtmlHelper.cs
new file mode 100644
index 00000000..893253b9
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/HtmlHelper.cs
@@ -0,0 +1,24 @@
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public static class HtmlHelper
+ {
+ #region 去除富文本中的HTML标签
+ ///
+ /// 去除富文本中的HTML标签
+ ///
+ ///
+ ///
+ ///
+ public static string ReplaceHtmlTag(string html, int length = 0)
+ {
+ string strText = System.Text.RegularExpressions.Regex.Replace(html, "<[^>]+>", "");
+ strText = System.Text.RegularExpressions.Regex.Replace(strText, "&[^;]+;", "");
+
+ if (length > 0 && strText.Length > length)
+ return strText.Substring(0, length);
+
+ return strText;
+ }
+ #endregion
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/HttpHelper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/HttpHelper.cs
new file mode 100644
index 00000000..8abcc5b1
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/HttpHelper.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Mime;
+using System.Text;
+using System.Text.Json;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public static class HttpHelper
+ {
+
+ public static HttpClient Client { get; set; } = new HttpClient();
+
+ public static async Task Get(string url)
+ {
+ return await Client.GetStringAsync(url);
+ }
+
+ public static async Task GetIO(string url)
+ {
+ return await Client.GetStreamAsync(url);
+ }
+
+
+ public static async Task Post(string url, object? item = null, Dictionary? head = null)
+ {
+
+ using StringContent json = new(JsonSerializer.Serialize(item), Encoding.UTF8, MediaTypeNames.Application.Json);
+
+
+ if (head is not null)
+ {
+ foreach (var d in head)
+ {
+ json.Headers.Add(d.Key, d.Value);
+ }
+ }
+
+ var httpResponse = await Client.PostAsync(url, json);
+
+ httpResponse.EnsureSuccessStatusCode();
+
+ var content = httpResponse.Content;
+
+ return await content.ReadAsStringAsync();
+ }
+
+
+ // public static string HttpGet(string Url, string postDataStr="")
+ // {
+ //#pragma warning disable SYSLIB0014 // 类型或成员已过时
+ // HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
+ //#pragma warning restore SYSLIB0014 // 类型或成员已过时
+ // request.Method = "GET";
+ // request.ContentType = "text/html;charset=UTF-8";
+
+ // HttpWebResponse response = (HttpWebResponse)request.GetResponse();
+ // Stream myResponseStream = response.GetResponseStream();
+ // StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
+ // string retString = myStreamReader.ReadToEnd();
+ // myStreamReader.Close();
+ // myResponseStream.Close();
+
+ // return retString;
+ // }
+
+ // public static bool HttpIOGet(string Url, string file, string postDataStr="")
+ // {
+ // HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
+ // request.Method = "GET";
+ // request.ContentType = "text/html;charset=UTF-8";
+
+ // HttpWebResponse response = (HttpWebResponse)request.GetResponse();
+ // Stream myResponseStream = response.GetResponseStream();
+ // FileStream writer = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
+ // byte[] buffer = new byte[1024];
+ // int c;
+ // while ((c = myResponseStream.Read(buffer, 0, buffer.Length)) > 0)
+ // {
+ // writer.Write(buffer, 0, c);
+ // }
+ // writer.Close();
+ // myResponseStream.Close();
+
+ // return true;
+ // }
+
+ // public static string HttpPost(string Url, string postDataStr="")
+ // {
+ // CookieContainer cookie = new CookieContainer();
+ //#pragma warning disable SYSLIB0014 // 类型或成员已过时
+ // HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
+ //#pragma warning restore SYSLIB0014 // 类型或成员已过时
+ // request.Method = "POST";
+ // request.ContentType = "application/x-www-form-urlencoded";
+ // request.ContentLength = Encoding.UTF8.GetByteCount(postDataStr);
+ // request.CookieContainer = cookie;
+
+ // Stream myRequestStream = request.GetRequestStream();
+ // StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312"));
+ // myStreamWriter.Write(postDataStr);
+ // myStreamWriter.Close();
+
+ // HttpWebResponse response = (HttpWebResponse)request.GetResponse();
+
+ // response.Cookies = cookie.GetCookies(response.ResponseUri);
+ // Stream myResponseStream = response.GetResponseStream();
+ // StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
+ // string retString = myStreamReader.ReadToEnd();
+ // myStreamReader.Close();
+ // myResponseStream.Close();
+
+ // return retString;
+ // }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/IdHelper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/IdHelper.cs
new file mode 100644
index 00000000..ed4e7821
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/IdHelper.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public static class IdHelper
+ {
+ public static dynamic[] ToDynamicArray(this IEnumerable ids)
+ {
+ return ids.Select(id => (dynamic)id).ToArray();
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/IpHelper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/IpHelper.cs
new file mode 100644
index 00000000..888f9db1
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/IpHelper.cs
@@ -0,0 +1,56 @@
+using System.Linq;
+using System.Net;
+using System.Net.NetworkInformation;
+using System.Net.Sockets;
+
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public class IpHelper
+ {
+ ///
+ /// 获取当前IP地址
+ ///
+ ///
+ ///
+ public static string GetCurrentIp(string preferredNetworks)
+ {
+ var instanceIp = "127.0.0.1";
+
+ try
+ {
+ // 获取可用网卡
+ var nics = NetworkInterface.GetAllNetworkInterfaces()?.Where(network => network.OperationalStatus == OperationalStatus.Up);
+
+ // 获取所有可用网卡IP信息
+ var ipCollection = nics?.Select(x => x.GetIPProperties())?.SelectMany(x => x.UnicastAddresses);
+
+ if (ipCollection is null)
+ {
+ return instanceIp;
+ }
+
+ foreach (var ipadd in ipCollection)
+ {
+ if (!IPAddress.IsLoopback(ipadd.Address) && ipadd.Address.AddressFamily == AddressFamily.InterNetwork)
+ {
+ if (string.IsNullOrEmpty(preferredNetworks))
+ {
+ instanceIp = ipadd.Address.ToString();
+ break;
+ }
+
+ if (!ipadd.Address.ToString().StartsWith(preferredNetworks)) continue;
+ instanceIp = ipadd.Address.ToString();
+ break;
+ }
+ }
+ }
+ catch
+ {
+ // ignored
+ }
+
+ return instanceIp;
+ }
+ }
+}
diff --git a/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/JsonHelper.cs b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/JsonHelper.cs
new file mode 100644
index 00000000..2daf839f
--- /dev/null
+++ b/Yi.Furion.Rbac/Yi.Framework.Infrastructure/Helper/JsonHelper.cs
@@ -0,0 +1,518 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using System;
+using System.Collections.Generic;
+using System.Text.Json;
+
+namespace Yi.Framework.Infrastructure.Helper
+{
+ public class JsonHelper
+ {
+ public static string ObjToStr(T obj, string dateTimeFormat)
+ {
+ IsoDateTimeConverter timeConverter = new IsoDateTimeConverter()
+ {
+ DateTimeFormat = dateTimeFormat
+ };
+ return JsonConvert.SerializeObject(obj, Formatting.Indented, timeConverter);
+ }
+
+ public static string ObjToStr(T obj)
+ {
+ return JsonConvert.SerializeObject(obj);
+ }
+
+ public static T StrToObj(string str)
+ {
+ return JsonConvert.DeserializeObject(str)!;
+ }
+ ///
+ /// 转换对象为JSON格式数据
+ ///
+ /// 类
+ /// 对象
+ /// 字符格式的JSON数据
+ public static string GetJSON(object obj)
+ {
+ string result = string.Empty;
+ try
+ {
+ System.Text.Json.JsonSerializer.Serialize("");
+ System.Runtime.Serialization.Json.DataContractJsonSerializer serializer =
+ new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
+ using (MemoryStream ms = new MemoryStream())
+ {
+ serializer.WriteObject(ms, obj);
+ result = System.Text.Encoding.UTF8.GetString(ms.ToArray());
+ }
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ return result;
+ }
+ ///
+ /// 转换List的数据为JSON格式
+ ///
+ /// 类
+ /// 列表值
+ /// JSON格式数据
+ public string JSON(List vals)
+ {
+ System.Text.StringBuilder st = new System.Text.StringBuilder();
+ try
+ {
+ System.Runtime.Serialization.Json.DataContractJsonSerializer s = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
+
+ foreach (T city in vals)
+ {
+ using (MemoryStream ms = new MemoryStream())
+ {
+ s.WriteObject(ms, city);
+ st.Append(System.Text.Encoding.UTF8.GetString(ms.ToArray()));
+ }
+ }
+ }
+ catch (Exception)
+ {
+ }
+
+ return st.ToString();
+ }
+ ///
+ /// JSON格式字符转换为T类型的对象
+ ///
+ ///
+ ///
+ ///
+ public static T ParseFormByJson(string jsonStr)
+ {
+ T obj = Activator.CreateInstance();
+ using (MemoryStream ms =
+ new MemoryStream(System.Text.Encoding.UTF8.GetBytes(jsonStr)))
+ {
+ System.Runtime.Serialization.Json.DataContractJsonSerializer serializer =
+ new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
+ return (T)serializer.ReadObject(ms)!;
+ }
+ }
+
+ public string JSON1