diff --git a/Admin.NET/Admin.NET.Application/Admin.NET.Application.csproj b/Admin.NET/Admin.NET.Application/Admin.NET.Application.csproj
index 16a1ebcb..1b4523b7 100644
--- a/Admin.NET/Admin.NET.Application/Admin.NET.Application.csproj
+++ b/Admin.NET/Admin.NET.Application/Admin.NET.Application.csproj
@@ -48,11 +48,7 @@
-
-
-
-
diff --git a/Admin.NET/Admin.NET.Core/Service/Role/SysRoleTableService.cs b/Admin.NET/Admin.NET.Core/Service/Role/SysRoleTableService.cs
index c663e5fb..a49f9112 100644
--- a/Admin.NET/Admin.NET.Core/Service/Role/SysRoleTableService.cs
+++ b/Admin.NET/Admin.NET.Core/Service/Role/SysRoleTableService.cs
@@ -92,7 +92,7 @@ public class SysRoleTableService : ITransient
var ignoreTables = new List
{
//"DingTalkUser",
- //"ApprovalFlow",
+ //"DataApproval",
//"GoViewPro",
//"GoViewPro",
//"GoViewProData"
diff --git a/Admin.NET/Admin.NET.sln b/Admin.NET/Admin.NET.sln
index 10512930..5adf7a13 100644
--- a/Admin.NET/Admin.NET.sln
+++ b/Admin.NET/Admin.NET.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
-VisualStudioVersion = 17.14.36429.23 d17.14
+VisualStudioVersion = 17.14.36429.23
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Application", "Admin.NET.Application\Admin.NET.Application.csproj", "{C3F5AEC5-ACEE-4109-94E3-3F981DC18268}"
EndProject
@@ -24,8 +24,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Plugin.DingTalk",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Plugin.ReZero", "Plugins\Admin.NET.Plugin.ReZero\Admin.NET.Plugin.ReZero.csproj", "{04AB2E76-DE8B-4EFD-9F48-F8D4C0993106}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Plugin.ApprovalFlow", "Plugins\Admin.NET.Plugin.ApprovalFlow\Admin.NET.Plugin.ApprovalFlow.csproj", "{4124E31B-EA94-4EE3-9EC6-A565F1420AEA}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Plugin.K3Cloud", "Plugins\Admin.NET.Plugin.K3Cloud\Admin.NET.Plugin.K3Cloud.csproj", "{9EB9C39E-E14F-443E-9AA3-EE417ABCBC1D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Plugin.PaddleOCR", "Plugins\Admin.NET.Plugin.PaddleOCR\Admin.NET.Plugin.PaddleOCR.csproj", "{1B106C11-E5BF-44AB-A283-1E948A8BD8C2}"
@@ -36,6 +34,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Admin.NET.Test", "Admin.NET
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Admin.NET.Plugin.Ai", "Plugins\Admin.NET.Plugin.Ai\Admin.NET.Plugin.Ai.csproj", "{EB254721-C73C-4B1F-B9D7-0D989409F0C8}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Admin.NET.Plugin.DataApproval", "Plugins\Admin.NET.Plugin.DataApproval\Admin.NET.Plugin.DataApproval.csproj", "{BCB22734-58C1-5B78-60E8-EE68E9F24333}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -70,10 +70,6 @@ Global
{04AB2E76-DE8B-4EFD-9F48-F8D4C0993106}.Debug|Any CPU.Build.0 = Debug|Any CPU
{04AB2E76-DE8B-4EFD-9F48-F8D4C0993106}.Release|Any CPU.ActiveCfg = Release|Any CPU
{04AB2E76-DE8B-4EFD-9F48-F8D4C0993106}.Release|Any CPU.Build.0 = Release|Any CPU
- {4124E31B-EA94-4EE3-9EC6-A565F1420AEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4124E31B-EA94-4EE3-9EC6-A565F1420AEA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4124E31B-EA94-4EE3-9EC6-A565F1420AEA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4124E31B-EA94-4EE3-9EC6-A565F1420AEA}.Release|Any CPU.Build.0 = Release|Any CPU
{9EB9C39E-E14F-443E-9AA3-EE417ABCBC1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9EB9C39E-E14F-443E-9AA3-EE417ABCBC1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9EB9C39E-E14F-443E-9AA3-EE417ABCBC1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -94,6 +90,10 @@ Global
{EB254721-C73C-4B1F-B9D7-0D989409F0C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB254721-C73C-4B1F-B9D7-0D989409F0C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB254721-C73C-4B1F-B9D7-0D989409F0C8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BCB22734-58C1-5B78-60E8-EE68E9F24333}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BCB22734-58C1-5B78-60E8-EE68E9F24333}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BCB22734-58C1-5B78-60E8-EE68E9F24333}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BCB22734-58C1-5B78-60E8-EE68E9F24333}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -102,11 +102,11 @@ Global
{C4A288D5-0FAA-4F43-9072-B97635D7871D} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
{F6A002AD-CF7F-4771-8597-F12A50A93DAA} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
{04AB2E76-DE8B-4EFD-9F48-F8D4C0993106} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
- {4124E31B-EA94-4EE3-9EC6-A565F1420AEA} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
{9EB9C39E-E14F-443E-9AA3-EE417ABCBC1D} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
{1B106C11-E5BF-44AB-A283-1E948A8BD8C2} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
{12998618-A875-4580-B5B1-0CC50CE85F27} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
{EB254721-C73C-4B1F-B9D7-0D989409F0C8} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
+ {BCB22734-58C1-5B78-60E8-EE68E9F24333} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5CD801D7-984A-4F5C-8FA2-211B7A5EA9F3}
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.Ai/Configuration/Ai.json b/Admin.NET/Plugins/Admin.NET.Plugin.Ai/Configuration/Ai.json
index 5fb60c94..ed3b6d42 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.Ai/Configuration/Ai.json
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.Ai/Configuration/Ai.json
@@ -1,4 +1,11 @@
{
+ "[openapi:AiChat]": {
+ "Group": "AiChat",
+ "Title": "AiChat",
+ "Description": "LLM 大模型",
+ "Version": "1.0.0",
+ "Order": 100
+ },
"LLM": {
"ModelProvider": "DeepSeek", // 当前使用模型,取值为下面Providers的ProductName
"InitSystemChatMessage": "你是一个经验丰富的 Admin.NET 人工智能助手,请根据用户的问题给出准确的回答。- **回答请以markdown格式输出**;- **适当加入emoji表达人类情感,使内容更易于理解与传播。**",
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Enum/FlowTypeEnum.cs b/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Enum/FlowTypeEnum.cs
deleted file mode 100644
index 3b165cb7..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Enum/FlowTypeEnum.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-namespace Admin.NET.Plugin.ApprovalFlow;
-
-///
-/// 流程类型枚举
-///
-[Description("流程类型枚举")]
-public enum FlowTypeEnum
-{
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.Core/Abstractions/Pay/IPayPlugin.cs b/Admin.NET/Plugins/Admin.NET.Plugin.Core/Abstractions/Pay/IPayPlugin.cs
deleted file mode 100644
index b8e872c0..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.Core/Abstractions/Pay/IPayPlugin.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-using PluginCore.IPlugins;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Admin.NET.Plugin.Core.Abstractions.Pay;
-public interface IPayPlugin : IPlugin
-{
- string Name { get; set; }
- string Say();
-}
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.Core/Admin.NET.Plugin.Core.csproj b/Admin.NET/Plugins/Admin.NET.Plugin.Core/Admin.NET.Plugin.Core.csproj
deleted file mode 100644
index f3688bb2..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.Core/Admin.NET.Plugin.Core.csproj
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
- net8.0;net9.0
- 1701;1702;8616;1591;8618;8619;8629;8602;8603;8604;8625;8765
- Admin.NET.Plugin.Core.xml
- enable
- enable
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.Core/Admin.NET.Plugin.Core.xml b/Admin.NET/Plugins/Admin.NET.Plugin.Core/Admin.NET.Plugin.Core.xml
deleted file mode 100644
index e1f8a56e..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.Core/Admin.NET.Plugin.Core.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- Admin.NET.Plugin.Core
-
-
-
-
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.Core/GlobalUsing.cs b/Admin.NET/Plugins/Admin.NET.Plugin.Core/GlobalUsing.cs
deleted file mode 100644
index 19a76f13..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.Core/GlobalUsing.cs
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Admin.NET.Plugin.ApprovalFlow.csproj b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Admin.NET.Plugin.DataApproval.csproj
similarity index 100%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Admin.NET.Plugin.ApprovalFlow.csproj
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Admin.NET.Plugin.DataApproval.csproj
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Configuration/ApprovalFlow.json b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Configuration/DataApproval.json
similarity index 67%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Configuration/ApprovalFlow.json
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Configuration/DataApproval.json
index 85b05128..3a2043d1 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Configuration/ApprovalFlow.json
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Configuration/DataApproval.json
@@ -1,13 +1,13 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
- "[openapi:审批流程]": {
- "Group": "审批流程",
- "Title": "审批流程",
+ "[openapi:DataApproval]": {
+ "Group": "DataApproval",
+ "Title": "DataApproval",
"Description": "对业务实体数据的增删改操作进行流程审批。",
"Version": "1.0.0",
"Order": 100
},
- "ApprovalFlow": {
+ "DataApproval": {
}
}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Const/ApprovalFlowConst.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Const/DataApprovalConst.cs
similarity index 84%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Const/ApprovalFlowConst.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Const/DataApprovalConst.cs
index 365309ca..97422a5d 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Const/ApprovalFlowConst.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Const/DataApprovalConst.cs
@@ -4,13 +4,13 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-namespace Admin.NET.Plugin.ApprovalFlow;
+namespace Admin.NET.Plugin.DataApproval;
///
-/// 审批流程相关常量
+/// 数据审批相关常量
///
-[Const("审批流程相关常量")]
-public class ApprovalFlowConst
+[Const("数据审批相关常量")]
+public class DataApprovalConst
{
///
/// API分组名称
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Entity/ApprovalForm.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Entity/ApprovalForm.cs
similarity index 95%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Entity/ApprovalForm.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Entity/ApprovalForm.cs
index 3146cd71..dda487f1 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Entity/ApprovalForm.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Entity/ApprovalForm.cs
@@ -1,62 +1,62 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-namespace Admin.NET.Plugin.ApprovalFlow;
-
-///
-/// 审批流表单
-///
-[SugarTable(null, "审批流表单")]
-public class ApprovalForm : EntityBaseData
-{
- ///
- /// 编号
- ///
- [SugarColumn(ColumnDescription = "编号", Length = 32)]
- public string? Code { get; set; }
-
- ///
- /// 名称
- ///
- [SugarColumn(ColumnDescription = "名称", Length = 32)]
- public string? Name { get; set; }
-
- ///
- /// 表单名称
- ///
- [SugarColumn(ColumnDescription = "表单名称", Length = 32)]
- public string? FormName { get; set; }
-
- ///
- /// 表单属性
- ///
- [SugarColumn(ColumnDescription = "表单属性", Length = 32)]
- public string? FormType { get; set; }
-
- ///
- /// 表单状态
- ///
- [SugarColumn(ColumnDescription = "表单状态")]
- public int? FormStatus { get; set; }
-
- ///
- /// 表单结果
- ///
- [SugarColumn(ColumnDescription = "表单结果", ColumnDataType = StaticConfig.CodeFirst_BigString)]
- public string? FormResult { get; set; }
-
- ///
- /// 状态
- ///
- [SugarColumn(ColumnDescription = "状态")]
- public int? Status { get; set; }
-
- ///
- /// 备注
- ///
- [SugarColumn(ColumnDescription = "备注", Length = 255)]
- public string? Remark { get; set; }
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.DataApproval;
+
+///
+/// 审批流表单
+///
+[SugarTable(null, "审批流表单")]
+public class ApprovalForm : EntityBaseData
+{
+ ///
+ /// 编号
+ ///
+ [SugarColumn(ColumnDescription = "编号", Length = 32)]
+ public string? Code { get; set; }
+
+ ///
+ /// 名称
+ ///
+ [SugarColumn(ColumnDescription = "名称", Length = 32)]
+ public string? Name { get; set; }
+
+ ///
+ /// 表单名称
+ ///
+ [SugarColumn(ColumnDescription = "表单名称", Length = 32)]
+ public string? FormName { get; set; }
+
+ ///
+ /// 表单属性
+ ///
+ [SugarColumn(ColumnDescription = "表单属性", Length = 32)]
+ public string? FormType { get; set; }
+
+ ///
+ /// 表单状态
+ ///
+ [SugarColumn(ColumnDescription = "表单状态")]
+ public int? FormStatus { get; set; }
+
+ ///
+ /// 表单结果
+ ///
+ [SugarColumn(ColumnDescription = "表单结果", ColumnDataType = StaticConfig.CodeFirst_BigString)]
+ public string? FormResult { get; set; }
+
+ ///
+ /// 状态
+ ///
+ [SugarColumn(ColumnDescription = "状态")]
+ public int? Status { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [SugarColumn(ColumnDescription = "备注", Length = 255)]
+ public string? Remark { get; set; }
}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Entity/ApprovalFormRecord.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Entity/ApprovalFormRecord.cs
similarity index 95%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Entity/ApprovalFormRecord.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Entity/ApprovalFormRecord.cs
index 78dc14ec..9a06d41c 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Entity/ApprovalFormRecord.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Entity/ApprovalFormRecord.cs
@@ -1,56 +1,56 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-namespace Admin.NET.Plugin.ApprovalFlow;
-
-///
-/// 审批流表单记录
-///
-[SugarTable(null, "审批流表单记录")]
-public class ApprovalFormRecord : EntityBaseData
-{
- ///
- /// 流程Id
- ///
- [SugarColumn(ColumnDescription = "流程Id")]
- public long? FlowId { get; set; }
-
- ///
- /// 表单名称
- ///
- [SugarColumn(ColumnDescription = "表单名称", Length = 32)]
- public string? FormName { get; set; }
-
- ///
- /// 表单类型
- ///
- [SugarColumn(ColumnDescription = "表单类型", Length = 32)]
- public string? FormType { get; set; }
-
- ///
- /// 表单状态
- ///
- [SugarColumn(ColumnDescription = "表单状态", Length = 11)]
- public string? FormStatus { get; set; }
-
- ///
- /// 修改前
- ///
- [SugarColumn(ColumnDescription = "修改前", ColumnDataType = StaticConfig.CodeFirst_BigString)]
- public string? FormBefore { get; set; }
-
- ///
- /// 修改后
- ///
- [SugarColumn(ColumnDescription = "修改后", ColumnDataType = StaticConfig.CodeFirst_BigString)]
- public string? FormAfter { get; set; }
-
- ///
- /// 表单结果
- ///
- [SugarColumn(ColumnDescription = "表单结果", ColumnDataType = StaticConfig.CodeFirst_BigString)]
- public string? FormResult { get; set; }
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.DataApproval;
+
+///
+/// 审批流表单记录
+///
+[SugarTable(null, "审批流表单记录")]
+public class ApprovalFormRecord : EntityBaseData
+{
+ ///
+ /// 流程Id
+ ///
+ [SugarColumn(ColumnDescription = "流程Id")]
+ public long? FlowId { get; set; }
+
+ ///
+ /// 表单名称
+ ///
+ [SugarColumn(ColumnDescription = "表单名称", Length = 32)]
+ public string? FormName { get; set; }
+
+ ///
+ /// 表单类型
+ ///
+ [SugarColumn(ColumnDescription = "表单类型", Length = 32)]
+ public string? FormType { get; set; }
+
+ ///
+ /// 表单状态
+ ///
+ [SugarColumn(ColumnDescription = "表单状态", Length = 11)]
+ public string? FormStatus { get; set; }
+
+ ///
+ /// 修改前
+ ///
+ [SugarColumn(ColumnDescription = "修改前", ColumnDataType = StaticConfig.CodeFirst_BigString)]
+ public string? FormBefore { get; set; }
+
+ ///
+ /// 修改后
+ ///
+ [SugarColumn(ColumnDescription = "修改后", ColumnDataType = StaticConfig.CodeFirst_BigString)]
+ public string? FormAfter { get; set; }
+
+ ///
+ /// 表单结果
+ ///
+ [SugarColumn(ColumnDescription = "表单结果", ColumnDataType = StaticConfig.CodeFirst_BigString)]
+ public string? FormResult { get; set; }
}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Entity/ApprovalFlow.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Entity/DataApproval.cs
similarity index 91%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Entity/ApprovalFlow.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Entity/DataApproval.cs
index 7ef66ca0..9d03efe5 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Entity/ApprovalFlow.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Entity/DataApproval.cs
@@ -4,13 +4,13 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-namespace Admin.NET.Plugin.ApprovalFlow;
+namespace Admin.NET.Plugin.DataApproval;
///
-/// 审批流程信息表
+/// 数据审批信息表
///
-[SugarTable(null, "审批流程信息表")]
-public class ApprovalFlow : EntityBaseData
+[SugarTable(null, "数据审批信息表")]
+public class DataApproval : EntityBaseData
{
///
/// 编号
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Entity/ApprovalFlowRecord.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Entity/DataApprovalRecord.cs
similarity index 93%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Entity/ApprovalFlowRecord.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Entity/DataApprovalRecord.cs
index bc48cbe2..1c2efbbe 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Entity/ApprovalFlowRecord.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Entity/DataApprovalRecord.cs
@@ -1,50 +1,50 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-namespace Admin.NET.Plugin.ApprovalFlow;
-
-///
-/// 审批流流程记录
-///
-[SugarTable(null, "审批流流程记录")]
-public class ApprovalFlowRecord : EntityBaseData
-{
- ///
- /// 表单名称
- ///
- [SugarColumn(ColumnDescription = "表单名称", Length = 255)]
- public string? FormName { get; set; }
-
- ///
- /// 表单状态
- ///
- [SugarColumn(ColumnDescription = "表单状态", Length = 32)]
- public string? FormStatus { get; set; }
-
- ///
- /// 表单触发
- ///
- [SugarColumn(ColumnDescription = "表单触发", ColumnDataType = StaticConfig.CodeFirst_BigString)]
- public string? FormJson { get; set; }
-
- ///
- /// 表单结果
- ///
- [SugarColumn(ColumnDescription = "表单结果", ColumnDataType = StaticConfig.CodeFirst_BigString)]
- public string? FormResult { get; set; }
-
- ///
- /// 流程结构
- ///
- [SugarColumn(ColumnDescription = "流程结构", ColumnDataType = StaticConfig.CodeFirst_BigString)]
- public string? FlowJson { get; set; }
-
- ///
- /// 流程结果
- ///
- [SugarColumn(ColumnDescription = "流程结果", ColumnDataType = StaticConfig.CodeFirst_BigString)]
- public string? FlowResult { get; set; }
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.DataApproval;
+
+///
+/// 审批流流程记录
+///
+[SugarTable(null, "审批流流程记录")]
+public class DataApprovalRecord : EntityBaseData
+{
+ ///
+ /// 表单名称
+ ///
+ [SugarColumn(ColumnDescription = "表单名称", Length = 255)]
+ public string? FormName { get; set; }
+
+ ///
+ /// 表单状态
+ ///
+ [SugarColumn(ColumnDescription = "表单状态", Length = 32)]
+ public string? FormStatus { get; set; }
+
+ ///
+ /// 表单触发
+ ///
+ [SugarColumn(ColumnDescription = "表单触发", ColumnDataType = StaticConfig.CodeFirst_BigString)]
+ public string? FormJson { get; set; }
+
+ ///
+ /// 表单结果
+ ///
+ [SugarColumn(ColumnDescription = "表单结果", ColumnDataType = StaticConfig.CodeFirst_BigString)]
+ public string? FormResult { get; set; }
+
+ ///
+ /// 流程结构
+ ///
+ [SugarColumn(ColumnDescription = "流程结构", ColumnDataType = StaticConfig.CodeFirst_BigString)]
+ public string? FlowJson { get; set; }
+
+ ///
+ /// 流程结果
+ ///
+ [SugarColumn(ColumnDescription = "流程结果", ColumnDataType = StaticConfig.CodeFirst_BigString)]
+ public string? FlowResult { get; set; }
}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/GlobalUsings.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/GlobalUsings.cs
similarity index 98%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/GlobalUsings.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/GlobalUsings.cs
index ed9f17ae..904ea938 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/GlobalUsings.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/GlobalUsings.cs
@@ -1,20 +1,20 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-global using Admin.NET.Core;
-global using Furion;
-global using Furion.DependencyInjection;
-global using Furion.DynamicApiController;
-global using Furion.FriendlyException;
-global using Mapster;
-global using Microsoft.AspNetCore.Mvc;
-global using Microsoft.Extensions.DependencyInjection;
-global using SqlSugar;
-global using System;
-global using System.Collections.Generic;
-global using System.ComponentModel;
-global using System.ComponentModel.DataAnnotations;
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+global using Admin.NET.Core;
+global using Furion;
+global using Furion.DependencyInjection;
+global using Furion.DynamicApiController;
+global using Furion.FriendlyException;
+global using Mapster;
+global using Microsoft.AspNetCore.Mvc;
+global using Microsoft.Extensions.DependencyInjection;
+global using SqlSugar;
+global using System;
+global using System.Collections.Generic;
+global using System.ComponentModel;
+global using System.ComponentModel.DataAnnotations;
global using System.Threading.Tasks;
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Middleware/ApprovalFlowMiddleware.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Middleware/DataApprovalMiddleware.cs
similarity index 76%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Middleware/ApprovalFlowMiddleware.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Middleware/DataApprovalMiddleware.cs
index 9c167bea..ffebab85 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Middleware/ApprovalFlowMiddleware.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Middleware/DataApprovalMiddleware.cs
@@ -1,50 +1,50 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using Admin.NET.Plugin.ApprovalFlow.Service;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Http;
-
-namespace Admin.NET.Plugin.ApprovalFlow;
-
-///
-/// 扩展审批流中间件
-///
-public static class ApprovalFlowMiddlewareExtensions
-{
- ///
- /// 使用审批流
- ///
- ///
- ///
- public static IApplicationBuilder UseApprovalFlow(this IApplicationBuilder builder)
- {
- return builder.UseMiddleware();
- }
-}
-
-///
-/// 审批流中间件
-///
-public class ApprovalFlowMiddleware
-{
- private readonly RequestDelegate _next;
- private readonly SysApprovalService _sysApprovalService;
-
- public ApprovalFlowMiddleware(RequestDelegate next)
- {
- _next = next;
- _sysApprovalService = App.GetRequiredService();
- }
-
- public async Task InvokeAsync(HttpContext context)
- {
- await _sysApprovalService.MatchApproval(context);
-
- // 调用下一个中间件
- await _next(context);
- }
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.NET.Plugin.DataApproval.Service;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+
+namespace Admin.NET.Plugin.DataApproval;
+
+///
+/// 扩展审批流中间件
+///
+public static class DataApprovalMiddlewareExtensions
+{
+ ///
+ /// 使用审批流
+ ///
+ ///
+ ///
+ public static IApplicationBuilder UseDataApproval(this IApplicationBuilder builder)
+ {
+ return builder.UseMiddleware();
+ }
+}
+
+///
+/// 审批流中间件
+///
+public class DataApprovalMiddleware
+{
+ private readonly RequestDelegate _next;
+ private readonly SysApprovalService _sysApprovalService;
+
+ public DataApprovalMiddleware(RequestDelegate next)
+ {
+ _next = next;
+ _sysApprovalService = App.GetRequiredService();
+ }
+
+ public async Task InvokeAsync(HttpContext context)
+ {
+ await _sysApprovalService.MatchApproval(context);
+
+ // 调用下一个中间件
+ await _next(context);
+ }
}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/SeedData/SysMenuSeedData.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/SeedData/SysMenuSeedData.cs
similarity index 93%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/SeedData/SysMenuSeedData.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/SeedData/SysMenuSeedData.cs
index d2ec2ae6..b4d75683 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/SeedData/SysMenuSeedData.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/SeedData/SysMenuSeedData.cs
@@ -4,10 +4,10 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-namespace Admin.NET.Plugin.ApprovalFlow;
+namespace Admin.NET.Plugin.DataApproval;
///
-/// 审批流程菜单表种子数据
+/// 数据审批菜单表种子数据
///
public class SysMenuSeedData : ISqlSugarEntitySeedData
{
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/ApprovalFlowService.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/DataApprovalService.cs
similarity index 65%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/ApprovalFlowService.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/DataApprovalService.cs
index b957d9b2..aeb9ad1d 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/ApprovalFlowService.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/DataApprovalService.cs
@@ -1,154 +1,154 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using System.Text.Json;
-
-namespace Admin.NET.Plugin.ApprovalFlow.Service;
-
-///
-/// 审批流程服务
-///
-[ApiDescriptionSettings(ApprovalFlowConst.GroupName, Order = 100, Description = "审批流程")]
-public class ApprovalFlowService : IDynamicApiController, ITransient
-{
- private readonly SqlSugarRepository _approvalFlowRep;
-
- public ApprovalFlowService(SqlSugarRepository approvalFlowRep)
- {
- _approvalFlowRep = approvalFlowRep;
- }
-
- ///
- /// 分页查询审批流
- ///
- ///
- ///
- [HttpPost]
- [ApiDescriptionSettings(Name = "Page")]
- public async Task> Page(ApprovalFlowInput input)
- {
- return await _approvalFlowRep.AsQueryable()
- .WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), u => u.Code.Contains(input.Keyword.Trim()) || u.Name.Contains(input.Keyword.Trim()) || u.Remark.Contains(input.Keyword.Trim()))
- .WhereIF(!string.IsNullOrWhiteSpace(input.Code), u => u.Code.Contains(input.Code.Trim()))
- .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name.Trim()))
- .WhereIF(!string.IsNullOrWhiteSpace(input.Remark), u => u.Remark.Contains(input.Remark.Trim()))
- .Select()
- .ToPagedListAsync(input.Page, input.PageSize);
- }
-
- ///
- /// 增加审批流
- ///
- ///
- ///
- [ApiDescriptionSettings(Name = "Add"), HttpPost]
- public async Task Add(AddApprovalFlowInput input)
- {
- var entity = input.Adapt();
- if (input.Code == null)
- {
- entity.Code = await LastCode("");
- }
- await _approvalFlowRep.InsertAsync(entity);
- return entity.Id;
- }
-
- ///
- /// 更新审批流
- ///
- ///
- ///
- [ApiDescriptionSettings(Name = "Update"), HttpPost]
- public async Task Update(UpdateApprovalFlowInput input)
- {
- var entity = input.Adapt();
- await _approvalFlowRep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
- }
-
- ///
- /// 删除审批流
- ///
- ///
- ///
- [ApiDescriptionSettings(Name = "Delete"), HttpPost]
- public async Task Delete(DeleteApprovalFlowInput input)
- {
- var entity = await _approvalFlowRep.GetByIdAsync(input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
- await _approvalFlowRep.FakeDeleteAsync(entity); // 假删除
- }
-
- ///
- /// 获取审批流
- ///
- ///
- ///
- public async Task GetDetail([FromQuery] QueryByIdApprovalFlowInput input)
- {
- return await _approvalFlowRep.GetByIdAsync(input.Id);
- }
-
- ///
- /// 根据编码获取审批流信息
- ///
- ///
- ///
- public async Task GetInfo([FromQuery] string code)
- {
- return await _approvalFlowRep.GetFirstAsync(u => u.Code == code);
- }
-
- ///
- /// 获取审批流列表
- ///
- ///
- ///
- public async Task> GetList([FromQuery] ApprovalFlowInput input)
- {
- return await _approvalFlowRep.AsQueryable().Select().ToListAsync();
- }
-
- ///
- /// 获取今天创建的最大编号
- ///
- ///
- ///
- private async Task LastCode(string prefix)
- {
- var today = DateTime.Now.Date;
- var count = await _approvalFlowRep.AsQueryable().Where(u => u.CreateTime >= today).CountAsync();
- return prefix + DateTime.Now.ToString("yyMMdd") + string.Format("{0:d2}", count + 1);
- }
-
- [HttpGet]
- [ApiDescriptionSettings(Name = "FlowList")]
- [DisplayName("获取审批流结构")]
- public async Task FlowList([FromQuery] string code)
- {
- var result = await _approvalFlowRep.AsQueryable().Where(u => u.Code == code).Select().FirstAsync();
- var FlowJson = result.FlowJson != null ? JsonSerializer.Deserialize(result.FlowJson) : new ApprovalFlowItem();
- var FormJson = result.FormJson != null ? JsonSerializer.Deserialize(result.FormJson) : new ApprovalFormItem();
- return new
- {
- FlowJson,
- FormJson
- };
- }
-
- [HttpGet]
- [ApiDescriptionSettings(Name = "FormRoutes")]
- [DisplayName("获取审批流规则")]
- public async Task> FormRoutes()
- {
- var results = await _approvalFlowRep.AsQueryable().Select().ToListAsync();
- var list = new List();
- foreach (var item in results)
- {
- var FormJson = item.FormJson != null ? JsonSerializer.Deserialize(item.FormJson) : new ApprovalFormItem();
- if (item.FormJson != null) list.Add(FormJson.Route);
- }
- return list;
- }
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json;
+
+namespace Admin.NET.Plugin.DataApproval.Service;
+
+///
+/// 数据审批服务
+///
+[ApiDescriptionSettings(DataApprovalConst.GroupName, Order = 100, Description = "数据审批")]
+public class DataApprovalService : IDynamicApiController, ITransient
+{
+ private readonly SqlSugarRepository _DataApprovalRep;
+
+ public DataApprovalService(SqlSugarRepository DataApprovalRep)
+ {
+ _DataApprovalRep = DataApprovalRep;
+ }
+
+ ///
+ /// 分页查询审批流
+ ///
+ ///
+ ///
+ [HttpPost]
+ [ApiDescriptionSettings(Name = "Page")]
+ public async Task> Page(DataApprovalInput input)
+ {
+ return await _DataApprovalRep.AsQueryable()
+ .WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), u => u.Code.Contains(input.Keyword.Trim()) || u.Name.Contains(input.Keyword.Trim()) || u.Remark.Contains(input.Keyword.Trim()))
+ .WhereIF(!string.IsNullOrWhiteSpace(input.Code), u => u.Code.Contains(input.Code.Trim()))
+ .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name.Trim()))
+ .WhereIF(!string.IsNullOrWhiteSpace(input.Remark), u => u.Remark.Contains(input.Remark.Trim()))
+ .Select()
+ .ToPagedListAsync(input.Page, input.PageSize);
+ }
+
+ ///
+ /// 增加审批流
+ ///
+ ///
+ ///
+ [ApiDescriptionSettings(Name = "Add"), HttpPost]
+ public async Task Add(AddDataApprovalInput input)
+ {
+ var entity = input.Adapt();
+ if (input.Code == null)
+ {
+ entity.Code = await LastCode("");
+ }
+ await _DataApprovalRep.InsertAsync(entity);
+ return entity.Id;
+ }
+
+ ///
+ /// 更新审批流
+ ///
+ ///
+ ///
+ [ApiDescriptionSettings(Name = "Update"), HttpPost]
+ public async Task Update(UpdateDataApprovalInput input)
+ {
+ var entity = input.Adapt();
+ await _DataApprovalRep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
+ }
+
+ ///
+ /// 删除审批流
+ ///
+ ///
+ ///
+ [ApiDescriptionSettings(Name = "Delete"), HttpPost]
+ public async Task Delete(DeleteDataApprovalInput input)
+ {
+ var entity = await _DataApprovalRep.GetByIdAsync(input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
+ await _DataApprovalRep.FakeDeleteAsync(entity); // 假删除
+ }
+
+ ///
+ /// 获取审批流
+ ///
+ ///
+ ///
+ public async Task GetDetail([FromQuery] QueryByIdDataApprovalInput input)
+ {
+ return await _DataApprovalRep.GetByIdAsync(input.Id);
+ }
+
+ ///
+ /// 根据编码获取审批流信息
+ ///
+ ///
+ ///
+ public async Task GetInfo([FromQuery] string code)
+ {
+ return await _DataApprovalRep.GetFirstAsync(u => u.Code == code);
+ }
+
+ ///
+ /// 获取审批流列表
+ ///
+ ///
+ ///
+ public async Task> GetList([FromQuery] DataApprovalInput input)
+ {
+ return await _DataApprovalRep.AsQueryable().Select().ToListAsync();
+ }
+
+ ///
+ /// 获取今天创建的最大编号
+ ///
+ ///
+ ///
+ private async Task LastCode(string prefix)
+ {
+ var today = DateTime.Now.Date;
+ var count = await _DataApprovalRep.AsQueryable().Where(u => u.CreateTime >= today).CountAsync();
+ return prefix + DateTime.Now.ToString("yyMMdd") + string.Format("{0:d2}", count + 1);
+ }
+
+ [HttpGet]
+ [ApiDescriptionSettings(Name = "FlowList")]
+ [DisplayName("获取审批流结构")]
+ public async Task FlowList([FromQuery] string code)
+ {
+ var result = await _DataApprovalRep.AsQueryable().Where(u => u.Code == code).Select().FirstAsync();
+ var FlowJson = result.FlowJson != null ? JsonSerializer.Deserialize(result.FlowJson) : new DataApprovalItem();
+ var FormJson = result.FormJson != null ? JsonSerializer.Deserialize(result.FormJson) : new ApprovalFormItem();
+ return new
+ {
+ FlowJson,
+ FormJson
+ };
+ }
+
+ [HttpGet]
+ [ApiDescriptionSettings(Name = "FormRoutes")]
+ [DisplayName("获取审批流规则")]
+ public async Task> FormRoutes()
+ {
+ var results = await _DataApprovalRep.AsQueryable().Select().ToListAsync();
+ var list = new List();
+ foreach (var item in results)
+ {
+ var FormJson = item.FormJson != null ? JsonSerializer.Deserialize(item.FormJson) : new ApprovalFormItem();
+ if (item.FormJson != null) list.Add(FormJson.Route);
+ }
+ return list;
+ }
}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFormItem.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/ApprovalFormItem.cs
similarity index 93%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFormItem.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/ApprovalFormItem.cs
index e80b4b1c..dff80fbe 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFormItem.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/ApprovalFormItem.cs
@@ -1,27 +1,27 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using System.Text.Json.Serialization;
-
-namespace Admin.NET.Plugin.ApprovalFlow.Service;
-
-public class ApprovalFormItem
-{
- [JsonPropertyName("configId")]
- public string ConfigId { get; set; }
-
- [JsonPropertyName("tableName")]
- public string TableName { get; set; }
-
- [JsonPropertyName("entityName")]
- public string EntityName { get; set; }
-
- [JsonPropertyName("typeName")]
- public string TypeName { get; set; }
-
- [JsonPropertyName("route")]
- public string Route => EntityName[..1].ToLower() + EntityName[1..] + "/" + TypeName;
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.NET.Plugin.DataApproval.Service;
+
+public class ApprovalFormItem
+{
+ [JsonPropertyName("configId")]
+ public string ConfigId { get; set; }
+
+ [JsonPropertyName("tableName")]
+ public string TableName { get; set; }
+
+ [JsonPropertyName("entityName")]
+ public string EntityName { get; set; }
+
+ [JsonPropertyName("typeName")]
+ public string TypeName { get; set; }
+
+ [JsonPropertyName("route")]
+ public string Route => EntityName[..1].ToLower() + EntityName[1..] + "/" + TypeName;
}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFlowDto.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/DataApprovalDto.cs
similarity index 96%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFlowDto.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/DataApprovalDto.cs
index a8fd9a83..7ba54baf 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFlowDto.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/DataApprovalDto.cs
@@ -4,12 +4,12 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-namespace Admin.NET.Plugin.ApprovalFlow.Service;
+namespace Admin.NET.Plugin.DataApproval.Service;
///
/// 审批流输出参数
///
-public class ApprovalFlowDto
+public class DataApprovalDto
{
///
/// 主键Id
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFlowInput.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/DataApprovalInput.cs
similarity index 89%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFlowInput.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/DataApprovalInput.cs
index dc9328f2..ed2eef19 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFlowInput.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/DataApprovalInput.cs
@@ -4,12 +4,12 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-namespace Admin.NET.Plugin.ApprovalFlow.Service;
+namespace Admin.NET.Plugin.DataApproval.Service;
///
/// 审批流基础输入参数
///
-public class ApprovalFlowBaseInput
+public class DataApprovalBaseInput
{
///
/// 编号
@@ -85,7 +85,7 @@ public class ApprovalFlowBaseInput
///
/// 审批流分页查询输入参数
///
-public class ApprovalFlowInput : BasePageInput
+public class DataApprovalInput : BasePageInput
{
///
/// 编号
@@ -106,7 +106,7 @@ public class ApprovalFlowInput : BasePageInput
///
/// 审批流增加输入参数
///
-public class AddApprovalFlowInput : ApprovalFlowBaseInput
+public class AddDataApprovalInput : DataApprovalBaseInput
{
///
/// 软删除
@@ -118,14 +118,14 @@ public class AddApprovalFlowInput : ApprovalFlowBaseInput
///
/// 审批流删除输入参数
///
-public class DeleteApprovalFlowInput : BaseIdInput
+public class DeleteDataApprovalInput : BaseIdInput
{
}
///
/// 审批流更新输入参数
///
-public class UpdateApprovalFlowInput : ApprovalFlowBaseInput
+public class UpdateDataApprovalInput : DataApprovalBaseInput
{
///
/// 主键Id
@@ -137,6 +137,6 @@ public class UpdateApprovalFlowInput : ApprovalFlowBaseInput
///
/// 审批流主键查询输入参数
///
-public class QueryByIdApprovalFlowInput : DeleteApprovalFlowInput
+public class QueryByIdDataApprovalInput : DeleteDataApprovalInput
{
}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFlowItem.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/DataApprovalItem.cs
similarity index 87%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFlowItem.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/DataApprovalItem.cs
index d35fea72..c691a030 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFlowItem.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/DataApprovalItem.cs
@@ -1,96 +1,96 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using System.Text.Json.Serialization;
-
-namespace Admin.NET.Plugin.ApprovalFlow.Service;
-
-public class ApprovalFlowItem
-{
- [JsonPropertyName("nodes")]
- public List Nodes { get; set; }
-
- [JsonPropertyName("edges")]
- public List Edges { get; set; }
-}
-
-public class ApprovalFlowNodeItem
-{
- [JsonPropertyName("id")]
- public string Id { get; set; }
-
- [JsonPropertyName("type")]
- public string Type { get; set; }
-
- [JsonPropertyName("x")]
- public float X { get; set; }
-
- [JsonPropertyName("y")]
- public float Y { get; set; }
-
- [JsonPropertyName("properties")]
- public FlowProperties Properties { get; set; }
-
- [JsonPropertyName("text")]
- [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
- public FlowTextItem Text { get; set; }
-}
-
-public class ApprovalFlowEdgeItem
-{
- [JsonPropertyName("id")]
- public string Id { get; set; }
-
- [JsonPropertyName("type")]
- public string Type { get; set; }
-
- [JsonPropertyName("sourceNodeId")]
- public string SourceNodeId { get; set; }
-
- [JsonPropertyName("targetNodeId")]
- public string TargetNodeId { get; set; }
-
- [JsonPropertyName("startPoint")]
- public FlowEdgePointItem StartPoint { get; set; }
-
- [JsonPropertyName("endPoint")]
- public FlowEdgePointItem EndPoint { get; set; }
-
- [JsonPropertyName("properties")]
- public FlowProperties Properties { get; set; }
-
- [JsonPropertyName("text")]
- [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
- public FlowTextItem Text { get; set; }
-
- [JsonPropertyName("pointsList")]
- public List PointsList { get; set; }
-}
-
-public class FlowProperties
-{
-}
-
-public class FlowTextItem
-{
- [JsonPropertyName("x")]
- public float X { get; set; }
-
- [JsonPropertyName("y")]
- public float Y { get; set; }
-
- [JsonPropertyName("value")]
- public string Value { get; set; }
-}
-
-public class FlowEdgePointItem
-{
- [JsonPropertyName("x")]
- public float X { get; set; }
-
- [JsonPropertyName("y")]
- public float Y { get; set; }
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.NET.Plugin.DataApproval.Service;
+
+public class DataApprovalItem
+{
+ [JsonPropertyName("nodes")]
+ public List Nodes { get; set; }
+
+ [JsonPropertyName("edges")]
+ public List Edges { get; set; }
+}
+
+public class DataApprovalNodeItem
+{
+ [JsonPropertyName("id")]
+ public string Id { get; set; }
+
+ [JsonPropertyName("type")]
+ public string Type { get; set; }
+
+ [JsonPropertyName("x")]
+ public float X { get; set; }
+
+ [JsonPropertyName("y")]
+ public float Y { get; set; }
+
+ [JsonPropertyName("properties")]
+ public FlowProperties Properties { get; set; }
+
+ [JsonPropertyName("text")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public FlowTextItem Text { get; set; }
+}
+
+public class DataApprovalEdgeItem
+{
+ [JsonPropertyName("id")]
+ public string Id { get; set; }
+
+ [JsonPropertyName("type")]
+ public string Type { get; set; }
+
+ [JsonPropertyName("sourceNodeId")]
+ public string SourceNodeId { get; set; }
+
+ [JsonPropertyName("targetNodeId")]
+ public string TargetNodeId { get; set; }
+
+ [JsonPropertyName("startPoint")]
+ public FlowEdgePointItem StartPoint { get; set; }
+
+ [JsonPropertyName("endPoint")]
+ public FlowEdgePointItem EndPoint { get; set; }
+
+ [JsonPropertyName("properties")]
+ public FlowProperties Properties { get; set; }
+
+ [JsonPropertyName("text")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public FlowTextItem Text { get; set; }
+
+ [JsonPropertyName("pointsList")]
+ public List PointsList { get; set; }
+}
+
+public class FlowProperties
+{
+}
+
+public class FlowTextItem
+{
+ [JsonPropertyName("x")]
+ public float X { get; set; }
+
+ [JsonPropertyName("y")]
+ public float Y { get; set; }
+
+ [JsonPropertyName("value")]
+ public string Value { get; set; }
+}
+
+public class FlowEdgePointItem
+{
+ [JsonPropertyName("x")]
+ public float X { get; set; }
+
+ [JsonPropertyName("y")]
+ public float Y { get; set; }
}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFlowOutput.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/DataApprovalOutput.cs
similarity index 96%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFlowOutput.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/DataApprovalOutput.cs
index 81f4b49c..3f03978b 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/ApprovalFlow/Dto/ApprovalFlowOutput.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/DataApproval/Dto/DataApprovalOutput.cs
@@ -4,12 +4,12 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-namespace Admin.NET.Plugin.ApprovalFlow.Service;
+namespace Admin.NET.Plugin.DataApproval.Service;
///
/// 审批流输出参数
///
-public class ApprovalFlowOutput
+public class DataApprovalOutput
{
///
/// 主键Id
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/SysApproval/SysApprovalService.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/SysApproval/SysApprovalService.cs
similarity index 73%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/SysApproval/SysApprovalService.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/SysApproval/SysApprovalService.cs
index 44f6f18f..3b58fbab 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Service/SysApproval/SysApprovalService.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Service/SysApproval/SysApprovalService.cs
@@ -1,81 +1,81 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using Microsoft.AspNetCore.Http;
-
-namespace Admin.NET.Plugin.ApprovalFlow.Service;
-
-public class SysApprovalService : ITransient
-{
- private readonly SqlSugarRepository _approvalFlowRep;
- private readonly SqlSugarRepository _approvalFormRep;
- private readonly ApprovalFlowService _approvalFlowService;
-
- public SysApprovalService(SqlSugarRepository approvalFlowRep, SqlSugarRepository approvalFormRep, ApprovalFlowService approvalFlowService)
- {
- _approvalFlowRep = approvalFlowRep;
- _approvalFormRep = approvalFormRep;
- _approvalFlowService = approvalFlowService;
- }
-
- ///
- /// 匹配审批流程
- ///
- ///
- ///
- [NonAction]
- public async Task MatchApproval(HttpContext context)
- {
- var request = context.Request;
- var response = context.Response;
-
- var path = request.Path.ToString().Split("/");
-
- var method = request.Method;
- var qs = request.QueryString;
- var h = request.Headers;
- var b = request.Body;
-
- var requestHeaders = request.Headers;
- var responseHeaders = response.Headers;
-
- var serviceName = path[1];
- if (serviceName.StartsWith("api"))
- {
- if (path.Length > 3)
- {
- var funcName = path[2];
- var typeName = path[3];
-
- var list = await _approvalFlowService.FormRoutes();
- if (list.Any(u => u.Contains(funcName) && u.Contains(typeName)))
- {
- var approvalFlow = new ApprovalFlowRecord
- {
- FormName = funcName,
- CreateTime = DateTime.Now,
- };
-
- // 判断是否需要审批
- await _approvalFlowRep.InsertAsync(approvalFlow);
-
- var approvalForm = new ApprovalFormRecord
- {
- FlowId = approvalFlow.Id,
- FormName = funcName,
- FormType = typeName,
- CreateTime = DateTime.Now,
- };
-
- // 判断是否需要审批
- await _approvalFormRep.InsertAsync(approvalForm);
- }
- }
- }
-
- await Task.CompletedTask;
- }
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Microsoft.AspNetCore.Http;
+
+namespace Admin.NET.Plugin.DataApproval.Service;
+
+public class SysApprovalService : ITransient
+{
+ private readonly SqlSugarRepository _DataApprovalRep;
+ private readonly SqlSugarRepository _approvalFormRep;
+ private readonly DataApprovalService _DataApprovalService;
+
+ public SysApprovalService(SqlSugarRepository DataApprovalRep, SqlSugarRepository approvalFormRep, DataApprovalService DataApprovalService)
+ {
+ _DataApprovalRep = DataApprovalRep;
+ _approvalFormRep = approvalFormRep;
+ _DataApprovalService = DataApprovalService;
+ }
+
+ ///
+ /// 匹配数据审批
+ ///
+ ///
+ ///
+ [NonAction]
+ public async Task MatchApproval(HttpContext context)
+ {
+ var request = context.Request;
+ var response = context.Response;
+
+ var path = request.Path.ToString().Split("/");
+
+ var method = request.Method;
+ var qs = request.QueryString;
+ var h = request.Headers;
+ var b = request.Body;
+
+ var requestHeaders = request.Headers;
+ var responseHeaders = response.Headers;
+
+ var serviceName = path[1];
+ if (serviceName.StartsWith("api"))
+ {
+ if (path.Length > 3)
+ {
+ var funcName = path[2];
+ var typeName = path[3];
+
+ var list = await _DataApprovalService.FormRoutes();
+ if (list.Any(u => u.Contains(funcName) && u.Contains(typeName)))
+ {
+ var DataApproval = new DataApprovalRecord
+ {
+ FormName = funcName,
+ CreateTime = DateTime.Now,
+ };
+
+ // 判断是否需要审批
+ await _DataApprovalRep.InsertAsync(DataApproval);
+
+ var approvalForm = new ApprovalFormRecord
+ {
+ FlowId = DataApproval.Id,
+ FormName = funcName,
+ FormType = typeName,
+ CreateTime = DateTime.Now,
+ };
+
+ // 判断是否需要审批
+ await _approvalFormRep.InsertAsync(approvalForm);
+ }
+ }
+ }
+
+ await Task.CompletedTask;
+ }
}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Startup.cs b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Startup.cs
similarity index 92%
rename from Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Startup.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Startup.cs
index f8d7f83a..4fe2599f 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Startup.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.DataApproval/Startup.cs
@@ -7,7 +7,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
-namespace Admin.NET.Plugin.ApprovalFlow;
+namespace Admin.NET.Plugin.DataApproval;
[AppStartup(100)]
public class Startup : AppStartup
@@ -18,6 +18,6 @@ public class Startup : AppStartup
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
- app.UseApprovalFlow();
+ app.UseDataApproval();
}
}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.GoView/Configuration/GoView.json b/Admin.NET/Plugins/Admin.NET.Plugin.GoView/Configuration/GoView.json
index 76e03c70..d3960ed9 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.GoView/Configuration/GoView.json
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.GoView/Configuration/GoView.json
@@ -1,9 +1,9 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
- "[openapi:GoView 大屏可视化]": {
- "Group": "GoView 大屏可视化",
- "Title": "GoView 大屏可视化",
+ "[openapi:GoView]": {
+ "Group": "GoView",
+ "Title": "GoView",
"Description": "GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可制作数据大屏,减少心智负担。",
"Version": "2.2.8",
"Order": 95
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Admin.NET.Plugin.PaddleOCR.csproj b/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Admin.NET.Plugin.PaddleOCR.csproj
index 35f74ed6..64586a2d 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Admin.NET.Plugin.PaddleOCR.csproj
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Admin.NET.Plugin.PaddleOCR.csproj
@@ -24,6 +24,10 @@
+
+
+
+
@@ -33,4 +37,10 @@
+
+
+ PreserveNewest
+
+
+
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Configuration/PaddleOCR.json b/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Configuration/PaddleOCR.json
new file mode 100644
index 00000000..02e21ab8
--- /dev/null
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Configuration/PaddleOCR.json
@@ -0,0 +1,9 @@
+{
+ "[openapi:PaddleOCR]": {
+ "Group": "PaddleOCR",
+ "Title": "PaddleOCR",
+ "Description": "文字识别与文档解析",
+ "Version": "1.0.0",
+ "Order": 100
+ }
+}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Const/ApplicationConst.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Const/PaddleOCRConst.cs
similarity index 96%
rename from Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Const/ApplicationConst.cs
rename to Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Const/PaddleOCRConst.cs
index c87228c1..f8122140 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Const/ApplicationConst.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Const/PaddleOCRConst.cs
@@ -10,7 +10,7 @@ namespace Admin.NET.Plugin.PaddleOCR;
/// PaddleOCR 图像识别
///
[Const("PaddleOCR 图像识别")]
-public class ApplicationConst
+public class PaddleOCRConst
{
///
/// API分组名称
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Service/PaddleOCRService.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Service/PaddleOCRService.cs
index acd95a6f..4cb0c67d 100644
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Service/PaddleOCRService.cs
+++ b/Admin.NET/Plugins/Admin.NET.Plugin.PaddleOCR/Service/PaddleOCRService.cs
@@ -14,7 +14,7 @@ namespace Admin.NET.Plugin.PaddleOCR.Service;
///
/// PaddleOCR 图像识别服务 🧩
///
-[ApiDescriptionSettings(ApplicationConst.GroupName, Description = "PaddleOCR 图像识别")]
+[ApiDescriptionSettings(PaddleOCRConst.GroupName, Description = "PaddleOCR 图像识别")]
public class PaddleOCRService : IDynamicApiController, ISingleton
{
private readonly PaddleOCREngine _engine;
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Admin.NET.Plugin.PluginCore.csproj b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Admin.NET.Plugin.PluginCore.csproj
deleted file mode 100644
index 4ab167f6..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Admin.NET.Plugin.PluginCore.csproj
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
- net8.0;net9.0
- 1701;1702;1591;8632
- enable
- disable
- True
- Admin.NET
- Admin.NET 通用权限开发平台
-
-
-
-
- true
- PreserveNewest
- PreserveNewest
- true
-
-
-
-
-
-
-
-
-
-
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/App_Data/PluginCore.Config.json b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/App_Data/PluginCore.Config.json
deleted file mode 100644
index 6340ddf3..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/App_Data/PluginCore.Config.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "Admin": {
- "UserName": "admin",
- "Password": "ABC12345"
- },
- "FrontendMode": "LocalEmbedded",
- "RemoteFrontend": "https://cdn.jsdelivr.net/gh/yiyungent/plugincore-admin-frontend@0.3.1/dist-cdn",
- "PluginWidgetDebug": false
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/App_Data/plugin.config.json b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/App_Data/plugin.config.json
deleted file mode 100644
index 1d0baec1..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/App_Data/plugin.config.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "EnabledPlugins": [ "Admin.NET.Plugin.Pay.Alipay" ] }
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/AppCenterController.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/AppCenterController.cs
deleted file mode 100644
index 3967d58b..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/AppCenterController.cs
+++ /dev/null
@@ -1,189 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using PluginCore.AspNetCore.ResponseModel;
-using PluginCore.Models;
-using System.Net;
-
-namespace PluginCore.AspNetCore.Controllers;
-
-///
-/// 应用中心
-/// 插件
-///
-[Route("api/plugincore/admin/[controller]/[action]")]
-// [PluginCoreAdminAuthorize]
-[ApiController]
-[NonUnify]
-public class AppCenterController : ControllerBase
-{
- #region Fields
-
- private static Dictionary _pluginDownloadTasks;
-
- #endregion Fields
-
- #region Ctor
-
- static AppCenterController()
- {
- _pluginDownloadTasks = new Dictionary();
- }
-
- public AppCenterController()
- {
- }
-
- #endregion Ctor
-
- #region Actions
-
- #region 插件列表
-
- ///
- /// 插件
- ///
- ///
- ///
- [HttpGet, HttpPost]
- public async Task> Plugins(string query = "")
- {
- BaseResponseModel responseDTO = new BaseResponseModel();
- IList pluginRegistryModels = new List();
- try
- {
- // 1. TODO: 从json文件中读取插件订阅源 registry url
- string registryUrl = "";
- // 2. TODO: 向订阅源发送 http get 获取插件列表信息 eg: http://rem-core-plugins-registry.moeci.com/?query=xxx
- IList remotePluginIds = new List();
-
- // 3. 根据本地已有 PluginId 插件情况 状态赋值
- PluginConfigModel pluginConfigModel = PluginConfigModelFactory.Create();
- // IList localPluginIds = pluginConfigModel.EnabledPlugins.Concat(pluginConfigModel.DisabledPlugins).Concat(pluginConfigModel.UninstalledPlugins).ToList();
- IList localPluginIds = PluginPathProvider.AllPluginFolderName();
-
- responseDTO.Code = 1;
- responseDTO.Message = "获取远程插件数据成功";
- responseDTO.Data = pluginRegistryModels;
- }
- catch (Exception ex)
- {
- responseDTO.Code = -1;
- responseDTO.Message = "获取远程插件数据失败: " + ex.Message;
- responseDTO.Data = pluginRegistryModels;
- }
-
- return await Task.FromResult(responseDTO);
- }
-
- #endregion 插件列表
-
- #region 下载插件
-
- [HttpGet, HttpPost]
- public async Task> DownloadPlugin(string pluginDownloadUrl = "")
- {
- BaseResponseModel responseDTO = new BaseResponseModel();
-
- #region 效验
-
- if (string.IsNullOrEmpty(pluginDownloadUrl))
- {
- responseDTO.Code = -1;
- responseDTO.Message = "插件下载地址不正确";
- return responseDTO;
- }
- // TODO: 效验是否本地已经存在相同pluginId的插件
-
- #endregion 效验
-
- try
- {
- // 1.执行下载操作, TODO:存在问题,阻塞对性能不好,但不阻塞又不好通知用户插件下载进度,以及可能存在在插件下载过程中,用户再次点击下载
- WebClient webClient = new WebClient();
- // TODO: 插件下载文件路径
- string pluginDownloadFilePath = "";
- //webClient.DownloadFileAsync(new Uri(pluginDownloadFilePath), "");
- Task task = webClient.DownloadFileTaskAsync(pluginDownloadUrl, pluginDownloadFilePath);
-
- _pluginDownloadTasks.Add(pluginDownloadUrl, task);
-
- webClient.DownloadFileCompleted += Plugin_DownloadFileCompleted;
- webClient.DownloadProgressChanged += Plugin_DownloadProgressChanged;
- webClient.Disposed += WebClient_Disposed;
-
- responseDTO.Code = 1;
- responseDTO.Message = "开始下载插件";
- }
- catch (Exception ex)
- {
- responseDTO.Code = -1;
- responseDTO.Message = "下载插件失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseDTO);
- }
-
- #endregion 下载插件
-
- #region 获取插件下载进度
-
- [HttpGet, HttpPost]
- public async Task> DownloadPluginProgress()
- {
- BaseResponseModel responseDTO = new BaseResponseModel();
- try
- {
- responseDTO.Data = new { };
-
- responseDTO.Code = 1;
- responseDTO.Message = "获取插件下载进度成功";
- }
- catch (Exception ex)
- {
- responseDTO.Code = -1;
- responseDTO.Message = "获取插件下载进度失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseDTO);
- }
-
- #endregion 获取插件下载进度
-
- #endregion Actions
-
- #region Helpers
-
- ///
- /// 插件下载完成
- ///
- ///
- ///
- private void Plugin_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
- {
- Console.WriteLine("插件下载完成");
- // 1.从 _pluginDownloadTasks 中移除
- //_pluginDownloadTasks.Remove();
- // 2. 解压插件
- }
-
- private void Plugin_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
- {
- Console.WriteLine($"插件下载进度改变: {e.ProgressPercentage}% {e.BytesReceived}/{e.TotalBytesToReceive}");
- }
-
- private void WebClient_Disposed(object sender, EventArgs e)
- {
- if (sender is WebClient webClient)
- {
- Console.WriteLine(webClient.BaseAddress);
- }
-
- Console.WriteLine(nameof(WebClient_Disposed) + ": " + sender.ToString());
- }
-
- #endregion Helpers
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/DebugController.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/DebugController.cs
deleted file mode 100644
index 94c34ae9..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/DebugController.cs
+++ /dev/null
@@ -1,268 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using PluginCore.AspNetCore.Extensions;
-using PluginCore.AspNetCore.ResponseModel;
-using PluginCore.Interfaces;
-using System.Runtime.Loader;
-
-namespace PluginCore.AspNetCore.Controllers;
-
-///
-/// [ASP.NET Core — 依赖注入\_啊晚的博客-CSDN博客\_asp.net core 依赖注入](https://blog.csdn.net/weixin_37648525/article/details/127942292)
-/// [ASP.NET Core中的依赖注入(3): 服务的注册与提供 - Artech - 博客园](https://www.cnblogs.com/artech/p/asp-net-core-di-register.html)
-/// [ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【总体设计 】 - Artech - 博客园](https://www.cnblogs.com/artech/p/asp-net-core-di-service-provider-1.html)
-/// [dotnet/ServiceProvider.cs at main · dotnet/dotnet](https://github.com/dotnet/dotnet/blob/main/src/runtime/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs)
-/// [Net6 DI源码分析Part2 Engine,ServiceProvider - 一身大膘 - 博客园](https://www.cnblogs.com/hts92/p/15800990.html)
-/// [【特别的骚气】asp.net core运行时注入服务,实现类库热插拔 - 四处观察 - 博客园](https://www.cnblogs.com/1996-Chinese-Chen/p/16154218.html)
-///
-/// ActivatorUtilities.CreateInstance(serviceProvider, "test");
-/// ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider);
-///
-[Route("api/plugincore/admin/[controller]/[action]")]
-//[PluginCoreAdminAuthorize]
-[ApiController]
-[NonUnify]
-public class DebugController : ControllerBase
-{
- #region Fields
-
- private readonly IPluginContextManager _pluginContextManager;
-
- #endregion Fields
-
- #region Ctor
-
- public DebugController(IPluginContextManager pluginContextManager)
- {
- _pluginContextManager = pluginContextManager;
- }
-
- #endregion Ctor
-
- #region Actions
-
- [HttpGet, HttpPost]
- public async Task> PluginContexts()
- {
- BaseResponseModel responseModel = new BaseResponseModel();
- try
- {
- var pluginContextList = _pluginContextManager.All();
- Dictionary> keyValuePairs = new Dictionary>();
- foreach (var pluginContext in pluginContextList)
- {
- keyValuePairs.Add($"{pluginContext.GetType().ToString()} - {pluginContext.PluginId} - {pluginContext.GetHashCode()}", pluginContext.Assemblies.Select(m => m.FullName).ToList());
- }
-
- responseModel.Code = 1;
- responseModel.Message = "success";
- responseModel.Data = keyValuePairs;
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "error";
- responseModel.Data = ex.ToString();
- }
-
- return await Task.FromResult(responseModel);
- }
-
- [HttpGet, HttpPost]
- public async Task> AssemblyLoadContexts()
- {
- BaseResponseModel responseModel = new BaseResponseModel();
- try
- {
- var assemblyLoadContextDefault = AssemblyLoadContext.Default;
- var assemblyLoadContextAll = AssemblyLoadContext.All;
- var responseDataModel = new AssemblyLoadContextsResponseDataModel();
- responseDataModel.Default = new AssemblyLoadContextsResponseDataModel.AssemblyLoadContextModel
- {
- Name = assemblyLoadContextDefault.Name,
- Type = assemblyLoadContextDefault.GetType().ToString(),
- Assemblies = assemblyLoadContextDefault.Assemblies.Select(m => new AssemblyModel { FullName = m.FullName, DefinedTypes = m.DefinedTypes.Select(m => m.FullName).ToList() }).ToList()
- };
- responseDataModel.All = assemblyLoadContextAll.Select(item => new AssemblyLoadContextsResponseDataModel.AssemblyLoadContextModel
- {
- Name = item.Name,
- Type = item.GetType().ToString(),
- Assemblies = item.Assemblies.Select(m => new AssemblyModel { FullName = m.FullName, DefinedTypes = m.DefinedTypes.Select(m => m.FullName).ToList() }).ToList()
- }).ToList();
-
- responseModel.Code = 1;
- responseModel.Message = "success";
- responseModel.Data = responseDataModel;
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "error";
- responseModel.Data = ex.ToString();
- }
-
- return await Task.FromResult(responseModel);
- }
-
- [HttpGet, HttpPost]
- public async Task> Assemblies()
- {
- BaseResponseModel responseModel = new BaseResponseModel();
- try
- {
- var assemblies = AppDomain.CurrentDomain.GetAssemblies();
- List assemblyModels = new List();
- foreach (var item in assemblies)
- {
- assemblyModels.Add(new AssemblyModel
- {
- FullName = item.FullName,
- DefinedTypes = item.DefinedTypes.Select(m => m.FullName).ToList()
- });
- }
-
- responseModel.Code = 1;
- responseModel.Message = "success";
- responseModel.Data = assemblyModels;
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "error";
- responseModel.Data = ex.ToString();
- }
-
- return await Task.FromResult(responseModel);
- }
-
- [HttpGet, HttpPost]
- public async Task> Services([FromServices] IServiceProvider serviceProvider)
- {
- BaseResponseModel responseModel = new BaseResponseModel();
- try
- {
- //IServiceProvider serviceProvider = HttpContext.RequestServices;
- //var provider = serviceProvider.GetType().GetProperty("RootProvider", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
- //var serviceField = provider.GetType().GetField("_realizedServices", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
- //var serviceValue = serviceField.GetValue(provider);
- //var funcType = serviceField.FieldType.GetGenericArguments()[1].GetGenericArguments()[0];
- //ConcurrentDictionary> realizedServices = (ConcurrentDictionary>)serviceValue;
-
- // 获取所有已经注册的服务
- var allService = serviceProvider.GetAllServiceDescriptors();
-
- List serviceModels = new List();
- foreach (var item in allService)
- {
- serviceModels.Add(new ServiceModel
- {
- Type = item.Key.ToString(),
- ImplementationType = item.Value.ImplementationType?.ToString() ?? "",
- Lifetime = item.Value.Lifetime.ToString(),
- TypeAssembly = new AssemblyModel
- {
- FullName = item.Key.Assembly.FullName,
- },
- ImplementationTypeAssembly = new AssemblyModel
- {
- FullName = item.Value.ImplementationType?.Assembly?.FullName ?? ""
- }
- });
- }
-
- responseModel.Code = 1;
- responseModel.Message = "success";
- responseModel.Data = serviceModels;
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "error";
- responseModel.Data = ex.ToString();
- }
-
- return await Task.FromResult(responseModel);
- }
-
- #endregion Actions
-
- public sealed class AssemblyLoadContextsResponseDataModel
- {
- public AssemblyLoadContextModel Default
- {
- get; set;
- }
-
- public List All
- {
- get; set;
- }
-
- public sealed class AssemblyLoadContextModel
- {
- public string Name
- {
- get; set;
- }
-
- public string Type
- {
- get; set;
- }
-
- public List Assemblies
- {
- get; set;
- }
- }
- }
-
- public sealed class AssembliesResponseDataModel
- {
- }
-
- public sealed class ServiceModel
- {
- public string Type
- {
- get; set;
- }
-
- public string ImplementationType
- {
- get; set;
- }
-
- public string Lifetime
- {
- get; set;
- }
-
- public AssemblyModel TypeAssembly
- {
- get; set;
- }
-
- public AssemblyModel ImplementationTypeAssembly
- {
- get; set;
- }
- }
-
- public sealed class AssemblyModel
- {
- public string FullName
- {
- get; set;
- }
-
- public List DefinedTypes
- {
- get; set;
- }
- }
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/PluginWidgetController.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/PluginWidgetController.cs
deleted file mode 100644
index b876ee2b..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/PluginWidgetController.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using PluginCore.AspNetCore.ResponseModel;
-using PluginCore.Interfaces;
-using PluginCore.IPlugins;
-
-namespace PluginCore.AspNetCore.Controllers;
-
-[Route("api/plugincore/[controller]/[action]")]
-[ApiController]
-[NonUnify]
-public class PluginWidgetController : ControllerBase
-{
- #region Fields
-
- private readonly IPluginFinder _pluginFinder;
-
- #endregion Fields
-
- #region Ctor
-
- public PluginWidgetController(IPluginFinder pluginFinder)
- {
- _pluginFinder = pluginFinder;
- }
-
- #endregion Ctor
-
- #region Actions
-
- #region Widget
-
- ///
- /// Widget
- ///
- ///
- [HttpGet, HttpPost]
- public async Task Widget(string widgetKey, string extraPars = "")
- {
- BaseResponseModel responseModel = new ResponseModel.BaseResponseModel();
- string responseData = "";
- widgetKey = widgetKey.Trim('"', '\'');
- string[] extraParsArr = null;
- if (!string.IsNullOrEmpty(extraPars))
- {
- extraParsArr = extraPars.Split(",", StringSplitOptions.RemoveEmptyEntries);
- extraParsArr = extraParsArr.Select(m => m.Trim('"', '\'')).ToArray();
- }
- StringBuilder sb = new StringBuilder();
- sb.AppendLine($"");
- try
- {
- List plugins = this._pluginFinder.EnablePlugins().ToList();
- foreach (var item in plugins)
- {
- string widgetStr = await item.Widget(widgetKey, extraParsArr);
- if (!string.IsNullOrEmpty(widgetStr))
- {
- // TODO: 配合 PluginCoreConfig.PluginWidgetDebug
- // TODO: PluginCoreConfig 改为 Options 模式, 避免手动反复读取文件 效率低
- //sb.AppendLine($"");
-
- sb.AppendLine(widgetStr);
- }
- }
- }
- catch (Exception ex)
- {
- Utils.LogUtil.Error(ex.ToString());
- sb.AppendLine($"");
- }
- sb.AppendLine($"");
- responseData = sb.ToString();
-
- responseModel.Code = 1;
- responseModel.Message = "Load Widget Success";
- responseModel.Data = responseData;
-
- //return await Task.FromResult(responseModel);
- return Content(responseData, "text/html;charset=utf-8");
- }
-
- #endregion Widget
-
- #endregion Actions
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/PluginsController.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/PluginsController.cs
deleted file mode 100644
index e23be0a0..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/PluginsController.cs
+++ /dev/null
@@ -1,709 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using PluginCore.AspNetCore.Interfaces;
-using PluginCore.AspNetCore.ResponseModel;
-using PluginCore.Infrastructure;
-using PluginCore.Interfaces;
-using PluginCore.IPlugins;
-using PluginCore.Models;
-
-namespace PluginCore.AspNetCore.Controllers;
-
-[Route("api/plugincore/admin/[controller]/[action]")]
-// [PluginCoreAdminAuthorize]
-[ApiController]
-[NonUnify]
-public class PluginsController : ControllerBase
-{
- #region Fields
-
- private readonly IPluginManager _pluginManager;
- private readonly IPluginFinder _pluginFinder;
- private readonly IPluginApplicationBuilderManager _pluginApplicationBuilderManager;
-
- #endregion Fields
-
- #region Ctor
-
- public PluginsController(IPluginManager pluginManager, IPluginFinder pluginFinder, IPluginApplicationBuilderManager pluginApplicationBuilderManager)
- {
- _pluginManager = pluginManager;
- _pluginFinder = pluginFinder;
- _pluginApplicationBuilderManager = pluginApplicationBuilderManager;
- }
-
- #endregion Ctor
-
- #region Actions
-
- #region 插件列表
-
- ///
- /// 加载插件列表
- ///
- /// 插件状态
- ///
- [HttpGet, HttpPost]
- public async Task> List(string status = "all")
- {
- BaseResponseModel responseData = new ResponseModel.BaseResponseModel();
- var pluginConfigModel = PluginConfigModelFactory.Create();
-
- // 获取所有插件信息
- IList pluginInfoModels = PluginInfoModelFactory.CreateAll();
- IList responseModels = new List();
- string[] enablePluginIds = _pluginFinder.EnablePluginIds().ToArray();
-
- // 添加插件状态
- responseModels = PluginInfoModelToResponseModel(pluginInfoModels, pluginConfigModel, enablePluginIds);
-
- #region 筛选插件状态
-
- switch (status.ToLower())
- {
- case "all":
- break;
-
- case "enabled":
- responseModels = responseModels.Where(m => m.Status == PluginStatus.Enabled).ToList();
- break;
-
- case "disabled":
- responseModels = responseModels.Where(m => m.Status == PluginStatus.Disabled).ToList();
- break;
-
- default:
- break;
- }
-
- #endregion 筛选插件状态
-
- responseData.Code = 1;
- responseData.Message = "加载插件列表成功";
- responseData.Data = responseModels;
-
- return await Task.FromResult(responseData);
- }
-
- #endregion 插件列表
-
- #region 卸载插件
-
- [HttpGet, HttpPost]
- public async Task> Uninstall(string pluginId)
- {
- BaseResponseModel responseData = new BaseResponseModel();
- pluginId = pluginId.Trim();
- var pluginConfigModel = PluginConfigModelFactory.Create();
- // 卸载插件 必须 先禁用插件
-
- #region 效验
-
- if (pluginConfigModel.EnabledPlugins.Contains(pluginId))
- {
- responseData.Code = -1;
- responseData.Message = "卸载失败: 请先禁用此插件";
- return await Task.FromResult(responseData);
- }
- string pluginDirStr = Path.Combine(PluginPathProvider.PluginsRootPath(), pluginId);
- string pluginWwwrootDirStr = Path.Combine(PluginPathProvider.PluginsWwwRootDir(), pluginId);
- if (!Directory.Exists(pluginDirStr) && !Directory.Exists(pluginWwwrootDirStr))
- {
- responseData.Code = -2;
- responseData.Message = "卸载失败: 此插件不存在";
- return await Task.FromResult(responseData);
- }
-
- #endregion 效验
-
- try
- {
- // PS:卸载插件必须先禁用插件,所以此时插件LoadContext已被移除释放(插件Assemblies已被释放), 此处不需移除LoadContext
-
- // 1.删除物理文件
- var pluginDir = new DirectoryInfo(pluginDirStr);
- if (pluginDir.Exists)
- {
- pluginDir.Delete(true);
- }
- // 虽然 已禁用 时 pluginWwwrootDirStr/pluginId 已删除, 但为确保, 还是再删除一次
- var pluginWwwrootDir = new DirectoryInfo(pluginWwwrootDirStr);
- if (pluginWwwrootDir.Exists)
- {
- pluginWwwrootDir.Delete(true);
- }
-
- responseData.Code = 1;
- responseData.Message = "卸载成功";
- }
- catch (Exception ex)
- {
- responseData.Code = -1;
- responseData.Message = "卸载失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseData);
- }
-
- #endregion 卸载插件
-
- #region 启用插件
-
- [HttpGet, HttpPost]
- public async Task> Enable(string pluginId)
- {
- BaseResponseModel responseData = new BaseResponseModel();
- var pluginConfigModel = PluginConfigModelFactory.Create();
- // 效验是否存在于 已禁用插件列表
-
- #region 效验
-
- pluginId = pluginId.Trim();
- var pluginDir = new DirectoryInfo(Path.Combine(PluginPathProvider.PluginsRootPath(), pluginId));
- if (pluginDir != null && !pluginDir.Exists)
- {
- responseData.Code = -1;
- responseData.Message = "启用失败: 此插件不存在";
- return await Task.FromResult(responseData);
- }
- string[] enablePluginIds = _pluginFinder.EnablePluginIds().ToArray();
- if (enablePluginIds.Contains(pluginId))
- {
- responseData.Code = -2;
- responseData.Message = "启用失败: 此插件已启用";
- return await Task.FromResult(responseData);
- }
-
- #endregion 效验
-
- try
- {
- // 1. 创建插件程序集加载上下文, 添加到 PluginsLoadContexts
- _pluginManager.LoadPlugin(pluginId);
- // 2. 添加到 pluginConfigModel.EnabledPlugins
- pluginConfigModel.EnabledPlugins.Add(pluginId);
- // 4.保存到 plugin.config.json
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- // 5. 找到此插件实例
- IPlugin plugin = _pluginFinder.Plugin(pluginId);
- if (plugin == null)
- {
- // 7.启用不成功, 回滚插件状态: (1)释放插件上下文 (2)更新 plugin.config.json
- try
- {
- _pluginManager.UnloadPlugin(pluginId);
- }
- catch (Exception ex)
- { }
-
- // 从 pluginConfigModel.EnabledPlugins 移除
- pluginConfigModel.EnabledPlugins.Remove(pluginId);
- // 保存到 plugin.config.json
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- responseData.Code = -1;
- responseData.Message = "启用失败: 此插件不存在";
- return await Task.FromResult(responseData);
- }
- // 6.调取插件的 AfterEnable(), 插件开发者可在此回收资源
- var pluginEnableResult = plugin.AfterEnable();
- if (!pluginEnableResult.IsSuccess)
- {
- // 7.启用不成功, 回滚插件状态: (1)释放插件上下文 (2)更新 plugin.config.json
- try
- {
- _pluginManager.UnloadPlugin(pluginId);
- }
- catch (Exception ex)
- { }
-
- // 从 pluginConfigModel.EnabledPlugins 移除
- pluginConfigModel.EnabledPlugins.Remove(pluginId);
- // 保存到 plugin.config.json
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- responseData.Code = -1;
- responseData.Message = "启用失败: 来自插件的错误信息: " + pluginEnableResult.Message;
- return await Task.FromResult(responseData);
- }
-
- // 7. ReBuild
- this._pluginApplicationBuilderManager.ReBuild();
-
- // 8. 尝试复制 插件下的 wwwroot 到 Plugins_wwwroot
- string wwwRootDir = PluginPathProvider.WwwRootDir(pluginId);
- if (Directory.Exists(wwwRootDir))
- {
- string targetDir = PluginPathProvider.PluginWwwRootDir(pluginId);
- Utils.FileUtil.CopyFolder(wwwRootDir, targetDir);
- }
-
- responseData.Code = 1;
- responseData.Message = "启用成功";
- }
- catch (Exception ex)
- {
- responseData.Code = -2;
- responseData.Message = "启用失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseData);
- }
-
- #endregion 启用插件
-
- #region 禁用插件
-
- [HttpGet, HttpPost]
- public async Task> Disable(string pluginId)
- {
- BaseResponseModel responseData = new BaseResponseModel();
-
- #region 效验
-
- pluginId = pluginId.Trim();
- var pluginConfigModel = PluginConfigModelFactory.Create();
- // string[] enablePluginIds = _pluginFinder.EnablePluginIds().ToArray();
- // // 效验是否存在于 已启用插件列表
- // if (!enablePluginIds.Contains(pluginId))
- // {
- // responseData.Code = -1;
- // responseData.Message = "禁用失败: 此插件不存在, 或未启用";
- // return await Task.FromResult(responseData);
- // }
-
- #endregion 效验
-
- try
- {
- // 1. 找到此插件实例
- IPlugin plugin = _pluginFinder.Plugin(pluginId);
- if (plugin == null)
- {
- responseData.Code = -1;
- responseData.Message = "禁用失败: 此插件不存在, 或未启用";
- return await Task.FromResult(responseData);
- }
- try
- {
- // 2.调取插件的 BeforeDisable(), 插件开发者可在此回收资源
- var pluginDisableResult = plugin.BeforeDisable();
- if (!pluginDisableResult.IsSuccess)
- {
- responseData.Code = -1;
- responseData.Message = "禁用失败: 来自插件的错误信息: " + pluginDisableResult.Message;
- return await Task.FromResult(responseData);
- }
- // 3.移除插件对应的程序集加载上下文
- _pluginManager.UnloadPlugin(pluginId);
- // 3.1. ReBuild
- this._pluginApplicationBuilderManager.ReBuild();
- if (pluginConfigModel.EnabledPlugins.Contains(pluginId))
- {
- // 4.从 pluginConfigModel.EnabledPlugins 移除
- pluginConfigModel.EnabledPlugins.Remove(pluginId);
- // 5.保存到 plugin.config.json
- PluginConfigModelFactory.Save(pluginConfigModel);
- }
- }
- catch (Exception ex)
- {
- //Utils.LogUtil.Error(ex.ToString());
- responseData.Code = -1;
- responseData.Message = "禁用失败: 此插件不存在, 或未启用";
- return await Task.FromResult(responseData);
- }
-
- // 7. 尝试移除 Plugins_wwwroot/PluginId
- string pluginWwwRootDir = PluginPathProvider.PluginWwwRootDir(pluginId);
- if (Directory.Exists(pluginWwwRootDir))
- {
- Directory.Delete(pluginWwwRootDir, true);
- }
-
- responseData.Code = 1;
- responseData.Message = "禁用成功";
- }
- catch (Exception ex)
- {
- responseData.Code = -2;
- responseData.Message = "禁用失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseData);
- }
-
- #endregion 禁用插件
-
- #region 上传插件
-
- ///
- /// 上传插件
- ///
- /// 注意: 参数名一定为 file, 对应前端传过来时以 file 为名
- ///
- [HttpGet, HttpPost]
- public async Task> Upload(IFormFile file)
- {
- BaseResponseModel responseData = new BaseResponseModel();
-
- #region 效验
-
- if (file == null)
- {
- responseData.Code = -1;
- responseData.Message = "上传的文件不能为空";
- return responseData;
- }
- //文件后缀
- string fileExtension = Path.GetExtension(file.FileName);//获取文件格式,拓展名
- // 类型标记
- UploadFileType uploadFileType = UploadFileType.NoAllowedType;
- switch (fileExtension)
- {
- case ".zip":
- uploadFileType = UploadFileType.Zip;
- break;
-
- case ".nupkg":
- uploadFileType = UploadFileType.Nupkg;
- break;
- }
-
- if (fileExtension != ".zip" && fileExtension != ".nupkg")
- {
- responseData.Code = -1;
- // nupkg 其实就是 zip
- responseData.Message = "只能上传 zip 或 nupkg 格式文件";
- return responseData;
- }
- // PluginCore.AspNetCore-v1.0.2 起 不再限制插件上传大小
- //判断文件大小
- //var fileSize = file.Length;
- //if (fileSize > 1024 * 1024 * 5) // 5M
- //{
- // responseData.Code = -1;
- // responseData.Message = "上传的文件不能大于5MB";
- // return responseData;
- //}
-
- #endregion 效验
-
- try
- {
- // 1.先上传到 临时插件上传目录, 用Guid.zip作为保存文件名
- string tempZipFilePath = Path.Combine(PluginPathProvider.TempPluginUploadDir(), Guid.NewGuid() + ".zip");
- using (var fs = System.IO.File.Create(tempZipFilePath))
- {
- file.CopyTo(fs); //将上传的文件文件流,复制到fs中
- fs.Flush();//清空文件流
- }
- // 2.解压
- bool isDecomparessSuccess = false;
- if (uploadFileType == UploadFileType.Zip)
- {
- isDecomparessSuccess = Utils.ZipHelper.DecomparessFile(tempZipFilePath, tempZipFilePath.Replace(".zip", ""));
- }
- else if (uploadFileType == UploadFileType.Nupkg)
- {
- isDecomparessSuccess = NupkgService.DecomparessFile(tempZipFilePath, tempZipFilePath.Replace(".zip", ""));
- }
-
- // 3.删除原压缩包
- System.IO.File.Delete(tempZipFilePath);
- if (!isDecomparessSuccess)
- {
- responseData.Code = -1;
- responseData.Message = "解压插件压缩包失败";
- return responseData;
- }
- // 4.读取其中的info.json, 获取 PluginId 值
- PluginInfoModel pluginInfoModel = PluginInfoModelFactory.ReadPluginDir(tempZipFilePath.Replace(".zip", ""));
- if (pluginInfoModel == null || string.IsNullOrEmpty(pluginInfoModel.PluginId))
- {
- // 记得删除已不再需要的临时插件文件夹
- Directory.Delete(tempZipFilePath.Replace(".zip", ""), true);
-
- responseData.Code = -1;
- responseData.Message = "不合法的插件";
- return responseData;
- }
- string pluginId = pluginInfoModel.PluginId;
- // 5.检索 此 PluginId 是否本地插件已存在
- var pluginConfigModel = PluginConfigModelFactory.Create();
- // 本地已经存在的 PluginId
- IList localExistPluginIds = PluginPathProvider.AllPluginFolderName();
- if (localExistPluginIds.Contains(pluginId))
- {
- // 记得删除已不再需要的临时插件文件夹
- Directory.Delete(tempZipFilePath.Replace(".zip", ""), true);
-
- responseData.Code = -1;
- responseData.Message = $"本地已有此插件 (PluginId: {pluginId}), 请前往插件列表删除后, 再上传";
- return responseData;
- }
- // 6.本地无此插件 -> 移动插件文件夹到 Plugins 下, 并以 PluginId 为插件文件夹名
- string pluginsRootPath = PluginPathProvider.PluginsRootPath();
- string newPluginDir = Path.Combine(pluginsRootPath, pluginId);
- Directory.Move(tempZipFilePath.Replace(".zip", ""), newPluginDir);
-
- // 7. 放入 Plugins 中, 默认为 已禁用
-
- responseData.Code = 1;
- responseData.Message = $"上传插件成功 (PluginId: {pluginId})";
- }
- catch (Exception ex)
- {
- responseData.Code = -1;
- responseData.Message = "上传插件失败: " + ex.Message;
- ex = ex.InnerException;
- while (ex != null)
- {
- responseData.Message += " - " + ex.InnerException.Message;
- ex = ex.InnerException;
- }
- }
-
- return await Task.FromResult(responseData);
- }
-
- #endregion 上传插件
-
- #region 查看详细
-
- [HttpGet, HttpPost]
- public async Task> Details(string pluginId)
- {
- BaseResponseModel responseData = new BaseResponseModel();
-
- try
- {
- #region 效验
-
- pluginId = pluginId.Trim();
- var pluginConfigModel = PluginConfigModelFactory.Create();
- string[] localPluginIds = PluginPathProvider.AllPluginFolderName().ToArray();
-
- if (!localPluginIds.Contains(pluginId))
- {
- responseData.Code = -1;
- responseData.Message = $"查看详细失败: 不存在 {pluginId} 插件";
- return await Task.FromResult(responseData);
- }
-
- #endregion 效验
-
- PluginInfoModel pluginInfoModel = PluginInfoModelFactory.Create(pluginId);
- string[] enablePluginIds = _pluginFinder.EnablePluginIds().ToArray();
- PluginInfoResponseModel pluginInfoResponseModel = PluginInfoModelToResponseModel(new List() { pluginInfoModel }, pluginConfigModel, enablePluginIds).FirstOrDefault();
-
- responseData.Code = 1;
- responseData.Message = "查看详细成功";
- responseData.Data = pluginInfoResponseModel;
- }
- catch (Exception ex)
- {
- responseData.Code = -1;
- responseData.Message = "查看详细失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseData);
- }
-
- #endregion 查看详细
-
- #region 查看文档
-
- [HttpGet, HttpPost]
- public async Task> Readme(string pluginId)
- {
- BaseResponseModel responseData = new BaseResponseModel();
-
- try
- {
- #region 效验
-
- pluginId = pluginId.Trim();
- // var pluginConfigModel = PluginConfigModelFactory.Create();
- string[] localPluginIds = PluginPathProvider.AllPluginFolderName().ToArray();
-
- if (!localPluginIds.Contains(pluginId))
- {
- responseData.Code = -1;
- responseData.Message = $"查看文档失败: 不存在 {pluginId} 插件";
- return await Task.FromResult(responseData);
- }
-
- #endregion 效验
-
- PluginReadmeModel readmeModel = PluginReadmeModelFactory.Create(pluginId);
- PluginReadmeResponseModel readmeResponseModel = new PluginReadmeResponseModel();
- readmeResponseModel.Content = readmeModel?.Content ?? "";
- readmeResponseModel.PluginId = pluginId;
-
- responseData.Code = 1;
- responseData.Message = "查看文档成功";
- responseData.Data = readmeResponseModel;
- }
- catch (Exception ex)
- {
- responseData.Code = -1;
- responseData.Message = "查看文档失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseData);
- }
-
- #endregion 查看文档
-
- #region 设置
-
- [HttpGet]
- public async Task> Settings(string pluginId)
- {
- BaseResponseModel responseData = new BaseResponseModel();
-
- try
- {
- #region 效验
-
- pluginId = pluginId.Trim();
- // var pluginConfigModel = PluginConfigModelFactory.Create();
- string[] localPluginIds = PluginPathProvider.AllPluginFolderName().ToArray();
-
- if (!localPluginIds.Contains(pluginId))
- {
- responseData.Code = -1;
- responseData.Message = $"查看设置失败: 不存在 {pluginId} 插件";
- return await Task.FromResult(responseData);
- }
-
- #endregion 效验
-
- string settingsJsonStr = PluginSettingsModelFactory.Create(pluginId);
-
- responseData.Code = 1;
- responseData.Message = "查看设置成功";
- responseData.Data = settingsJsonStr ?? "无设置项";
- }
- catch (Exception ex)
- {
- responseData.Code = -1;
- responseData.Message = "查看设置失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseData);
- }
-
- [HttpPost]
- public async Task> Settings(PluginSettingsInputModel inputModel)
- {
- BaseResponseModel responseData = new BaseResponseModel();
-
- try
- {
- #region 效验
-
- inputModel.PluginId = inputModel.PluginId.Trim();
- // var pluginConfigModel = PluginConfigModelFactory.Create();
- string[] localPluginIds = PluginPathProvider.AllPluginFolderName().ToArray();
-
- if (!localPluginIds.Contains(inputModel.PluginId))
- {
- responseData.Code = -1;
- responseData.Message = $"设置失败: 不存在 {inputModel.PluginId} 插件";
- return await Task.FromResult(responseData);
- }
-
- #endregion 效验
-
- inputModel.Data = inputModel.Data ?? "";
- PluginSettingsModelFactory.Save(pluginSettingsJsonStr: inputModel.Data, pluginId: inputModel.PluginId);
-
- responseData.Code = 1;
- responseData.Message = "设置成功";
- responseData.Data = inputModel.Data;
- }
- catch (Exception ex)
- {
- responseData.Code = -1;
- responseData.Message = "设置失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseData);
- }
-
- #endregion 设置
-
- #endregion Actions
-
- #region Helpers
-
- [NonAction]
- private IList PluginInfoModelToResponseModel(IList pluginInfoModels, PluginConfigModel pluginConfigModel, string[] enablePluginIds)
- {
- // 获取 Plugins 下所有插件
- // DirectoryInfo pluginsDir = new DirectoryInfo(PluginPathProvider.PluginsRootPath());
- // List pluginIds = pluginsDir?.GetDirectories()?.Select(m => m.Name)?.ToList() ?? new List();
-
- IList responseModels = new List();
-
- #region 添加插件状态信息
-
- foreach (var model in pluginInfoModels)
- {
- PluginInfoResponseModel responseModel = new PluginInfoResponseModel();
- responseModel.Author = model.Author;
- responseModel.Description = model.Description;
- responseModel.DisplayName = model.DisplayName;
- responseModel.PluginId = model.PluginId;
- responseModel.SupportedVersions = model.SupportedVersions;
- responseModel.Version = model.Version;
- responseModel.DependPlugins = model.DependPlugins;
-
- if (pluginConfigModel.EnabledPlugins.Contains(model.PluginId) && !enablePluginIds.Contains(model.PluginId))
- {
- // 错误情况: 配置 标识 已启用, 但实际没有启用成功
- pluginConfigModel.EnabledPlugins.Remove(model.PluginId);
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- responseModel.Status = PluginStatus.Disabled;
- }
- else if (!pluginConfigModel.EnabledPlugins.Contains(model.PluginId) && enablePluginIds.Contains(model.PluginId))
- {
- // 错误情况: 配置没有标识 已启用, 但实际 已启用
- pluginConfigModel.EnabledPlugins.Add(model.PluginId);
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- responseModel.Status = PluginStatus.Enabled;
- }
- else if (pluginConfigModel.EnabledPlugins.Contains(model.PluginId) && enablePluginIds.Contains(model.PluginId))
- {
- responseModel.Status = PluginStatus.Enabled;
- }
- else
- {
- responseModel.Status = PluginStatus.Disabled;
- }
- responseModels.Add(responseModel);
- }
-
- #endregion 添加插件状态信息
-
- return responseModels;
- }
-
- public enum UploadFileType
- {
- NoAllowedType = 0,
- Zip = 1,
- Nupkg = 2
- }
-
- #endregion Helpers
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/UserController.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/UserController.cs
deleted file mode 100644
index 70a8b09a..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Controllers/UserController.cs
+++ /dev/null
@@ -1,181 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using Furion.DataEncryption;
-using Microsoft.AspNetCore.Authorization;
-using PluginCore.AspNetCore.RequestModel.User;
-using PluginCore.AspNetCore.ResponseModel;
-using PluginCore.Config;
-
-
-namespace PluginCore.AspNetCore.Controllers;
-
-[Route("api/plugincore/admin/[controller]/[action]")]
-[ApiController]
-[NonUnify]
-public class UserController : ControllerBase
-{
- public string RemoteFronted
- {
- get
- {
- return PluginCore.Config.PluginCoreConfigFactory.Create().RemoteFrontend;
- }
- }
-
- private readonly UserManager _userManager;
- private readonly SqlSugarRepository _sysUserRep;
- private readonly SysOrgService _sysOrgService;
- private readonly SysUserExtOrgService _sysUserExtOrgService;
- private readonly SysUserRoleService _sysUserRoleService;
- private readonly SysConfigService _sysConfigService;
-
- public UserController(UserManager userManager,
- SqlSugarRepository sysUserRep,
- SysOrgService sysOrgService,
- SysUserExtOrgService sysUserExtOrgService,
- SysUserRoleService sysUserRoleService,
- SysConfigService sysConfigService)
- {
- _userManager = userManager;
- _sysUserRep = sysUserRep;
- _sysOrgService = sysOrgService;
- _sysUserExtOrgService = sysUserExtOrgService;
- _sysUserRoleService = sysUserRoleService;
- _sysConfigService = sysConfigService;
- }
-
- ///
- /// 登录系统
- ///
- ///
- /// 用户名/密码:superadmin/123456
- ///
- [AllowAnonymous]
- [HttpGet, HttpPost]
- [DisplayName("登录系统")]
- public async Task> Login([FromBody] LoginRequestModel input)
- {
- BaseResponseModel responseModel = new BaseResponseModel();
-
- // 账号是否存在
- var user = await _sysUserRep.AsQueryable().Includes(t => t.SysOrg).Filter(null, true).FirstAsync(u => u.Account.Equals(input.UserName));
- _ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009);
-
- // 账号是否被冻结
- if (user.Status == StatusEnum.Disable)
- throw Oops.Oh(ErrorCodeEnum.D1017);
-
- // 租户是否被禁用
- var tenant = await _sysUserRep.ChangeRepository>().GetFirstAsync(u => u.Id == user.TenantId);
- if (tenant != null && tenant.Status == StatusEnum.Disable)
- throw Oops.Oh(ErrorCodeEnum.Z1003);
-
- // 密码是否正确
- if (CryptogramUtil.CryptoType == CryptogramEnum.MD5.ToString())
- {
- if (user.Password != MD5Encryption.Encrypt(input.Password))
- throw Oops.Oh(ErrorCodeEnum.D1000);
- }
- else
- {
- if (CryptogramUtil.Decrypt(user.Password) != input.Password)
- throw Oops.Oh(ErrorCodeEnum.D1000);
- }
-
- var tokenExpire = await _sysConfigService.GetTokenExpire();
- var refreshTokenExpire = await _sysConfigService.GetRefreshTokenExpire();
-
- // 生成Token令牌
- var accessToken = JWTEncryption.Encrypt(new Dictionary
- {
- { ClaimConst.UserId, user.Id },
- { ClaimConst.TenantId, user.TenantId },
- { ClaimConst.Account, user.Account },
- { ClaimConst.RealName, user.RealName },
- { ClaimConst.AccountType, user.AccountType },
- { ClaimConst.OrgId, user.OrgId },
- { ClaimConst.OrgName, user.SysOrg?.Name },
- //{ ClaimConst.OrgType, user.SysOrg?.OrgType },
- }, tokenExpire);
-
- // 生成刷新Token令牌
- var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, refreshTokenExpire);
-
- responseModel.Code = 1;
- responseModel.Message = "登录成功";
- responseModel.Data = new
- {
- token = accessToken,
- userName = user.NickName,
- RefreshToken = refreshToken
- };
- return await Task.FromResult(responseModel);
- }
-
- [HttpGet, HttpPost]
- public async Task> Logout()
- {
- BaseResponseModel responseModel = new BaseResponseModel()
- {
- Code = 1,
- Message = "退出登录成功"
- };
-
- return await Task.FromResult(responseModel);
- }
-
- [HttpGet, HttpPost]
- public async Task> Info()
- {
- BaseResponseModel responseModel = new BaseResponseModel();
-
- try
- {
- string adminUserName = PluginCoreConfigFactory.Create().Admin.UserName;
-
- responseModel.Code = 1;
- responseModel.Message = "成功";
- responseModel.Data = new
- {
- name = adminUserName,
- //avatar = this.RemoteFronted + "/images/avatar.gif"
- avatar = ""
- };
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseModel);
- }
-
- [HttpGet, HttpPost]
- public async Task> Update([FromBody] UpdateRequestModel requestModel)
- {
- BaseResponseModel responseModel = new BaseResponseModel();
-
- try
- {
- PluginCoreConfig pluginCoreConfig = PluginCoreConfigFactory.Create();
- pluginCoreConfig.Admin.UserName = requestModel.UserName;
- pluginCoreConfig.Admin.Password = requestModel.Password;
- PluginCoreConfigFactory.Save(pluginCoreConfig);
-
- responseModel.Code = 1;
- responseModel.Message = "修改成功, 需要重新登录";
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseModel);
- }
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Entity/SysPluginCore.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Entity/SysPluginCore.cs
deleted file mode 100644
index 0a6eae2c..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Entity/SysPluginCore.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-namespace Admin.NET.Plugin.PluginCore;
-
-///
-/// 系统动态插件表
-///
-[SugarTable(null, "系统动态插件表")]
-[SysTable]
-public class SysPluginCore : EntityTenant
-{
- ///
- /// 插件ID
- ///
- [SugarColumn(ColumnDescription = "插件ID", Length = 128)]
- [Required]
- public virtual string PluginId { get; set; }
-
- ///
- /// 名称
- ///
- [SugarColumn(ColumnDescription = "名称", Length = 64)]
- [Required, MaxLength(64)]
- public virtual string DisplayName { get; set; }
-
- ///
- /// 作者
- ///
- [SugarColumn(ColumnDescription = "作者", Length = 64)]
- [Required, MaxLength(64)]
- public virtual string Author { get; set; }
-
- ///
- /// 版本
- ///
- [SugarColumn(ColumnDescription = "版本", Length = 64)]
- [Required, MaxLength(64)]
- public virtual string Version { get; set; }
-
- ///
- /// 描述
- ///
- [SugarColumn(ColumnDescription = "描述", Length = 512)]
- [MaxLength(512)]
- public string? Description { get; set; }
-
- ///
- /// 排序
- ///
- [SugarColumn(ColumnDescription = "排序")]
- public int OrderNo { get; set; } = 100;
-
- ///
- /// 状态
- ///
- [SugarColumn(ColumnDescription = "状态")]
- public StatusEnum Status { get; set; } = StatusEnum.Enable;
-
- ///
- /// 备注
- ///
- [SugarColumn(ColumnDescription = "备注", Length = 128)]
- [MaxLength(128)]
- public string? Remark { get; set; }
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/GlobalUsings.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/GlobalUsings.cs
deleted file mode 100644
index 9b331497..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/GlobalUsings.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-global using Admin.NET.Core;
-global using Admin.NET.Core.Service;
-global using Furion;
-global using Furion.DependencyInjection;
-global using Furion.DynamicApiController;
-global using Furion.FriendlyException;
-global using Mapster;
-global using Microsoft.AspNetCore.Http;
-global using Microsoft.AspNetCore.Mvc;
-global using Microsoft.Extensions.DependencyInjection;
-global using Newtonsoft.Json;
-global using SqlSugar;
-global using System.ComponentModel;
-global using System.ComponentModel.DataAnnotations;
-global using System.Data;
-global using System.Linq.Dynamic.Core;
-global using System.Text;
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/SeedData/SysMenuSeedData.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/SeedData/SysMenuSeedData.cs
deleted file mode 100644
index 3e755c45..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/SeedData/SysMenuSeedData.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-namespace Admin.NET.Plugin.PluginCore;
-
-///
-/// 系统菜单表种子数据
-///
-[IncreSeed]
-public class SysMenu_PluginCore_SeedData : ISqlSugarEntitySeedData
-{
- ///
- /// 种子数据
- ///
- ///
- public IEnumerable HasData()
- {
- return
- [
- new SysMenu{ Id=1310000000802, Pid=1310000000301, Title="应用插件", Path="/platform/pluginCore", Name="sysPluginCore", Component="/system/pluginCore/index", Icon="ele-Connection", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=210 },
- new SysMenu{ Id=1310000000803, Pid=1310000000802, Title="启用", Permission="sysPluginCore/enable", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
- new SysMenu{ Id=1310000000804, Pid=1310000000802, Title="卸载", Permission="sysPluginCore/delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
- new SysMenu{ Id=1310000000805, Pid=1310000000802, Title="禁用", Permission="sysPluginCore/disable", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
- new SysMenu{ Id=1310000000806, Pid=1310000000802, Title="详细", Permission="sysPluginCore/details", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
- new SysMenu{ Id=1310000000807, Pid=1310000000802, Title="文档", Permission="sysPluginCore/readme", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=140 },
- new SysMenu{ Id=1310000000808, Pid=1310000000802, Title="设置", Permission="sysPluginCore/setting", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=150 },
- ];
- }
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Service/Plugin/Dto/PluginCoreInput.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Service/Plugin/Dto/PluginCoreInput.cs
deleted file mode 100644
index bd948bd8..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Service/Plugin/Dto/PluginCoreInput.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-namespace Admin.NET.Plugin.PluginCore;
-
-public class PagePluginCoreInput : BasePageInput
-{
- ///
- /// 名称
- ///
- public string Name { get; set; }
-
- ///
- /// 编码
- ///
- public string Code { get; set; }
-}
-
-public class AddPluginCoreInput : SysPluginCore
-{
-}
-
-public class UpdatePluginCoreInput : AddPluginCoreInput
-{
-}
-
-public class DeletePluginCoreInput : BaseIdInput
-{
-}
-
-public class EnablePluginCoreInput : BaseIdInput
-{
-}
-
-public class UpdatePluginCoreSettingInput : BaseIdInput
-{
- public string Data { get; set; }
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Service/Plugin/SysPluginCoreService.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Service/Plugin/SysPluginCoreService.cs
deleted file mode 100644
index 3c5e1814..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Service/Plugin/SysPluginCoreService.cs
+++ /dev/null
@@ -1,695 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using PluginCore;
-using PluginCore.AspNetCore.Interfaces;
-using PluginCore.AspNetCore.ResponseModel;
-using PluginCore.Infrastructure;
-using PluginCore.Interfaces;
-using PluginCore.IPlugins;
-using PluginCore.Models;
-using PluginCore.Utils;
-
-namespace Admin.NET.Plugin.PluginCore;
-
-///
-/// 系统动态插件服务
-///
-[ApiDescriptionSettings(Order = 245)]
-public class SysPluginCoreService : IDynamicApiController, ITransient
-{
- #region Fields
-
- private readonly IPluginManager _pluginManager;
- private readonly IPluginFinder _pluginFinder;
- private readonly IPluginApplicationBuilderManager _pluginApplicationBuilderManager;
-
- #endregion Fields
-
- private readonly IDynamicApiRuntimeChangeProvider _provider;
- private readonly SqlSugarRepository _sysPluginRep;
-
- public SysPluginCoreService(IPluginManager pluginManager, IPluginFinder pluginFinder, IPluginApplicationBuilderManager pluginApplicationBuilderManager, IDynamicApiRuntimeChangeProvider provider,
- SqlSugarRepository sysPluginRep)
- {
- _pluginManager = pluginManager;
- _pluginFinder = pluginFinder;
- _pluginApplicationBuilderManager = pluginApplicationBuilderManager;
- _provider = provider;
- _sysPluginRep = sysPluginRep;
- }
-
- ///
- /// 获取动态插件列表
- ///
- ///
- ///
- [DisplayName("获取动态插件列表")]
- public async Task> Page(PagePluginInput input)
- {
- return await _sysPluginRep.AsQueryable()
- .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.DisplayName.Contains(input.Name))
- .OrderBy(u => u.OrderNo)
- .ToPagedListAsync(input.Page, input.PageSize);
- }
-
- ///
- /// 查看详细
- ///
- ///
- ///
- [ApiDescriptionSettings(Name = "Details"), HttpGet]
- [DisplayName("查看详细")]
- public async Task Details(long id)
- {
- var pluginCore = await _sysPluginRep.GetByIdAsync(id);
- if (pluginCore == null) throw Oops.Oh("查询插件ID失败"); ;
-
- // 先移除再添加动态程序集/接口
-
- try
- {
- #region 效验
-
- var pluginId = pluginCore.PluginId;
- var pluginConfigModel = PluginConfigModelFactory.Create();
- string[] localPluginIds = PluginPathProvider.AllPluginFolderName().ToArray();
-
- if (!localPluginIds.Contains(pluginId))
- {
- throw Oops.Oh($"查看详细失败: 不存在 {pluginId} 插件");
- }
-
- #endregion 效验
-
- PluginInfoModel pluginInfoModel = PluginInfoModelFactory.Create(pluginId);
- string[] enablePluginIds = _pluginFinder.EnablePluginIds().ToArray();
- PluginInfoResponseModel pluginInfoResponseModel = PluginInfoModelToResponseModel(new List() { pluginInfoModel }, pluginConfigModel, enablePluginIds).FirstOrDefault();
-
- return pluginInfoResponseModel;
- }
- catch (Exception ex)
- {
- throw Oops.Oh("查看详细失败: " + ex.Message);
- }
- }
-
- #region 查看文档
-
- ///
- /// 查看文档
- ///
- ///
- ///
- [ApiDescriptionSettings(Name = "Readme"), HttpGet]
- [DisplayName("查看文档")]
- public async Task Readme(long id)
- {
- var pluginCore = await _sysPluginRep.GetByIdAsync(id);
- if (pluginCore == null) throw Oops.Oh("查询插件ID失败"); ;
-
- try
- {
- #region 效验
-
- var pluginId = pluginCore.PluginId;
- var pluginConfigModel = PluginConfigModelFactory.Create();
- string[] localPluginIds = PluginPathProvider.AllPluginFolderName().ToArray();
-
- if (!localPluginIds.Contains(pluginId))
- {
- throw Oops.Oh($"查看详细失败: 不存在 {pluginId} 插件");
- }
-
- #endregion 效验
-
- PluginReadmeModel readmeModel = PluginReadmeModelFactory.Create(pluginId);
- PluginReadmeResponseModel readmeResponseModel = new PluginReadmeResponseModel();
- readmeResponseModel.Content = readmeModel?.Content ?? "";
- readmeResponseModel.PluginId = pluginId;
-
- return readmeResponseModel;
- }
- catch (Exception ex)
- {
- throw Oops.Oh("查看详细失败: " + ex.Message);
- }
- }
-
- #endregion 查看文档
-
- ///
- /// 卸载动态插件
- ///
- ///
- ///
- [ApiDescriptionSettings(Name = "Uninstall"), HttpPost]
- [DisplayName("卸载动态插件")]
- public async Task Uninstall(DeletePluginCoreInput input)
- {
- var pluginCore = await _sysPluginRep.GetByIdAsync(input.Id);
- if (pluginCore == null) throw Oops.Oh("查询插件ID失败");
-
- // 卸载插件 必须 先禁用插件
-
- #region 效验
-
- var pluginId = pluginCore.PluginId;
- var pluginConfigModel = PluginConfigModelFactory.Create();
- if (pluginConfigModel.EnabledPlugins.Contains(pluginId))
- {
- throw Oops.Oh("卸载失败: 请先禁用此插件");
- }
- string pluginDirStr = Path.Combine(PluginPathProvider.PluginsRootPath(), pluginId);
- string pluginWwwrootDirStr = Path.Combine(PluginPathProvider.PluginsWwwRootDir(), pluginId);
- if (!Directory.Exists(pluginDirStr) && !Directory.Exists(pluginWwwrootDirStr))
- {
- throw Oops.Oh("卸载失败: 此插件不存在");
- }
-
- #endregion 效验
-
- try
- {
- // PS:卸载插件必须先禁用插件,所以此时插件LoadContext已被移除释放(插件Assemblies已被释放), 此处不需移除LoadContext
-
- // 1.删除物理文件
- var pluginDir = new DirectoryInfo(pluginDirStr);
- if (pluginDir.Exists)
- {
- pluginDir.Delete(true);
- }
- // 虽然 已禁用 时 pluginWwwrootDirStr/pluginId 已删除, 但为确保, 还是再删除一次
- var pluginWwwrootDir = new DirectoryInfo(pluginWwwrootDirStr);
- if (pluginWwwrootDir.Exists)
- {
- pluginWwwrootDir.Delete(true);
- }
-
- await _sysPluginRep.DeleteAsync(u => u.Id == input.Id);
- }
- catch (Exception ex)
- {
- throw Oops.Oh("卸载失败: " + ex.Message);
- }
- }
-
- #region 设置
-
- ///
- /// 插件设置设置
- ///
- ///
- ///
- [ApiDescriptionSettings(Name = "Settings"), HttpGet]
- [DisplayName("插件设置设置")]
- public async Task Settings(long id)
- {
- var pluginCore = await _sysPluginRep.GetByIdAsync(id);
- if (pluginCore == null) throw Oops.Oh("查询插件ID失败"); ;
-
- try
- {
- #region 效验
-
- var pluginId = pluginCore.PluginId;
- var pluginConfigModel = PluginConfigModelFactory.Create();
- string[] localPluginIds = PluginPathProvider.AllPluginFolderName().ToArray();
-
- if (!localPluginIds.Contains(pluginId))
- {
- throw Oops.Oh($"查看详细失败: 不存在 {pluginId} 插件");
- }
-
- #endregion 效验
-
- string settingsJsonStr = PluginSettingsModelFactory.Create(pluginId);
-
- return settingsJsonStr ?? "无设置项";
- }
- catch (Exception ex)
- {
- throw Oops.Oh("查看设置失败: " + ex.Message);
- }
- }
-
- ///
- /// 插件设置设置
- ///
- ///
- ///
- [ApiDescriptionSettings(Name = "Settings"), HttpPost]
- [DisplayName("插件设置设置")]
- public async Task Settings(UpdatePluginCoreSettingInput input)
- {
- var pluginCore = await _sysPluginRep.GetByIdAsync(input.Id);
- if (pluginCore == null) throw Oops.Oh("查询插件ID失败"); ;
-
- try
- {
- #region 效验
-
- var pluginId = pluginCore.PluginId;
- var pluginConfigModel = PluginConfigModelFactory.Create();
- string[] localPluginIds = PluginPathProvider.AllPluginFolderName().ToArray();
-
- if (!localPluginIds.Contains(pluginId))
- {
- throw Oops.Oh($"查看详细失败: 不存在 {pluginId} 插件");
- }
-
- #endregion 效验
-
- input.Data = input.Data ?? "";
- PluginSettingsModelFactory.Save(pluginSettingsJsonStr: input.Data, pluginId: pluginCore.PluginId);
- }
- catch (Exception ex)
- {
- throw Oops.Oh("设置失败: " + ex.Message);
- }
- }
-
- #endregion 设置
-
- ///
- /// 启用插件
- ///
- ///
- ///
- [ApiDescriptionSettings(Name = "Enable"), HttpPost]
- [DisplayName("启用插件")]
- public async Task Enable(EnablePluginCoreInput input)
- {
- var pluginCore = await _sysPluginRep.GetByIdAsync(input.Id);
- if (pluginCore == null) return;
-
- // 移除动态程序集/接口
- var pluginConfigModel = PluginConfigModelFactory.Create();
- // 效验是否存在于 已禁用插件列表
-
- #region 效验
-
- var pluginId = pluginCore.PluginId;
- var pluginDir = new DirectoryInfo(Path.Combine(PluginPathProvider.PluginsRootPath(), pluginId));
- if (pluginDir != null && !pluginDir.Exists)
- {
- throw Oops.Oh("启用失败: 此插件不存在");
- }
- string[] enablePluginIds = _pluginFinder.EnablePluginIds().ToArray();
- if (enablePluginIds.Contains(pluginId))
- {
- throw Oops.Oh("启用失败: 此插件已启用");
- }
-
- #endregion 效验
-
- try
- {
- // 1. 创建插件程序集加载上下文, 添加到 PluginsLoadContexts
- _pluginManager.LoadPlugin(pluginId);
- // 2. 添加到 pluginConfigModel.EnabledPlugins
- pluginConfigModel.EnabledPlugins.Add(pluginId);
- // 4.保存到 plugin.config.json
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- // 5. 找到此插件实例
- IPlugin plugin = _pluginFinder.Plugin(pluginId);
- if (plugin == null)
- {
- // 7.启用不成功, 回滚插件状态: (1)释放插件上下文 (2)更新 plugin.config.json
- try
- {
- _pluginManager.UnloadPlugin(pluginId);
- }
- catch (Exception ex)
- { }
-
- // 从 pluginConfigModel.EnabledPlugins 移除
- pluginConfigModel.EnabledPlugins.Remove(pluginId);
- // 保存到 plugin.config.json
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- throw Oops.Oh("启用失败: 此插件不存在");
- }
- // 6.调取插件的 AfterEnable(), 插件开发者可在此回收资源
- var pluginEnableResult = plugin.AfterEnable();
- if (!pluginEnableResult.IsSuccess)
- {
- // 7.启用不成功, 回滚插件状态: (1)释放插件上下文 (2)更新 plugin.config.json
- try
- {
- _pluginManager.UnloadPlugin(pluginId);
- }
- catch (Exception ex)
- { }
-
- // 从 pluginConfigModel.EnabledPlugins 移除
- pluginConfigModel.EnabledPlugins.Remove(pluginId);
- // 保存到 plugin.config.json
- PluginConfigModelFactory.Save(pluginConfigModel);
- throw Oops.Oh("启用失败: 来自插件的错误信息: " + pluginEnableResult.Message);
- }
-
- // 7. ReBuild
- this._pluginApplicationBuilderManager.ReBuild();
-
- // 8. 尝试复制 插件下的 wwwroot 到 Plugins_wwwroot
- string wwwRootDir = PluginPathProvider.WwwRootDir(pluginId);
- if (Directory.Exists(wwwRootDir))
- {
- string targetDir = PluginPathProvider.PluginWwwRootDir(pluginId);
- FileUtil.CopyFolder(wwwRootDir, targetDir);
- }
-
- //9.载入Furion动态插件
- var pluginMainAssembly = _pluginManager.GetPluginAssembly(pluginId);
- // 将程序集添加进动态 WebAPI 应用部件
- _provider.AddAssembliesWithNotifyChanges(pluginMainAssembly);
-
- await _sysPluginRep.UpdateAsync(u => new SysPluginCore() { Status = StatusEnum.Enable }, u => u.Id == input.Id);
- }
- catch (Exception ex)
- {
- throw Oops.Oh("启用失败: " + ex.Message);
- }
- }
-
- ///
- /// 禁用插件
- ///
- ///
- ///
- [ApiDescriptionSettings(Name = "Disable"), HttpPost]
- [DisplayName("禁用插件")]
- public async Task Disable(EnablePluginCoreInput input)
- {
- var pluginCore = await _sysPluginRep.GetByIdAsync(input.Id);
- if (pluginCore == null) return;
-
- // 移除动态程序集/
-
- #region 效验
-
- var pluginId = pluginCore.PluginId;
- var pluginConfigModel = PluginConfigModelFactory.Create();
- // string[] enablePluginIds = _pluginFinder.EnablePluginIds().ToArray();
- // // 效验是否存在于 已启用插件列表
- // if (!enablePluginIds.Contains(pluginId))
- // {
- // responseData.Code = -1;
- // responseData.Message = "禁用失败: 此插件不存在, 或未启用";
- // return await Task.FromResult(responseData);
- // }
-
- #endregion 效验
-
- try
- {
- // 1. 找到此插件实例
- IPlugin plugin = _pluginFinder.Plugin(pluginId);
- if (plugin == null)
- {
- throw Oops.Oh("禁用失败: 此插件不存在, 或未启用");
- }
- try
- {
- // 2.调取插件的 BeforeDisable(), 插件开发者可在此回收资源
- var pluginDisableResult = plugin.BeforeDisable();
- if (!pluginDisableResult.IsSuccess)
- {
- throw Oops.Oh("禁用失败: 来自插件的错误信息: " + pluginDisableResult.Message);
- }
- // 3.移除插件对应的程序集加载上下文
- _pluginManager.UnloadPlugin(pluginId);
- // 3.1. ReBuild
- this._pluginApplicationBuilderManager.ReBuild();
- if (pluginConfigModel.EnabledPlugins.Contains(pluginId))
- {
- // 4.从 pluginConfigModel.EnabledPlugins 移除
- pluginConfigModel.EnabledPlugins.Remove(pluginId);
- // 5.保存到 plugin.config.json
- PluginConfigModelFactory.Save(pluginConfigModel);
- }
- }
- catch (Exception ex)
- {
- LogUtil.Error(ex.ToString());
- throw Oops.Oh("禁用失败: 此插件不存在, 或未启用");
- }
-
- // 7. 尝试移除 Plugins_wwwroot/PluginId
- string pluginWwwRootDir = PluginPathProvider.PluginWwwRootDir(pluginId);
- if (Directory.Exists(pluginWwwRootDir))
- {
- Directory.Delete(pluginWwwRootDir, true);
- }
- //8.移除Furion动态插件
-
- //9.载入Furion动态插件
- var pluginMainAssembly = _pluginManager.GetPluginAssembly(pluginId);
- // 将程序集添加进动态 WebAPI 应用部件
- _provider.RemoveAssembliesWithNotifyChanges(pluginMainAssembly);
-
- await _sysPluginRep.UpdateAsync(u => new SysPluginCore() { Status = StatusEnum.Disable }, u => u.Id == input.Id);
- }
- catch (Exception ex)
- {
- throw Oops.Oh("禁用失败: " + ex.Message);
- }
- }
-
- ///
- /// 上传文件
- ///
- ///
- ///
- ///
- [DisplayName("上传文件")]
- public async Task UploadFile([Required] IFormFile file, [FromQuery] string? path)
- {
- var sysFile = await HandleUploadFile(file, path);
- //return new FileOutput
- //{
- //};
- }
-
- ///
- /// 上传文件
- ///
- /// 文件
- /// 路径
- ///
- [NonAction]
- private async Task HandleUploadFile(IFormFile file, string savePath)
- {
- if (file == null) throw Oops.Oh(ErrorCodeEnum.D8000);
-
- var path = savePath;
-
- BaseResponseModel responseData = new BaseResponseModel();
-
- #region 效验
-
- if (file == null)
- {
- throw Oops.Oh("上传的文件不能为空");
- //responseData.Code = -1;
- //responseData.Message = "上传的文件不能为空";
- //return responseData;
- }
- //文件后缀
- string fileExtension = Path.GetExtension(file.FileName);//获取文件格式,拓展名
- // 类型标记
- UploadFileType uploadFileType = UploadFileType.NoAllowedType;
- switch (fileExtension)
- {
- case ".zip":
- uploadFileType = UploadFileType.Zip;
- break;
-
- case ".nupkg":
- uploadFileType = UploadFileType.Nupkg;
- break;
- }
-
- if (fileExtension != ".zip" && fileExtension != ".nupkg")
- {
- throw Oops.Oh("只能上传 zip 或 nupkg 格式文件");
- //responseData.Code = -1;
- //// nupkg 其实就是 zip
- //responseData.Message = "只能上传 zip 或 nupkg 格式文件";
- //return responseData;
- }
- // PluginCore.AspNetCore-v1.0.2 起 不再限制插件上传大小
- //判断文件大小
- //var fileSize = file.Length;
- //if (fileSize > 1024 * 1024 * 5) // 5M
- //{
- // responseData.Code = -1;
- // responseData.Message = "上传的文件不能大于5MB";
- // return responseData;
- //}
-
- #endregion 效验
-
- try
- {
- // 1.先上传到 临时插件上传目录, 用Guid.zip作为保存文件名
- string tempZipFilePath = Path.Combine(PluginPathProvider.TempPluginUploadDir(), Guid.NewGuid() + ".zip");
- using (var fs = System.IO.File.Create(tempZipFilePath))
- {
- file.CopyTo(fs); //将上传的文件文件流,复制到fs中
- fs.Flush();//清空文件流
- }
- // 2.解压
- bool isDecomparessSuccess = false;
- if (uploadFileType == UploadFileType.Zip)
- {
- isDecomparessSuccess = ZipHelper.DecomparessFile(tempZipFilePath, tempZipFilePath.Replace(".zip", ""));
- }
- else if (uploadFileType == UploadFileType.Nupkg)
- {
- isDecomparessSuccess = NupkgService.DecomparessFile(tempZipFilePath, tempZipFilePath.Replace(".zip", ""));
- }
-
- // 3.删除原压缩包
- System.IO.File.Delete(tempZipFilePath);
- if (!isDecomparessSuccess)
- {
- throw Oops.Oh("解压插件压缩包失败");
-
- //responseData.Code = -1;
- //responseData.Message = "解压插件压缩包失败";
- //return responseData;
- }
- // 4.读取其中的info.json, 获取 PluginId 值
- PluginInfoModel pluginInfoModel = PluginInfoModelFactory.ReadPluginDir(tempZipFilePath.Replace(".zip", ""));
- if (pluginInfoModel == null || string.IsNullOrEmpty(pluginInfoModel.PluginId))
- {
- // 记得删除已不再需要的临时插件文件夹
- Directory.Delete(tempZipFilePath.Replace(".zip", ""), true);
- throw Oops.Oh("不合法的插件");
-
- //responseData.Code = -1;
- //responseData.Message = "不合法的插件";
- //return responseData;
- }
- string pluginId = pluginInfoModel.PluginId;
- // 5.检索 此 PluginId 是否本地插件已存在
- var pluginConfigModel = PluginConfigModelFactory.Create();
- // 本地已经存在的 PluginId
- IList localExistPluginIds = PluginPathProvider.AllPluginFolderName();
- if (localExistPluginIds.Contains(pluginId))
- {
- // 记得删除已不再需要的临时插件文件夹
- Directory.Delete(tempZipFilePath.Replace(".zip", ""), true);
- throw Oops.Oh($"本地已有此插件 (PluginId: {pluginId}), 请前往插件列表删除后, 再上传");
-
- //responseData.Code = -1;
- //responseData.Message = $"本地已有此插件 (PluginId: {pluginId}), 请前往插件列表删除后, 再上传";
- //return responseData;
- }
- // 6.本地无此插件 -> 移动插件文件夹到 Plugins 下, 并以 PluginId 为插件文件夹名
- string pluginsRootPath = PluginPathProvider.PluginsRootPath();
- string newPluginDir = Path.Combine(pluginsRootPath, pluginId);
- Directory.Move(tempZipFilePath.Replace(".zip", ""), newPluginDir);
-
- // 7. 放入 Plugins 中, 默认为 已禁用
-
- var pluginCore = new SysPluginCore();
- pluginCore.PluginId = pluginId;
- pluginCore.DisplayName = pluginInfoModel.DisplayName;
- pluginCore.Description = pluginInfoModel.Description;
- pluginCore.Author = pluginInfoModel.Author;
- pluginCore.Version = pluginInfoModel.Version;
- pluginCore.Status = StatusEnum.Disable;
- await _sysPluginRep.InsertAsync(pluginCore.Adapt());
-
- responseData.Code = 1;
- responseData.Message = $"上传插件成功 (PluginId: {pluginId})";
- }
- catch (Exception ex)
- {
- throw Oops.Oh("上传插件失败: " + ex.Message);
-
- //responseData.Code = -1;
- //responseData.Message = "上传插件失败: " + ex.Message;
- //ex = ex.InnerException;
- //while (ex != null)
- //{
- // responseData.Message += " - " + ex.InnerException.Message;
- // ex = ex.InnerException;
- //}
- }
-
- return responseData;
- }
-
- #region Helpers
-
- [NonAction]
- private IList PluginInfoModelToResponseModel(IList pluginInfoModels, PluginConfigModel pluginConfigModel, string[] enablePluginIds)
- {
- // 获取 Plugins 下所有插件
- // DirectoryInfo pluginsDir = new DirectoryInfo(PluginPathProvider.PluginsRootPath());
- // List pluginIds = pluginsDir?.GetDirectories()?.Select(m => m.Name)?.ToList() ?? new List();
-
- IList responseModels = new List();
-
- #region 添加插件状态信息
-
- foreach (var model in pluginInfoModels)
- {
- PluginInfoResponseModel responseModel = new PluginInfoResponseModel();
- responseModel.Author = model.Author;
- responseModel.Description = model.Description;
- responseModel.DisplayName = model.DisplayName;
- responseModel.PluginId = model.PluginId;
- responseModel.SupportedVersions = model.SupportedVersions;
- responseModel.Version = model.Version;
- responseModel.DependPlugins = model.DependPlugins;
-
- if (pluginConfigModel.EnabledPlugins.Contains(model.PluginId) && !enablePluginIds.Contains(model.PluginId))
- {
- // 错误情况: 配置 标识 已启用, 但实际没有启用成功
- pluginConfigModel.EnabledPlugins.Remove(model.PluginId);
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- responseModel.Status = PluginStatus.Disabled;
- }
- else if (!pluginConfigModel.EnabledPlugins.Contains(model.PluginId) && enablePluginIds.Contains(model.PluginId))
- {
- // 错误情况: 配置没有标识 已启用, 但实际 已启用
- pluginConfigModel.EnabledPlugins.Add(model.PluginId);
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- responseModel.Status = PluginStatus.Enabled;
- }
- else if (pluginConfigModel.EnabledPlugins.Contains(model.PluginId) && enablePluginIds.Contains(model.PluginId))
- {
- responseModel.Status = PluginStatus.Enabled;
- }
- else
- {
- responseModel.Status = PluginStatus.Disabled;
- }
- responseModels.Add(responseModel);
- }
-
- #endregion 添加插件状态信息
-
- return responseModels;
- }
-
- public enum UploadFileType
- {
- NoAllowedType = 0,
- Zip = 1,
- Nupkg = 2
- }
-
- #endregion Helpers
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Startup.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Startup.cs
deleted file mode 100644
index 3f087971..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/Startup.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-
-namespace Admin.NET.Plugin.PluginCore;
-
-[AppStartup(100)]
-public class Startup : AppStartup
-{
- public void ConfigureServices(IServiceCollection services)
- {
- RunOptions.Default
- .AddComponent()
- .UseComponent();
- }
-
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
- {
- }
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/StartupServiceComponent.cs b/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/StartupServiceComponent.cs
deleted file mode 100644
index 9076e720..00000000
--- a/Admin.NET/Plugins/Admin.NET.Plugin.PluginCore/StartupServiceComponent.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-using PluginCore;
-using PluginCore.AspNetCore.Extensions;
-using PluginCore.Interfaces;
-using PluginCore.Models;
-
-namespace Admin.NET.Plugin.PluginCore;
-
-// 模拟 ConfigureService
-public sealed class StartupServiceComponent : IServiceComponent
-{
- public void Load(IServiceCollection services, ComponentContext componentContext)
- {
- // 1. 添加 PluginCore
- services.AddPluginCore();
- IPluginManager pluginManager = App.GetService();
- IDynamicApiRuntimeChangeProvider provider = App.GetService();
-
- #region 获取 PluginConfigModel
-
- PluginConfigModel pluginConfigModel = PluginConfigModelFactory.Create();
-
- #endregion 获取 PluginConfigModel
-
- // 已启用的插件
-
- #region 加载 已启用插件的Assemblies
-
- IList enabledPluginIds = pluginConfigModel.EnabledPlugins;
- foreach (var pluginId in enabledPluginIds)
- {
- //9.载入Furion动态插件
- var pluginMainAssembly = pluginManager.GetPluginAssembly(pluginId);
- // 将程序集添加进动态 WebAPI 应用部件
- provider.AddAssembliesWithNotifyChanges(pluginMainAssembly);
- }
-
- #endregion 加载 已启用插件的Assemblies
- }
-}
-
-// 模拟 Configure
-public sealed class StartupApplicationComponent : IApplicationComponent
-{
- public void Load(IApplicationBuilder app, IWebHostEnvironment env, ComponentContext componentContext)
- {
- // 2. 使用 PluginCore
- app.UsePluginCore();
- }
-}
\ No newline at end of file
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/AdminUI/PluginCoreAdminUIBuilderExtensions.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/AdminUI/PluginCoreAdminUIBuilderExtensions.cs
deleted file mode 100644
index 5e68b54d..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/AdminUI/PluginCoreAdminUIBuilderExtensions.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.FileProviders;
-using Microsoft.Extensions.Options;
-
-namespace PluginCore.AspNetCore.AdminUI
-{
- public static class PluginCoreAdminUIBuilderExtensions
- {
-
- ///
- /// Register the SwaggerUI middleware with provided options
- ///
- public static IApplicationBuilder UsePluginCoreAdminUI(this IApplicationBuilder app, PluginCoreAdminUIOptions options)
- {
- #region Old - 区分
- //Config.PluginCoreConfig pluginCoreConfig = Config.PluginCoreConfigFactory.Create();
-
- //switch (pluginCoreConfig.FrontendMode?.ToLower())
- //{
- // case "localembedded":
- // app.UseMiddleware(options);
- // break;
- // case "localfolder":
-
- // #region LocalFolder
- // //string contentRootPath = Directory.GetCurrentDirectory();
-
- // // https://docs.microsoft.com/zh-CN/aspnet/core/fundamentals/static-files?view=aspnetcore-5.0
- // //var options = new DefaultFilesOptions()
- // //{
- // // RequestPath = "/PluginCore/Admin",
- // //};
- // //// TODO: 404: 无效, 失败, 改为使用 Controller 手动指定
- // ////options.DefaultFileNames.Add("PluginCoreAdmin/index.html");
- // //app.UseDefaultFiles(options);
-
- // // 注意: 为了无需重启Web,而更新是否本地前端配置, 因此此项保持常驻开启
- // // 因此, 需要保证 PluginCoreAdmin 文件夹存在
- // string pluginCoreAdminDir = PluginPathProvider.PluginCoreAdminDir();
- // app.UseStaticFiles(new StaticFileOptions
- // {
- // FileProvider = new PhysicalFileProvider(
- // pluginCoreAdminDir),
- // RequestPath = "/PluginCore/Admin"
- // });
- // #endregion
-
- // break;
- // case "remotecdn":
-
- // break;
- // default:
- // app.UseMiddleware(options);
- // break;
- //}
-
- //return app;
- #endregion
-
-
- return app.UseMiddleware(options);
- }
-
- ///
- /// Register the SwaggerUI middleware with optional setup action for DI-injected options
- ///
- public static IApplicationBuilder UsePluginCoreAdminUI(
- this IApplicationBuilder app)
- {
- PluginCoreAdminUIOptions options = new PluginCoreAdminUIOptions()
- {
-
- };
-
- return app.UsePluginCoreAdminUI(options);
- }
-
-
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/AdminUI/PluginCoreAdminUIMiddleware.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/AdminUI/PluginCoreAdminUIMiddleware.cs
deleted file mode 100644
index b1a57525..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/AdminUI/PluginCoreAdminUIMiddleware.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.StaticFiles;
-using Microsoft.Extensions.FileProviders;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-
-namespace PluginCore.AspNetCore.AdminUI
-{
- public class PluginCoreAdminUIMiddleware
- {
- private const string EmbeddedFileNamespace = "PluginCore.AspNetCore.node_modules.plugincore_admin_frontend.dist";
-
- private readonly PluginCoreAdminUIOptions _options;
- private readonly StaticFileMiddleware _staticFileMiddleware;
-
-
- public PluginCoreAdminUIMiddleware(
- RequestDelegate next,
- IWebHostEnvironment hostingEnv,
- ILoggerFactory loggerFactory,
- PluginCoreAdminUIOptions options)
- {
- _options = options ?? new PluginCoreAdminUIOptions();
-
- _staticFileMiddleware = CreateStaticFileMiddleware(next, hostingEnv, loggerFactory, options);
- }
-
- public async Task Invoke(HttpContext httpContext)
- {
- var httpMethod = httpContext.Request.Method;
- var path = httpContext.Request.Path.Value;
-
- // If the RoutePrefix is requested (with or without trailing slash), redirect to index URL
- if (httpMethod == "GET" && Regex.IsMatch(path, $"^/?{Regex.Escape(_options.RoutePrefix)}/?$", RegexOptions.IgnoreCase))
- {
- // Use relative redirect to support proxy environments
- var relativeIndexUrl = string.IsNullOrEmpty(path) || path.EndsWith("/")
- ? "index.html"
- : $"{path.Split('/').Last()}/index.html";
-
- RespondWithRedirect(httpContext.Response, relativeIndexUrl);
- return;
- }
-
- if (httpMethod == "GET" && Regex.IsMatch(path, $"^/{Regex.Escape(_options.RoutePrefix)}/?index.html$", RegexOptions.IgnoreCase))
- {
- await RespondWithIndexHtml(httpContext.Response);
- return;
- }
-
- await _staticFileMiddleware.Invoke(httpContext);
- }
-
- private StaticFileMiddleware CreateStaticFileMiddleware(
- RequestDelegate next,
- IWebHostEnvironment hostingEnv,
- ILoggerFactory loggerFactory,
- PluginCoreAdminUIOptions options)
- {
- Config.PluginCoreConfig pluginCoreConfig = Config.PluginCoreConfigFactory.Create();
- IFileProvider fileProvider = null;
- switch (pluginCoreConfig.FrontendMode?.ToLower())
- {
- case "localembedded":
- fileProvider = new EmbeddedFileProvider(typeof(PluginCoreAdminUIMiddleware).GetTypeInfo().Assembly,
- EmbeddedFileNamespace);
- break;
- case "localfolder":
- string absoluteRootPath = PluginPathProvider.PluginCoreAdminDir();
- fileProvider = new PhysicalFileProvider(absoluteRootPath);
- break;
- case "remotecdn":
- fileProvider = new PluginCoreAdminUIRemoteFileProvider(pluginCoreConfig.RemoteFrontend);
- break;
- default:
- fileProvider = new EmbeddedFileProvider(typeof(PluginCoreAdminUIMiddleware).GetTypeInfo().Assembly,
- EmbeddedFileNamespace);
- break;
- }
-
- var staticFileOptions = new StaticFileOptions
- {
- RequestPath = string.IsNullOrEmpty(options.RoutePrefix) ? string.Empty : $"/{options.RoutePrefix}",
- FileProvider = fileProvider,
- };
-
- return new StaticFileMiddleware(next, hostingEnv, Options.Create(staticFileOptions), loggerFactory);
- }
-
- private void RespondWithRedirect(HttpResponse response, string location)
- {
- response.StatusCode = 301;
- response.Headers["Location"] = location;
- }
-
- private async Task RespondWithIndexHtml(HttpResponse response)
- {
- response.StatusCode = 200;
- response.ContentType = "text/html;charset=utf-8";
-
- using (var stream = _options.IndexStream())
- {
- // Inject arguments before writing to response
- var htmlBuilder = new StringBuilder(new StreamReader(stream).ReadToEnd());
- foreach (var entry in GetIndexArguments())
- {
- htmlBuilder.Replace(entry.Key, entry.Value);
- }
-
- await response.WriteAsync(htmlBuilder.ToString(), Encoding.UTF8);
- }
- }
-
- private IDictionary GetIndexArguments()
- {
- return new Dictionary()
- {
- //{ "%(DocumentTitle)", _options.DocumentTitle },
- //{ "%(HeadContent)", _options.HeadContent },
- //{ "%(ConfigObject)", JsonSerializer.Serialize(_options.ConfigObject, _jsonSerializerOptions) },
- //{ "%(OAuthConfigObject)", JsonSerializer.Serialize(_options.OAuthConfigObject, _jsonSerializerOptions) },
- //{ "%(Interceptors)", JsonSerializer.Serialize(_options.Interceptors) },
- };
- }
-
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/AdminUI/PluginCoreAdminUIOptions.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/AdminUI/PluginCoreAdminUIOptions.cs
deleted file mode 100644
index 2e175191..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/AdminUI/PluginCoreAdminUIOptions.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Net.Http;
-using System.Reflection;
-using System.Text;
-
-namespace PluginCore.AspNetCore.AdminUI
-{
- public class PluginCoreAdminUIOptions
- {
- ///
- /// Gets or sets a route prefix for accessing the swagger-ui
- ///
- public string RoutePrefix { get; set; } = "PluginCore/Admin";
-
- ///
- /// Gets or sets a Stream function for retrieving the swagger-ui page
- ///
- public Func IndexStream
- {
- get
- {
- Func funcStream = null;
- ;
- Config.PluginCoreConfig pluginCoreConfig = Config.PluginCoreConfigFactory.Create();
- switch (pluginCoreConfig.FrontendMode?.ToLower())
- {
- case "localembedded":
- funcStream = () => typeof(PluginCoreAdminUIOptions).GetTypeInfo().Assembly
- .GetManifestResourceStream("PluginCore.AspNetCore.node_modules.plugincore_admin_frontend.dist.index.html");
- break;
- case "localfolder":
- string absoluteRootPath = PluginPathProvider.PluginCoreAdminDir();
- string indexFilePath = Path.Combine(absoluteRootPath, "index.html");
-
- funcStream = () => (Stream)new FileStream(indexFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 1, FileOptions.Asynchronous | FileOptions.SequentialScan);
- break;
- case "remotecdn":
- string remoteFrontendRootPath = pluginCoreConfig.RemoteFrontend;
- string indexFileRemotePath = remoteFrontendRootPath + "/" + "index.html";
-
- funcStream = () => new HttpClient().GetStreamAsync(indexFileRemotePath).Result;
- break;
- default:
- funcStream = () => typeof(PluginCoreAdminUIOptions).GetTypeInfo().Assembly
- .GetManifestResourceStream("PluginCore.AspNetCore.node_modules.plugincore_admin_frontend.dist.index.html");
- break;
- }
-
- return funcStream;
- }
- }
-
-
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/AdminUI/PluginCoreAdminUIRemoteFileProvider.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/AdminUI/PluginCoreAdminUIRemoteFileProvider.cs
deleted file mode 100644
index 32e87e10..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/AdminUI/PluginCoreAdminUIRemoteFileProvider.cs
+++ /dev/null
@@ -1,131 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Net.Http;
-using System.Text;
-using Microsoft.Extensions.FileProviders;
-using Microsoft.Extensions.Primitives;
-
-namespace PluginCore.AspNetCore.AdminUI
-{
- public class PluginCoreAdminUIRemoteFileProvider : IFileProvider
- {
- protected string RootUrl { get; set; }
-
- public PluginCoreAdminUIRemoteFileProvider(string rootUrl)
- {
- this.RootUrl = rootUrl;
- }
-
- public IDirectoryContents GetDirectoryContents(string subpath)
- {
- return (IDirectoryContents)NotFoundDirectoryContents.Singleton;
- }
-
- public IFileInfo GetFileInfo(string subpath)
- {
- if (string.IsNullOrEmpty(subpath))
- return (IFileInfo)new NotFoundFileInfo(subpath);
-
- IFileInfo fileInfo = new PluginCoreAdminUIFileInfo(this.RootUrl, subpath);
-
- return fileInfo;
- }
-
- public IChangeToken Watch(string filter)
- {
- throw new NotImplementedException();
- }
-
-
- public class PluginCoreAdminUIFileInfo : IFileInfo
- {
- protected string RootUrl { get; set; }
-
- protected string SubPath { get; set; }
-
- private string _name;
-
- public PluginCoreAdminUIFileInfo(string rootUrl, string subpath)
- {
- this.RootUrl = rootUrl;
- this.SubPath = subpath;
- this._name = this.SubPath.Substring(this.SubPath.LastIndexOf("/") + 1);
- }
-
- public Stream CreateReadStream()
- {
- HttpClient httpClient = new HttpClient();
-
- return httpClient.GetStreamAsync($"{this.RootUrl}/{this.SubPath}").Result;
- }
-
- public bool Exists
- {
- get
- {
- bool isExist = false;
- if (this.Name == "index.html")
- {
- isExist = true;
- }
-
- return isExist;
- }
- }
- public bool IsDirectory
- {
- get
- {
- return false;
- }
- }
-
- public DateTimeOffset LastModified
- {
- get
- {
- return new DateTimeOffset(DateTime.Now);
- }
- }
-
- public long Length
- {
- get
- {
- return 111;
- }
- }
-
- public string Name
- {
- get
- {
- return this._name;
- }
- }
-
- public string PhysicalPath
- {
- get
- {
- return "";
- }
- }
- }
-
- }
-
-
-
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authentication/PluginCoreAuthenticationHandler.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authentication/PluginCoreAuthenticationHandler.cs
deleted file mode 100644
index 58f6ea2c..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authentication/PluginCoreAuthenticationHandler.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Security.Claims;
-using System.Text;
-using System.Text.Encodings.Web;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using PluginCore.AspNetCore.Authorization;
-
-namespace PluginCore.AspNetCore.Authentication
-{
- ///
- /// https://stackoverflow.com/questions/52287542/invalidoperationexception-no-authenticationscheme-was-specified-and-there-was
- ///
- public class PluginCoreAuthenticationHandler : AuthenticationHandler
- {
- private readonly AccountManager _accountManager;
-
- public PluginCoreAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, AccountManager accountManager) : base(options, logger, encoder, clock)
- {
- this._accountManager = accountManager;
- }
-
- protected override async Task HandleAuthenticateAsync()
- {
- string token = this._accountManager.CurrentToken();
- if (string.IsNullOrEmpty(token))
- {
- return AuthenticateResult.NoResult();
- }
-
- bool isAdmin = AccountManager.IsAdminToken(token);
-
- if (!isAdmin)
- {
- return AuthenticateResult.Fail($"token is not admin");
- }
- else
- {
- var id = new ClaimsIdentity(
- // new Claim[] { new Claim("PluginCore.Token", token) }, // not safe , just as an example , should custom claims on your own
- claims: new Claim[] { new Claim(type: IPlugins.Constants.AspNetCoreAuthenticationClaimType, value: token) }, // not safe , just as an example , should custom claims on your own
- authenticationType: Scheme.Name
- );
- ClaimsPrincipal principal = new ClaimsPrincipal(identity: id);
- var ticket = new AuthenticationTicket(
- principal: principal,
- properties: new AuthenticationProperties(),
- authenticationScheme: Scheme.Name);
-
- // Utils.LogUtil.Info($"通过 Authentication: token: {token}");
- Utils.LogUtil.Info($"Authentication Passed");
-
- return AuthenticateResult.Success(ticket);
- }
-
- }
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authentication/PluginCoreAuthenticationSchemeOptions.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authentication/PluginCoreAuthenticationSchemeOptions.cs
deleted file mode 100644
index 4cf4de2f..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authentication/PluginCoreAuthenticationSchemeOptions.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.AspNetCore.Authentication;
-
-namespace PluginCore.AspNetCore.Authentication
-{
- public class PluginCoreAuthenticationSchemeOptions : AuthenticationSchemeOptions
- {
-
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authorization/AccountManager.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authorization/AccountManager.cs
deleted file mode 100644
index bb5f9e75..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authorization/AccountManager.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.AspNetCore.Http;
-using PluginCore.Utils;
-
-namespace PluginCore.AspNetCore.Authorization
-{
- public class AccountManager
- {
- private readonly IHttpContextAccessor _httpContextAccessor;
-
- public Microsoft.AspNetCore.Http.HttpContext HttpContext
- {
- get
- {
- return this._httpContextAccessor.HttpContext;
- }
- }
-
- public AccountManager(IHttpContextAccessor httpContextAccessor)
- {
- // Exception: IFeatureCollection has been disposed. Object name: 'Collection'.
- // https://stackoverflow.com/questions/59963383/session-setstring-method-throws-exception-ifeaturecollection-has-been-disposed
- //HttpContext = ((HttpContextAccessor)httpContextAccessor).HttpContext;
- //HttpContext = httpContextAccessor.HttpContext;
- // 注意: 不要将 HttpContext 保存起来,应当每次都从 httpContextAccessor 取
- _httpContextAccessor = httpContextAccessor;
- }
-
- public static Config.PluginCoreConfig.AdminModel Admin
- {
- get
- {
- return Config.PluginCoreConfigFactory.Create().Admin;
- }
- set
- {
- var sourceModel = Config.PluginCoreConfigFactory.Create();
- sourceModel.Admin = value;
- Config.PluginCoreConfigFactory.Save(sourceModel);
- }
- }
-
- public static string CurrentToken(HttpContext httpContext)
- {
- string token = null;
- HttpRequest request = httpContext.Request;
- try
- {
- // header -> cookie
- try
- {
- // header 中找 token
- if (request.Headers.ContainsKey("Authorization"))
- {
- string authHeader = request.Headers["Authorization"];
- if (!string.IsNullOrEmpty(authHeader) && authHeader.StartsWith("Bearer"))
- {
- token = authHeader.Substring("Bearer ".Length).Trim();
- }
- }
- }
- catch (Exception ex)
- {
- //throw ex;
- }
- if (string.IsNullOrEmpty(token))
- {
- // cookie 中找 token
- //string tokenCookieName = "token";
- // string tokenCookieName = "PluginCore.Admin.Token";
- string tokenCookieName = IPlugins.Constants.AspNetCoreAuthorizationTokenCookieName;
- if (request.Cookies.Keys.Contains(tokenCookieName))
- {
- if (request.Cookies[tokenCookieName] != null && string.IsNullOrEmpty(request.Cookies[tokenCookieName]) == false)
- {
- token = request.Cookies[tokenCookieName];
- }
- }
- }
- }
- catch (Exception ex)
- {
- throw ex;
- }
-
- return token;
- }
-
- public string CurrentToken()
- {
- return CurrentToken(this.HttpContext);
- }
-
- public static string CreateToken()
- {
- return CreateToken(Admin.UserName, Admin.Password);
- }
-
- public static string CreateToken(string userName, string password)
- {
- string token = $"UserName={userName}&Password={password}";
- token = Md5Helper.MD5Encrypt32(token);
-
- return token;
- }
-
- public static bool IsAdminToken(string token)
- {
- bool isAdmin = false;
- isAdmin = CreateToken().Equals(token);
-
- return isAdmin;
- }
-
- public bool IsAdmin()
- {
- return IsAdmin(this.HttpContext);
- }
-
- public static bool IsAdmin(HttpContext httpContext)
- {
- bool isAdmin = false;
- try
- {
- string currentToken = CurrentToken(httpContext);
- isAdmin = IsAdminToken(currentToken);
- }
- catch (Exception ex)
- {
- throw ex;
- }
-
- return isAdmin;
- }
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authorization/PluginCoreAdminAuthorizationHandler.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authorization/PluginCoreAdminAuthorizationHandler.cs
deleted file mode 100644
index d3c25b36..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authorization/PluginCoreAdminAuthorizationHandler.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Authorization;
-
-namespace PluginCore.AspNetCore.Authorization
-{
- public class PluginCoreAdminAuthorizationHandler : AuthorizationHandler
- {
- private readonly AccountManager _accountManager;
-
- public PluginCoreAdminAuthorizationHandler(AccountManager accountManager)
- {
- _accountManager = accountManager;
- }
-
- ///
- /// 必须在其中呼叫一次 代表满足 ,否则皆为 不满足此 Requirement
- ///
- ///
- ///
- ///
- protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
- PluginCoreAdminRequirement requirement)
- {
- bool isAdmin = this._accountManager.IsAdmin();
- if (!isAdmin)
- {
- context.Fail();
- }
- else
- {
- // 认证通过后, 可通过下面方式获取 token
- var identity = context.User.Identity;
-
- string token = this._accountManager.CurrentToken();
-
- // Utils.LogUtil.Info($"通过 Authorization: token: {token}");
- Utils.LogUtil.Info($"Authorization Granted");
-
- context.Succeed(requirement);
- }
-
- await Task.CompletedTask;
- }
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authorization/PluginCoreAdminAuthorizeAttribute.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authorization/PluginCoreAdminAuthorizeAttribute.cs
deleted file mode 100644
index dfb1efe5..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authorization/PluginCoreAdminAuthorizeAttribute.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.AspNetCore.Authorization;
-
-namespace PluginCore.AspNetCore.Authorization
-{
- ///
- /// 注意: PluginCoreAdmin -> PluginCore.Admin
- ///
- public class PluginCoreAdminAuthorizeAttribute : AuthorizeAttribute
- {
- // public PluginCoreAdminAuthorizeAttribute() : base("PluginCore.Admin")
- public PluginCoreAdminAuthorizeAttribute() : base(policy: IPlugins.Constants.AspNetCoreAuthorizationPolicyName)
- {
- // 同时明确指定 认证方案 与 授权策略
- AuthenticationSchemes = PluginCore.IPlugins.Constants.AspNetCoreAuthenticationScheme;
- }
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authorization/PluginCoreAdminRequirement.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authorization/PluginCoreAdminRequirement.cs
deleted file mode 100644
index b7f16989..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Authorization/PluginCoreAdminRequirement.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.AspNetCore.Authorization;
-
-namespace PluginCore.AspNetCore.Authorization
-{
- public class PluginCoreAdminRequirement : IAuthorizationRequirement
- {
- public PluginCoreAdminRequirement()
- {
-
- }
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/BackgroundServices/BackgroundServicesHelper.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/BackgroundServices/BackgroundServicesHelper.cs
deleted file mode 100644
index 96d71c75..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/BackgroundServices/BackgroundServicesHelper.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using Microsoft.Extensions.DependencyInjection;
-
-namespace PluginCore.AspNetCore.BackgroundServices
-{
- public static class BackgroundServicesHelper
- {
- public static IServiceCollection AddBackgroundServices(this IServiceCollection services)
- {
- //services.AddScoped(typeof(IHostedService), typeof(TimeBackgroundService));
- // AddHostedService: Microsoft.AspNetCore.App
- services.AddHostedService(); // 以这种方式注入就是单例
-
- return services;
- }
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/BackgroundServices/PluginTimeJobBackgroundService.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/BackgroundServices/PluginTimeJobBackgroundService.cs
deleted file mode 100644
index 9a62fe6f..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/BackgroundServices/PluginTimeJobBackgroundService.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Linq;
-using System.Threading.Tasks;
-using PluginCore.Interfaces;
-using PluginCore.IPlugins;
-using PluginCore.Utils;
-
-namespace PluginCore.AspNetCore.BackgroundServices
-{
- public class PluginTimeJobBackgroundService : TimeBackgroundService
- {
- ///
- /// 插件与之最近执行时间
- /// 最近执行时间: 10位秒 时间戳
- ///
- private readonly Dictionary _pluginAndLastExecuteTimeDic = new Dictionary();
-
- private readonly IPluginFinder _pluginFinder;
-
- private static readonly object _doWorklock = new object();
-
- public PluginTimeJobBackgroundService(IPluginFinder pluginFinder)
- {
- _pluginFinder = pluginFinder;
- // 最小间隔 1 秒
- _timerPeriod = TimeSpan.FromSeconds(1);
- }
-
- protected override void DoWork(object state)
- {
- lock (_doWorklock)
- {
- //Console.WriteLine("Memory used before collection: {0:N0}", GC.GetTotalMemory(false));
-
- var plugins = this._pluginFinder.EnablePlugins().ToList();
-
- List enabledPluginKeyList = new List();
- foreach (var item in plugins)
- {
- string pluginKey = item.GetType().ToString();
- enabledPluginKeyList.Add(pluginKey);
- if (this._pluginAndLastExecuteTimeDic.ContainsKey(pluginKey))
- {
- long lastExecuteTime = this._pluginAndLastExecuteTimeDic[pluginKey];
- long nowTime = DateTime.Now.ToTimeStamp10();
- if (nowTime - lastExecuteTime >= item.SecondsPeriod)
- {
- // 调用
- Utils.LogUtil.Info($"{pluginKey}: {nameof(ITimeJobPlugin)}.{nameof(ITimeJobPlugin.ExecuteAsync)}");
- Task task = item?.ExecuteAsync();
- this._pluginAndLastExecuteTimeDic[pluginKey] = DateTime.Now.ToTimeStamp10();
- }
- }
- else
- {
- // 调用
- Utils.LogUtil.Info($"{pluginKey}: {nameof(ITimeJobPlugin)}.{nameof(ITimeJobPlugin.ExecuteAsync)}");
- Task task = item?.ExecuteAsync();
- this._pluginAndLastExecuteTimeDic.Add(pluginKey, DateTime.Now.ToTimeStamp10());
- }
- }
- // 所有插件遍历结束
- // 出现在了 _pluginAndLastExecuteTimeDic 中,但没有出现在 enabledPluginKeyList, 说明为之前启用过,但现在已禁用的插件,需要去除掉
- List keys = this._pluginAndLastExecuteTimeDic.Select(m => m.Key).ToList();
- foreach (string key in keys)
- {
- if (!enabledPluginKeyList.Contains(key))
- {
- this._pluginAndLastExecuteTimeDic.Remove(key);
- }
- }
-
- GC.Collect();
- GC.WaitForPendingFinalizers();
- //Console.WriteLine("Memory used after full collection: {0:N0}", GC.GetTotalMemory(true));
- }
- }
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/BackgroundServices/TimeBackgroundService.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/BackgroundServices/TimeBackgroundService.cs
deleted file mode 100644
index d3087a14..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/BackgroundServices/TimeBackgroundService.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using Microsoft.Extensions.Hosting;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace PluginCore.AspNetCore.BackgroundServices
-{
- public abstract class TimeBackgroundService : IHostedService, IDisposable
- {
- protected Timer _timer;
- protected TimeSpan _timerPeriod;
-
- public virtual Task StartAsync(CancellationToken cancellationToken)
- {
- _timer = new Timer(DoWork, null, TimeSpan.Zero, _timerPeriod);
-
- return Task.CompletedTask;
- }
-
- public virtual Task StopAsync(CancellationToken cancellationToken)
- {
- _timer?.Change(Timeout.Infinite, 0);
-
- return Task.CompletedTask;
- }
-
- protected abstract void DoWork(object state);
-
- public virtual void Dispose()
- {
- _timer?.Dispose();
- }
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/CHANGELOG.md b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/CHANGELOG.md
deleted file mode 100644
index 4ffa87a0..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/CHANGELOG.md
+++ /dev/null
@@ -1,280 +0,0 @@
-# Changelog
-
-All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines.
-
----
-## [unreleased]
-
-### Documentation
-
-- **(CHANGELOG.md)** update - ([85bf0d9](https://github.com/yiyungent/PluginCore/commit/85bf0d9bd8e2f9efa7e8c0db3127ec8aaa054bc8)) - github-actions[bot]
-- **(CHANGELOG.md)** update - ([a329e4e](https://github.com/yiyungent/PluginCore/commit/a329e4e7ec4048ec445e826f4536402abd832e46)) - github-actions[bot]
-- **(CHANGELOG.md)** update - ([0bbfc89](https://github.com/yiyungent/PluginCore/commit/0bbfc8955b7f6338db2125c78ec250e9eeeadcce)) - github-actions[bot]
-- **(CHANGELOG.md)** update - ([4f6b47b](https://github.com/yiyungent/PluginCore/commit/4f6b47b3f86bfce4a8f660166837a7322c568d78)) - github-actions[bot]
-
-### Miscellaneous Chores
-
-- **(src/plugincore.aspnetcore)** cliff.toml, CHANGELOG.md - ([bf95c28](https://github.com/yiyungent/PluginCore/commit/bf95c287ae9902608c4711e4dec05575c2d0e794)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.4.3](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.4.2..PluginCore.AspNetCore-v1.4.3) - 2024-08-31
-
-### Bug Fixes
-
-- **(PluginCore.AspNetCore/Controllers/PluginsController)** swagger [FromForm] - ([241d9a7](https://github.com/yiyungent/PluginCore/commit/241d9a72973d9cf1a11c11264a91e9370b2a6cda)) - yiyun
-
-### Features
-
-- **(src/plugincore.aspnetcore/extensions/plugincorestartupextensions.cs)** 插件 wwwroot 默认页 指定, 无需再手动 - ([469ae81](https://github.com/yiyungent/PluginCore/commit/469ae81fc31adce0c0b0701e2dfa1d98634ee184)) - yiyun
-
-### Miscellaneous Chores
-
-- **(PluginCore.AspNetCore.csproj)** 1.4.2 -> 1.4.3 - ([1924e0c](https://github.com/yiyungent/PluginCore/commit/1924e0c179aaac1a1d1f57a8bdebc7578d0b7650)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.4.2](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.4.1..PluginCore.AspNetCore-v1.4.2) - 2024-04-06
-
-### Features
-
-- **(src/plugincore.aspnetcore/backgroundservices/plugintimejobbackgroundservice.cs)** log - ([5da04c2](https://github.com/yiyungent/PluginCore/commit/5da04c20b57a166811ef8af828c5fd0bafab844c)) - yiyun
-- **(src/plugincore.aspnetcore/extensions/plugincorestartupextensions.cs)** plugin:startup->appstart - ([71cafe7](https://github.com/yiyungent/PluginCore/commit/71cafe7fa7348b4d8ccb0b342f31ff848c6e77e9)) - yiyun
-
-### Build
-
-- **(src/plugincore.aspnetcore/plugincore.aspnetcore.csproj)** 1.4.1 -> 1.4.2 - ([75f17be](https://github.com/yiyungent/PluginCore/commit/75f17becb01b6d833759811e65cf464ea7a745b1)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.4.1](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.4.0..PluginCore.AspNetCore-v1.4.1) - 2024-03-14
-
-### Bug Fixes
-
-- **(src/plugincore.aspnetcore/extensions/plugincorestartupextensions.cs)** log, _serviceProvider - ([7d7a904](https://github.com/yiyungent/PluginCore/commit/7d7a904fd1794e26f278655f6f3f286b92bd1492)) - yiyun
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** 1.4.0 -> 1.4.1 - ([393d861](https://github.com/yiyungent/PluginCore/commit/393d861870c45a70f63421b5451df76e4ed9c808)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.4.0](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.3.4..PluginCore.AspNetCore-v1.4.0) - 2024-02-15
-
-### Features
-
-- **(src/plugincore.aspnetcore)** authentication & Authorize - ([73a673e](https://github.com/yiyungent/PluginCore/commit/73a673e06d2a8d662a44323cf7401e91d814ae90)) - yiyun
-- **(src/plugincore.aspnetcore)** 认证与授权: 优化,分离, PluginCoreStartupExtensions 优化 - ([ebab6d8](https://github.com/yiyungent/PluginCore/commit/ebab6d888a303f221e4a45ddaa28107ff4a012c4)) - yiyun
-- **(src/plugincore.aspnetcore)** accountManager 部分方法静态化, 提供 HttpContext 传入方式, 相关引用处更新调用 - ([491f334](https://github.com/yiyungent/PluginCore/commit/491f334baabb28e1736b5cc1bd19a0081c54949c)) - yiyun
-
-### Miscellaneous Chores
-
-- **(src/plugincore.aspnetcore/extensions/plugincorestartupextensions.cs)** 代码缩进: 美化 - ([6a03628](https://github.com/yiyungent/PluginCore/commit/6a036289ba6f3ae1592b4e4ed58b4fb1bcdc1306)) - yiyun
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** 1.3.4 -> 1.4.0 - ([f786f5e](https://github.com/yiyungent/PluginCore/commit/f786f5eeb5e19558e3e73890a42f56ce812784cc)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.3.4](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.3.3..PluginCore.AspNetCore-v1.3.4) - 2023-12-30
-
-### Bug Fixes
-
-- **(src/plugincore.aspnetcore)** 转向/适配 LogUtil - ([1a7c71d](https://github.com/yiyungent/PluginCore/commit/1a7c71d748fd228f1053de67572a04f466012ab8)) - yiyun
-- **(src/plugincore.aspnetcore)** 适配: LogUtil - ([f150d07](https://github.com/yiyungent/PluginCore/commit/f150d07b55326133afdfe2c156464605483feb05)) - yiyun
-- **(src/plugincore.aspnetcore)** 适配 LogUtil.Error - ([9c82b16](https://github.com/yiyungent/PluginCore/commit/9c82b161c5507ad1a7b78b1191dba208e8f4be45)) - yiyun
-- **(src/plugincore.aspnetcore/middlewares/languagemiddleware.cs)** namespace: 语法降级 - ([a1f83fc](https://github.com/yiyungent/PluginCore/commit/a1f83fce8f1dcf2e5ead3b8a15eae006053af4de)) - yiyun
-
-### Documentation
-
-- **(src/plugincore.aspnetcore/readme.txt)** zh -> EN - ([f822b0b](https://github.com/yiyungent/PluginCore/commit/f822b0b79d1afca536bb7e10814226fb65988365)) - yiyun
-- **(src/plugincore.aspnetcore/readme.txt)** update - ([0a3210b](https://github.com/yiyungent/PluginCore/commit/0a3210bc073252a1f18d0910dc80aabd1061a66f)) - yiyun
-
-### Features
-
-- **(src/**/*.cs)** // License: Apache-2.0 -> // License: GNU LGPLv3 - ([57366d3](https://github.com/yiyungent/PluginCore/commit/57366d3e2afdb8e20e94851aa8a09f1ee61b6d7e)) - yiyun
-- **(src/**/*.cs)** // Project: https://moeci.com/PluginCore -> // Project: https://yiyungent.github.io/PluginCore - ([7420480](https://github.com/yiyungent/PluginCore/commit/742048065978c1b8597fab3d52f011db4247fbda)) - yiyun
-- **(src/plugincore.aspnetcore)** use Constants - ([6cd128a](https://github.com/yiyungent/PluginCore/commit/6cd128a2ce6da83f8cfee46ae03a7af44380e791)) - yiyun
-- **(src/plugincore.aspnetcore)** languageMiddleware: 当前 Language - ([b0d79e7](https://github.com/yiyungent/PluginCore/commit/b0d79e7a0ae469cc295d87ed8a7c97a355cbc7a1)) - yiyun
-- **(src/plugincore.aspnetcore)** 适配: LogUtil - ([b09da39](https://github.com/yiyungent/PluginCore/commit/b09da39199d614f40ec533d7a472069c40121fae)) - yiyun
-- **(src/plugincore.aspnetcore)** 认证与授权: 日志输出: 中文->英文 - ([1470a99](https://github.com/yiyungent/PluginCore/commit/1470a9913fff6e0df37495d1143f5a55eed995fd)) - yiyun
-- **(src/plugincore.aspnetcore/controllers/pluginscontroller.cs)** 启用,禁用: Message: 使用 BasePlugin 源 - ([d6c8a33](https://github.com/yiyungent/PluginCore/commit/d6c8a3361a7573c68031ad6e8bd8aa35c65035d4)) - yiyun
-- **(src/plugincore.aspnetcore/extensions/plugincorestartupextensions.cs)** use Constants - ([68952a1](https://github.com/yiyungent/PluginCore/commit/68952a13613d469cefe9fc9fd13ab7525dd93f78)) - yiyun
-- **(src/plugincore.aspnetcore/extensions/plugincorestartupextensions.cs)** use constants - ([37798ef](https://github.com/yiyungent/PluginCore/commit/37798efc92f82e5e5f4d696b6de5466809a18d48)) - yiyun
-- **(src/plugincore.aspnetcore/extensions/plugincorestartupextensions.cs)** 初始化: Logger - ([6e24a5a](https://github.com/yiyungent/PluginCore/commit/6e24a5a391af60f8ec0ba85e8ea86ea23c49f522)) - yiyun
-- **(src/plugincore.aspnetcore/extensions/plugincorestartupextensions.cs)** log 输出 -> 英文 - ([e41b73a](https://github.com/yiyungent/PluginCore/commit/e41b73adda0ca5d9f1f60109ee8b6fe7de39deda)) - yiyun
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** 1.3.3 -> 1.3.4 - ([84550cc](https://github.com/yiyungent/PluginCore/commit/84550cc9159c387cedbc8beda282dfcfea9cdcb1)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.3.3](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.3.2..PluginCore.AspNetCore-v1.3.3) - 2023-12-14
-
-### Build
-
-- **(src/plugincore.aspnetcore/plugincore.aspnetcore.csproj)** packageReference update, 1.3.2->1.3.3 - ([6fc3d1a](https://github.com/yiyungent/PluginCore/commit/6fc3d1ad6359a5f8690babfc6949e0821d5bd6c5)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.3.2](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.3.1..PluginCore.AspNetCore-v1.3.2) - 2023-08-21
-
-### Features
-
-- **(src/plugincore.aspnetcore/extensions/plugincorestartupextensions.cs)** services: PluginFinder - ([144db05](https://github.com/yiyungent/PluginCore/commit/144db05576001a72f9cbd6beea0b3b5baa6a082c)) - yiyun
-
-### Build
-
-- **(src/plugincore.aspnetcore/plugincore.aspnetcore.csproj)** 1.3.2 - ([dfdd17d](https://github.com/yiyungent/PluginCore/commit/dfdd17dbcb2fc636cc102ab76497ff5768c64a4e)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.3.1](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.3.0..PluginCore.AspNetCore-v1.3.1) - 2023-02-15
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** `1.3.1` - ([39e0d03](https://github.com/yiyungent/PluginCore/commit/39e0d037c6f3e0dcf4845b5ca8ae2aa41142a474)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.3.0](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.2.0..PluginCore.AspNetCore-v1.3.0) - 2023-02-15
-
-### Bug Fixes
-
-- **(plugincore.aspnetcore,plugincore)** iList EnabledPlugins->List,IList不支持Remove - ([4d5d30e](https://github.com/yiyungent/PluginCore/commit/4d5d30e66c4c28998a7a6ac96bf3ffb25e4872b4)) - yiyun
-
-### Features
-
-- **(plugincore.aspnetcore,plugincore.iplugins,plugincore)** 仅保留已启用/已禁用 状态, IPlugin新方法 - ([e843a5b](https://github.com/yiyungent/PluginCore/commit/e843a5ba9fad4e88290c09bb3282b730c44c5a06)) - yiyun
-
-### Build
-
-- **(src/plugincore.aspnetcore/plugincore.aspnetcore.csproj)** `1.3.0` - ([64b9775](https://github.com/yiyungent/PluginCore/commit/64b977569312539aa2775235ae1f0fca5517ddcd)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.2.0](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.1.0..PluginCore.AspNetCore-v1.2.0) - 2023-02-14
-
-### Features
-
-- **(src/plugincore.aspnetcore/controllers/debugcontroller.cs)** pluginContexts:PluginId - ([f82b7b1](https://github.com/yiyungent/PluginCore/commit/f82b7b199420b15fc6f38e8f26c8094ee4be1b88)) - yiyun
-
-### Build
-
-- **(src/plugincore.aspnetcore/plugincore.aspnetcore.csproj)** 1.2.0 - ([fe418e0](https://github.com/yiyungent/PluginCore/commit/fe418e0f67dd8ed1fd2d78dc3f4106c8dc1a396b)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.1.0](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.0.4..PluginCore.AspNetCore-v1.1.0) - 2023-02-10
-
-### Features
-
-- **(src/plugincore.aspnetcore/)** update - ([52ee48f](https://github.com/yiyungent/PluginCore/commit/52ee48fe234040fd0cc0a4d21f3c2e1c9483735e)) - yiyun
-- **(src/plugincore.aspnetcore/controllers/debugcontroller.cs)** add - ([196823d](https://github.com/yiyungent/PluginCore/commit/196823d6e3b39eb70d1d4bb55d7d4c8433ee64fc)) - yiyun
-- **(src/plugincore.aspnetcore/controllers/debugcontroller.cs)** 完成 - ([2a2e213](https://github.com/yiyungent/PluginCore/commit/2a2e2131ee4b25912c16ca0d01ef408702cbfc39)) - yiyun
-- **(src/plugincore.aspnetcore/controllers/debugcontroller.cs)** services - ([22edc22](https://github.com/yiyungent/PluginCore/commit/22edc229c1bedc4667a920ef62c11c8e002ba9d2)) - yiyun
-
-### Build
-
-- **(src/plugincore.aspnetcore/plugincore.aspnetcore.csproj)** 1.1.0 - ([3bdb176](https://github.com/yiyungent/PluginCore/commit/3bdb17602c3258386711b200917e567c82dc442b)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.0.4](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.0.3..PluginCore.AspNetCore-v1.0.4) - 2023-01-12
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** 1.0.4 - ([46cf5dd](https://github.com/yiyungent/PluginCore/commit/46cf5dd5f955f6b648323e5216af97dd177e5a4b)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.0.3](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.0.2..PluginCore.AspNetCore-v1.0.3) - 2022-06-03
-
-### Bug Fixes
-
-- **(backgroundservices/plugintimejobbackgroundservice.cs)** 定时任务:强制GC回收,抑制内存++ - ([434e824](https://github.com/yiyungent/PluginCore/commit/434e82403b6aa2050945eeaa1131ea7965bdbc5f)) - yiyun
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** 1.0.3 - ([7da5638](https://github.com/yiyungent/PluginCore/commit/7da5638672571ca0ef057ebf73493260886b903e)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.0.2](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.0.1..PluginCore.AspNetCore-v1.0.2) - 2022-04-19
-
-### Features
-
-- **(plugincore.aspnetcore)** pluginsController: 移除: 插件上传大小限制 - ([90f8d67](https://github.com/yiyungent/PluginCore/commit/90f8d671a840ae8ca3688f4a5cbc22e568a6159e)) - yiyun
-
-### Style
-
-- add: copyright: *.cs - ([9643dce](https://github.com/yiyungent/PluginCore/commit/9643dce112861a440d63306cb555accbed3d5111)) - yiyun
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** 1.0.2 - ([b4eb1cc](https://github.com/yiyungent/PluginCore/commit/b4eb1cca9039ff95a516ba6d4000f10d156e03d0)) - yiyun
-- **(plugincore.aspnetcore/package.json,package-lock.json)** "plugincore-admin-frontend": "0.3.2" - ([7a70b20](https://github.com/yiyungent/PluginCore/commit/7a70b2003128bf569b4fdd4b7eaa662a92da8ee8)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.0.1](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v1.0.0..PluginCore.AspNetCore-v1.0.1) - 2022-04-17
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** 1.0.1 - ([ab348ce](https://github.com/yiyungent/PluginCore/commit/ab348ceca937f1b1f4ba8c83f4816b9a0ae7ea3e)) - yiyun
-
----
-## [PluginCore.AspNetCore-v1.0.0](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v0.0.5..PluginCore.AspNetCore-v1.0.0) - 2022-04-17
-
-### Bug Fixes
-
-- **(plugincore)** 临时修复由于 PluginContextManager 单例失败 导致的插件信息丢失 - ([fa613b4](https://github.com/yiyungent/PluginCore/commit/fa613b4c46e41c906fe955eb8f62c3f4937795bc)) - yiyun
-
-### Features
-
-- **(plugincore,plugincore.aspnetcore)** aspNetCorePluginManagerBeta,PluginLoadContext,PluginFinder - ([9d65a59](https://github.com/yiyungent/PluginCore/commit/9d65a590e3e0850251f6d815c322c7c5d9c7cf3f)) - yiyun
-- **(plugincore.aspnetcore)** add:DebugController.PluginContext - ([cd8de63](https://github.com/yiyungent/PluginCore/commit/cd8de636c8d7e2b125e11c6ce4091567cb97d4bc)) - yiyun
-- **(plugincore.aspnetcore)** commonResponseModel -> BaseResponseModel - ([1a0e834](https://github.com/yiyungent/PluginCore/commit/1a0e834b7dfdb45c45770d42b1733f1cb449a6ca)) - yiyun
-
-### Refactoring
-
-- **(plugincore.aspnetcore,plugincore)** 未完成 - ([a151bcd](https://github.com/yiyungent/PluginCore/commit/a151bcda125cb7e9b5fe11d44e1389afa7a1db5e)) - yiyun
-- **(plugincore.aspnetcore,plugincore)** 重构v2: 未测试 - ([53dde31](https://github.com/yiyungent/PluginCore/commit/53dde31116bd6455d33f7d7006b6fd1430f3694b)) - yiyun
-- **(plugincore.aspnetcore,plugincore)** 变量名,属性名,类名规范化 - ([eaadabf](https://github.com/yiyungent/PluginCore/commit/eaadabfd759228da245af1d9bd5b86e557540d28)) - yiyun
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** 1.0.0 - ([9b5caf4](https://github.com/yiyungent/PluginCore/commit/9b5caf4c4cdc543025c5493d35275a836cae61a9)) - yiyun
-
----
-## [PluginCore.AspNetCore-v0.0.5](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v0.0.4..PluginCore.AspNetCore-v0.0.5) - 2022-04-16
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** 0.0.5 - ([3e5cb09](https://github.com/yiyungent/PluginCore/commit/3e5cb0921a9faa33f93169c2d983011a1e8c5b5f)) - yiyun
-
----
-## [PluginCore.AspNetCore-v0.0.4](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v0.0.3..PluginCore.AspNetCore-v0.0.4) - 2022-04-16
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** 0.0.4 - ([adffab3](https://github.com/yiyungent/PluginCore/commit/adffab3fecee6696709c1d325b8c11e5a5389031)) - yiyun
-
----
-## [PluginCore.AspNetCore-v0.0.3](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v0.0.2..PluginCore.AspNetCore-v0.0.3) - 2022-04-16
-
-### Bug Fixes
-
-- **(plugincore.aspnetcore/extensions/plugincorestartupextensions.cs)** pluginFinder:TryAddTransient - ([03e9235](https://github.com/yiyungent/PluginCore/commit/03e9235c3c7fe68a3209cb1109792869e78aaa4e)) - yiyun
-- **(plugincore.aspnetcore/extensions/plugincorestartupextensions.cs)** 注释错误: 在程序启动时加载所有 已安装并启用 的插件 - ([844826a](https://github.com/yiyungent/PluginCore/commit/844826a630f99c2d866a98e6556404d4b1857e52)) - yiyun
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** 0.0.3 - ([ee81a45](https://github.com/yiyungent/PluginCore/commit/ee81a4536af17a85bbebc07bc0c980af8c00ad63)) - yiyun
-
----
-## [PluginCore.AspNetCore-v0.0.2](https://github.com/yiyungent/PluginCore/compare/PluginCore.AspNetCore-v0.0.1..PluginCore.AspNetCore-v0.0.2) - 2022-04-16
-
-### Refactoring
-
-- 1.提取出 PluginCore.AspNetCore,PluginCore.IPlugins.AspNetCore 2.提取出更多接口,可自由替换 - ([fffd8d9](https://github.com/yiyungent/PluginCore/commit/fffd8d91c23fd6e4a4d09cbf91975beb3cf7acf0)) - yiyun
-
-### Build
-
-- **(plugincore.aspnetcore.csproj)** 0.0.2 - ([ba7b274](https://github.com/yiyungent/PluginCore/commit/ba7b27496a4ba784c271305489b9f2f8e6f74ad3)) - yiyun
-
----
-## [PluginCore.AspNetCore-v0.0.1](https://github.com/yiyungent/PluginCore/compare/PluginCore-v0.9.3..PluginCore.AspNetCore-v0.0.1) - 2022-03-26
-
-### Features
-
-- **(plugincore.aspnetcore)** pluginCore.AspNetCore,PluginCore.AspNetCore-nuget-push.yml - ([491f63e](https://github.com/yiyungent/PluginCore/commit/491f63e3362129a2239d87b090aa04cc2e414e9a)) - yiyun
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/AppCenterController.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/AppCenterController.cs
deleted file mode 100644
index 762495f5..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/AppCenterController.cs
+++ /dev/null
@@ -1,207 +0,0 @@
-//===================================================
-// License: GNU LGPLv3
-// Contributors: yiyungent@gmail.com
-// Project: https://yiyungent.github.io/PluginCore
-// GitHub: https://github.com/yiyungent/PluginCore
-//===================================================
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Threading.Tasks;
-using PluginCore;
-using PluginCore.Models;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using PluginCore.AspNetCore.Authorization;
-using PluginCore.AspNetCore.ResponseModel;
-//using ResponseModel;
-
-
-namespace PluginCore.AspNetCore.Controllers
-{
- ///
- /// 应用中心
- /// 插件
- ///
- [Route("api/plugincore/admin/[controller]/[action]")]
- [PluginCoreAdminAuthorize]
- [ApiController]
- public class AppCenterController : ControllerBase
- {
- #region Fields
-
- private static Dictionary _pluginDownloadTasks;
-
- #endregion
-
- #region Ctor
-
- static AppCenterController()
- {
- _pluginDownloadTasks = new Dictionary();
- }
-
- public AppCenterController()
- {
-
- }
- #endregion
-
- #region Actions
-
- #region 插件列表
- ///
- /// 插件
- ///
- ///
- ///
- [HttpGet, HttpPost]
- public async Task> Plugins(string query = "")
- {
- BaseResponseModel responseDTO = new BaseResponseModel();
- IList pluginRegistryModels = new List();
- try
- {
- // 1. TODO: 从json文件中读取插件订阅源 registry url
- string registryUrl = "";
- // 2. TODO: 向订阅源发送 http get 获取插件列表信息 eg: http://rem-core-plugins-registry.moeci.com/?query=xxx
- IList remotePluginIds = new List();
-
- // 3. 根据本地已有 PluginId 插件情况 状态赋值
- PluginConfigModel pluginConfigModel = PluginConfigModelFactory.Create();
- // IList localPluginIds = pluginConfigModel.EnabledPlugins.Concat(pluginConfigModel.DisabledPlugins).Concat(pluginConfigModel.UninstalledPlugins).ToList();
- IList localPluginIds = PluginPathProvider.AllPluginFolderName();
-
-
-
- responseDTO.Code = 1;
- responseDTO.Message = "获取远程插件数据成功";
- responseDTO.Data = pluginRegistryModels;
- }
- catch (Exception ex)
- {
- responseDTO.Code = -1;
- responseDTO.Message = "获取远程插件数据失败: " + ex.Message;
- responseDTO.Data = pluginRegistryModels;
- }
-
- return await Task.FromResult(responseDTO);
- }
- #endregion
-
- #region 下载插件
- [HttpGet, HttpPost]
- public async Task> DownloadPlugin(string pluginDownloadUrl = "")
- {
- BaseResponseModel responseDTO = new BaseResponseModel();
-
- #region 效验
- if (string.IsNullOrEmpty(pluginDownloadUrl))
- {
- responseDTO.Code = -1;
- responseDTO.Message = "插件下载地址不正确";
- return responseDTO;
- }
- // TODO: 效验是否本地已经存在相同pluginId的插件
-
- #endregion
-
- try
- {
- // 1.执行下载操作, TODO:存在问题,阻塞对性能不好,但不阻塞又不好通知用户插件下载进度,以及可能存在在插件下载过程中,用户再次点击下载
- WebClient webClient = new WebClient();
- // TODO: 插件下载文件路径
- string pluginDownloadFilePath = "";
- //webClient.DownloadFileAsync(new Uri(pluginDownloadFilePath), "");
- Task task = webClient.DownloadFileTaskAsync(pluginDownloadUrl, pluginDownloadFilePath);
-
- _pluginDownloadTasks.Add(pluginDownloadUrl, task);
-
- webClient.DownloadFileCompleted += Plugin_DownloadFileCompleted;
- webClient.DownloadProgressChanged += Plugin_DownloadProgressChanged;
- webClient.Disposed += WebClient_Disposed;
-
- responseDTO.Code = 1;
- responseDTO.Message = "开始下载插件";
- }
- catch (Exception ex)
- {
- responseDTO.Code = -1;
- responseDTO.Message = "下载插件失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseDTO);
- }
-
-
-
-
- #endregion
-
- #region 获取插件下载进度
- [HttpGet, HttpPost]
- public async Task> DownloadPluginProgress()
- {
- BaseResponseModel responseDTO = new BaseResponseModel();
- try
- {
- responseDTO.Data = new { };
-
-
-
- responseDTO.Code = 1;
- responseDTO.Message = "获取插件下载进度成功";
- }
- catch (Exception ex)
- {
- responseDTO.Code = -1;
- responseDTO.Message = "获取插件下载进度失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseDTO);
- }
- #endregion
-
- #endregion
-
- #region Helpers
-
- ///
- /// 插件下载完成
- ///
- ///
- ///
- private void Plugin_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
- {
- Utils.LogUtil.Info("插件下载完成");
- // 1.从 _pluginDownloadTasks 中移除
- //_pluginDownloadTasks.Remove();
- // 2. 解压插件
-
- }
-
- private void Plugin_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
- {
- Utils.LogUtil.Info($"插件下载进度改变: {e.ProgressPercentage}% {e.BytesReceived}/{e.TotalBytesToReceive}");
- }
-
- private void WebClient_Disposed(object sender, EventArgs e)
- {
- if (sender is WebClient webClient)
- {
- Utils.LogUtil.Info(webClient.BaseAddress);
- }
-
- Utils.LogUtil.Info(nameof(WebClient_Disposed) + ": " + sender.ToString());
- }
-
- #endregion
-
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/DebugController.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/DebugController.cs
deleted file mode 100644
index a3ef7fc5..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/DebugController.cs
+++ /dev/null
@@ -1,280 +0,0 @@
-using System.Runtime.CompilerServices;
-//===================================================
-// License: GNU LGPLv3
-// Contributors: yiyungent@gmail.com
-// Project: https://yiyungent.github.io/PluginCore
-// GitHub: https://github.com/yiyungent/PluginCore
-//===================================================
-
-
-
-using Microsoft.AspNetCore.Mvc;
-using PluginCore.AspNetCore.Authorization;
-using PluginCore.AspNetCore.ResponseModel;
-using PluginCore.Interfaces;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using System.Linq;
-using System.Runtime.Loader;
-using Microsoft.Extensions.DependencyInjection;
-using System.Collections.Concurrent;
-using PluginCore.AspNetCore.Extensions;
-
-namespace PluginCore.AspNetCore.Controllers
-{
- ///
- /// [ASP.NET Core — 依赖注入\_啊晚的博客-CSDN博客\_asp.net core 依赖注入](https://blog.csdn.net/weixin_37648525/article/details/127942292)
- /// [ASP.NET Core中的依赖注入(3): 服务的注册与提供 - Artech - 博客园](https://www.cnblogs.com/artech/p/asp-net-core-di-register.html)
- /// [ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【总体设计 】 - Artech - 博客园](https://www.cnblogs.com/artech/p/asp-net-core-di-service-provider-1.html)
- /// [dotnet/ServiceProvider.cs at main · dotnet/dotnet](https://github.com/dotnet/dotnet/blob/main/src/runtime/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs)
- /// [Net6 DI源码分析Part2 Engine,ServiceProvider - 一身大膘 - 博客园](https://www.cnblogs.com/hts92/p/15800990.html)
- /// [【特别的骚气】asp.net core运行时注入服务,实现类库热插拔 - 四处观察 - 博客园](https://www.cnblogs.com/1996-Chinese-Chen/p/16154218.html)
- ///
- /// ActivatorUtilities.CreateInstance(serviceProvider, "test");
- /// ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider);
- ///
- ///
- [Route("api/plugincore/admin/[controller]/[action]")]
- [PluginCoreAdminAuthorize]
- [ApiController]
- public class DebugController : ControllerBase
- {
- #region Fields
- private readonly IPluginContextManager _pluginContextManager;
- #endregion
-
- #region Ctor
- public DebugController(IPluginContextManager pluginContextManager)
- {
- _pluginContextManager = pluginContextManager;
- }
- #endregion
-
- #region Actions
-
- [HttpGet, HttpPost]
- public async Task> PluginContexts()
- {
- BaseResponseModel responseModel = new BaseResponseModel();
- try
- {
- var pluginContextList = _pluginContextManager.All();
- Dictionary> keyValuePairs = new Dictionary>();
- foreach (var pluginContext in pluginContextList)
- {
- keyValuePairs.Add($"{pluginContext.GetType().ToString()} - {pluginContext.PluginId} - {pluginContext.GetHashCode()}", pluginContext.Assemblies.Select(m => m.FullName).ToList());
- }
-
- responseModel.Code = 1;
- responseModel.Message = "success";
- responseModel.Data = keyValuePairs;
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "error";
- responseModel.Data = ex.ToString();
- }
-
- return await Task.FromResult(responseModel);
- }
-
- [HttpGet, HttpPost]
- public async Task> AssemblyLoadContexts()
- {
- BaseResponseModel responseModel = new BaseResponseModel();
- try
- {
- var assemblyLoadContextDefault = AssemblyLoadContext.Default;
- var assemblyLoadContextAll = AssemblyLoadContext.All;
- var responseDataModel = new AssemblyLoadContextsResponseDataModel();
- responseDataModel.Default = new AssemblyLoadContextsResponseDataModel.AssemblyLoadContextModel
- {
- Name = assemblyLoadContextDefault.Name,
- Type = assemblyLoadContextDefault.GetType().ToString(),
- Assemblies = assemblyLoadContextDefault.Assemblies.Select(m => new AssemblyModel { FullName = m.FullName, DefinedTypes = m.DefinedTypes.Select(m => m.FullName).ToList() }).ToList()
- };
- responseDataModel.All = assemblyLoadContextAll.Select(item => new AssemblyLoadContextsResponseDataModel.AssemblyLoadContextModel
- {
- Name = item.Name,
- Type = item.GetType().ToString(),
- Assemblies = item.Assemblies.Select(m => new AssemblyModel { FullName = m.FullName, DefinedTypes = m.DefinedTypes.Select(m => m.FullName).ToList() }).ToList()
- }).ToList();
-
- responseModel.Code = 1;
- responseModel.Message = "success";
- responseModel.Data = responseDataModel;
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "error";
- responseModel.Data = ex.ToString();
- }
-
- return await Task.FromResult(responseModel);
- }
-
- [HttpGet, HttpPost]
- public async Task> Assemblies()
- {
- BaseResponseModel responseModel = new BaseResponseModel();
- try
- {
- var assemblies = AppDomain.CurrentDomain.GetAssemblies();
- List assemblyModels = new List();
- foreach (var item in assemblies)
- {
- assemblyModels.Add(new AssemblyModel
- {
- FullName = item.FullName,
- DefinedTypes = item.DefinedTypes.Select(m => m.FullName).ToList()
- });
- }
-
- responseModel.Code = 1;
- responseModel.Message = "success";
- responseModel.Data = assemblyModels;
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "error";
- responseModel.Data = ex.ToString();
- }
-
- return await Task.FromResult(responseModel);
- }
-
- [HttpGet, HttpPost]
- public async Task> Services([FromServices] IServiceProvider serviceProvider)
- {
- BaseResponseModel responseModel = new BaseResponseModel();
- try
- {
- //IServiceProvider serviceProvider = HttpContext.RequestServices;
- //var provider = serviceProvider.GetType().GetProperty("RootProvider", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
- //var serviceField = provider.GetType().GetField("_realizedServices", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
- //var serviceValue = serviceField.GetValue(provider);
- //var funcType = serviceField.FieldType.GetGenericArguments()[1].GetGenericArguments()[0];
- //ConcurrentDictionary> realizedServices = (ConcurrentDictionary>)serviceValue;
-
- // 获取所有已经注册的服务
- var allService = serviceProvider.GetAllServiceDescriptors();
-
- List serviceModels = new List();
- foreach (var item in allService)
- {
- serviceModels.Add(new ServiceModel
- {
- Type = item.Key.ToString(),
- ImplementationType = item.Value.ImplementationType?.ToString() ?? "",
- Lifetime = item.Value.Lifetime.ToString(),
- TypeAssembly = new AssemblyModel
- {
- FullName = item.Key.Assembly.FullName,
- },
- ImplementationTypeAssembly = new AssemblyModel
- {
- FullName = item.Value.ImplementationType?.Assembly?.FullName ?? ""
- }
- });
- }
-
- responseModel.Code = 1;
- responseModel.Message = "success";
- responseModel.Data = serviceModels;
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "error";
- responseModel.Data = ex.ToString();
- }
-
- return await Task.FromResult(responseModel);
- }
-
- #endregion
-
- public sealed class AssemblyLoadContextsResponseDataModel
- {
- public AssemblyLoadContextModel Default
- {
- get; set;
- }
-
- public List All
- {
- get; set;
- }
-
- public sealed class AssemblyLoadContextModel
- {
- public string Name
- {
- get; set;
- }
- public string Type
- {
- get; set;
- }
- public List Assemblies
- {
- get; set;
- }
- }
- }
-
- public sealed class AssembliesResponseDataModel
- {
-
- }
-
- public sealed class ServiceModel
- {
- public string Type
- {
- get; set;
- }
-
- public string ImplementationType
- {
- get; set;
- }
-
- public string Lifetime
- {
- get; set;
- }
-
- public AssemblyModel TypeAssembly
- {
- get; set;
- }
-
- public AssemblyModel ImplementationTypeAssembly
- {
- get; set;
- }
- }
-
- public sealed class AssemblyModel
- {
- public string FullName
- {
- get; set;
- }
-
- public List DefinedTypes
- {
- get; set;
- }
- }
-
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/HomeController.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/HomeController.cs
deleted file mode 100644
index 8b093c30..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/HomeController.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-//===================================================
-// License: GNU LGPLv3
-// Contributors: yiyungent@gmail.com
-// Project: https://yiyungent.github.io/PluginCore
-// GitHub: https://github.com/yiyungent/PluginCore
-//===================================================
-
-
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Net;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Mvc;
-
-namespace PluginCore.AspNetCore.Controllers
-{
- [Controller]
- public class HomeController : Controller
- {
- #region Old
- //private readonly IWebHostEnvironment _webHostEnvironment;
-
- //public bool IsLocalFronted
- //{
- // get
- // {
- // return PluginCore.Config.PluginCoreConfigFactory.Create().IsLocalFrontend;
- // }
- //}
-
- //public string RemoteFronted
- //{
- // get
- // {
- // return PluginCore.Config.PluginCoreConfigFactory.Create().RemoteFrontend;
- // }
- //}
-
- //public HomeController(IWebHostEnvironment webHostEnvironment)
- //{
- // this._webHostEnvironment = webHostEnvironment;
- //}
-
- //[Route("PluginCore/Admin")]
- //public async Task Home()
- //{
- // if (this.IsLocalFronted)
- // {
- // var localIndexFilePath = Path.Combine(
- // this._webHostEnvironment.ContentRootPath, "PluginCoreAdmin", "index.html");
-
- // return PhysicalFile(localIndexFilePath, "text/html");
- // }
- // else
- // {
- // string htmlStr = string.Empty;
- // HttpClient httpClient = new HttpClient();
- // htmlStr = await httpClient.GetStringAsync(this.RemoteFronted + "/index.html");
-
- // return Content(htmlStr, "text/html", Encoding.UTF8);
- // }
- //}
- #endregion
-
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/PluginWidgetController.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/PluginWidgetController.cs
deleted file mode 100644
index 0b00b6d4..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/PluginWidgetController.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-//===================================================
-// License: GNU LGPLv3
-// Contributors: yiyungent@gmail.com
-// Project: https://yiyungent.github.io/PluginCore
-// GitHub: https://github.com/yiyungent/PluginCore
-//===================================================
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Threading.Tasks;
-using PluginCore;
-using PluginCore.Models;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using PluginCore.AspNetCore.Authorization;
-using PluginCore.AspNetCore.ResponseModel;
-using PluginCore.IPlugins;
-using System.Text;
-using PluginCore.Interfaces;
-
-namespace PluginCore.AspNetCore.Controllers
-{
- [Route("api/plugincore/[controller]/[action]")]
- [ApiController]
- public class PluginWidgetController : ControllerBase
- {
- #region Fields
- private readonly IPluginFinder _pluginFinder;
- #endregion
-
- #region Ctor
- public PluginWidgetController(IPluginFinder pluginFinder)
- {
- _pluginFinder = pluginFinder;
- }
- #endregion
-
- #region Actions
-
- #region Widget
- ///
- /// Widget
- ///
- ///
- [HttpGet, HttpPost]
- //public async Task> Widget(string widgetKey, string extraPars = "")
- public async Task Widget(string widgetKey, string extraPars = "")
- {
- BaseResponseModel responseModel = new ResponseModel.BaseResponseModel();
- string responseData = "";
- widgetKey = widgetKey.Trim('"', '\'');
- string[] extraParsArr = null;
- if (!string.IsNullOrEmpty(extraPars))
- {
- extraParsArr = extraPars.Split(",", StringSplitOptions.RemoveEmptyEntries);
- extraParsArr = extraParsArr.Select(m => m.Trim('"', '\'')).ToArray();
- }
- StringBuilder sb = new StringBuilder();
- sb.AppendLine($"");
- try
- {
- List plugins = this._pluginFinder.EnablePlugins().ToList();
- foreach (var item in plugins)
- {
- string widgetStr = await item.Widget(widgetKey, extraParsArr);
- if (!string.IsNullOrEmpty(widgetStr))
- {
- // TODO: 配合 PluginCoreConfig.PluginWidgetDebug
- // TODO: PluginCoreConfig 改为 Options 模式, 避免手动反复读取文件 效率低
- //sb.AppendLine($"");
-
- sb.AppendLine(widgetStr);
- }
- }
-
- }
- catch (Exception ex)
- {
- Utils.LogUtil.Error(ex, ex.Message);
- sb.AppendLine($"");
- }
- sb.AppendLine($"");
- responseData = sb.ToString();
-
- responseModel.Code = 1;
- responseModel.Message = "Load Widget Success";
- responseModel.Data = responseData;
-
- //return await Task.FromResult(responseModel);
- return Content(responseData, "text/html;charset=utf-8");
- }
- #endregion
-
- #endregion
-
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/PluginsController.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/PluginsController.cs
deleted file mode 100644
index d6ddec27..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/PluginsController.cs
+++ /dev/null
@@ -1,688 +0,0 @@
-//===================================================
-// License: GNU LGPLv3
-// Contributors: yiyungent@gmail.com
-// Project: https://yiyungent.github.io/PluginCore
-// GitHub: https://github.com/yiyungent/PluginCore
-//===================================================
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-//using Core.Common;
-//using Framework.Authorization;
-using PluginCore;
-using PluginCore.Models;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using PluginCore.AspNetCore.Authorization;
-using PluginCore.Infrastructure;
-using PluginCore.IPlugins;
-using PluginCore.AspNetCore.ResponseModel;
-using PluginCore.Interfaces;
-using PluginCore.AspNetCore.Interfaces;
-
-//using ResponseModel;
-
-namespace PluginCore.AspNetCore.Controllers
-{
- [Route("api/plugincore/admin/[controller]/[action]")]
- [PluginCoreAdminAuthorize]
- [ApiController]
- public class PluginsController : ControllerBase
- {
- #region Fields
- private readonly IPluginManager _pluginManager;
- private readonly IPluginFinder _pluginFinder;
- private readonly IPluginApplicationBuilderManager _pluginApplicationBuilderManager;
- #endregion
-
- #region Ctor
- public PluginsController(IPluginManager pluginManager, IPluginFinder pluginFinder, IPluginApplicationBuilderManager pluginApplicationBuilderManager)
- {
- _pluginManager = pluginManager;
- _pluginFinder = pluginFinder;
- _pluginApplicationBuilderManager = pluginApplicationBuilderManager;
- }
- #endregion
-
- #region Actions
-
- #region 插件列表
- ///
- /// 加载插件列表
- ///
- /// 插件状态
- ///
- [HttpGet, HttpPost]
- public async Task> List(string status = "all")
- {
- BaseResponseModel responseData = new ResponseModel.BaseResponseModel();
- var pluginConfigModel = PluginConfigModelFactory.Create();
-
- // 获取所有插件信息
- IList pluginInfoModels = PluginInfoModelFactory.CreateAll();
- IList responseModels = new List();
- string[] enablePluginIds = _pluginFinder.EnablePluginIds().ToArray();
-
- // 添加插件状态
- responseModels = PluginInfoModelToResponseModel(pluginInfoModels, pluginConfigModel, enablePluginIds);
- #region 筛选插件状态
- switch (status.ToLower())
- {
- case "all":
- break;
- case "enabled":
- responseModels = responseModels.Where(m => m.Status == PluginStatus.Enabled).ToList();
- break;
- case "disabled":
- responseModels = responseModels.Where(m => m.Status == PluginStatus.Disabled).ToList();
- break;
- default:
- break;
- }
- #endregion
-
- responseData.Code = 1;
- responseData.Message = "加载插件列表成功";
- responseData.Data = responseModels;
-
- return await Task.FromResult(responseData);
- }
- #endregion
-
- #region 卸载插件
- [HttpGet, HttpPost]
- public async Task> Uninstall(string pluginId)
- {
- BaseResponseModel responseData = new BaseResponseModel();
- pluginId = pluginId.Trim();
- var pluginConfigModel = PluginConfigModelFactory.Create();
- // 卸载插件 必须 先禁用插件
- #region 效验
- if (pluginConfigModel.EnabledPlugins.Contains(pluginId))
- {
- responseData.Code = -1;
- responseData.Message = "卸载失败: 请先禁用此插件";
- return await Task.FromResult(responseData);
- }
- string pluginDirStr= Path.Combine(PluginPathProvider.PluginsRootPath(), pluginId);
- string pluginWwwrootDirStr = Path.Combine(PluginPathProvider.PluginsWwwRootDir(), pluginId);
- if (!Directory.Exists(pluginDirStr) && !Directory.Exists(pluginWwwrootDirStr))
- {
- responseData.Code = -2;
- responseData.Message = "卸载失败: 此插件不存在";
- return await Task.FromResult(responseData);
- }
- #endregion
-
- try
- {
- // PS:卸载插件必须先禁用插件,所以此时插件LoadContext已被移除释放(插件Assemblies已被释放), 此处不需移除LoadContext
-
- // 1.删除物理文件
- var pluginDir = new DirectoryInfo(pluginDirStr);
- if (pluginDir.Exists) {
- pluginDir.Delete(true);
- }
- // 虽然 已禁用 时 pluginWwwrootDirStr/pluginId 已删除, 但为确保, 还是再删除一次
- var pluginWwwrootDir = new DirectoryInfo(pluginWwwrootDirStr);
- if (pluginWwwrootDir.Exists) {
- pluginWwwrootDir.Delete(true);
- }
-
- responseData.Code = 1;
- responseData.Message = "卸载成功";
- }
- catch (Exception ex)
- {
- responseData.Code = -1;
- responseData.Message = "卸载失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseData);
- }
- #endregion
-
- #region 启用插件
- [HttpGet, HttpPost]
- public async Task> Enable(string pluginId)
- {
- BaseResponseModel responseData = new BaseResponseModel();
- var pluginConfigModel = PluginConfigModelFactory.Create();
- // 效验是否存在于 已禁用插件列表
- #region 效验
- pluginId = pluginId.Trim();
- var pluginDir = new DirectoryInfo(Path.Combine(PluginPathProvider.PluginsRootPath(), pluginId));
- if (pluginDir != null && !pluginDir.Exists)
- {
- responseData.Code = -1;
- responseData.Message = "启用失败: 此插件不存在";
- return await Task.FromResult(responseData);
- }
- string[] enablePluginIds = _pluginFinder.EnablePluginIds().ToArray();
- if (enablePluginIds.Contains(pluginId)) {
- responseData.Code = -2;
- responseData.Message = "启用失败: 此插件已启用";
- return await Task.FromResult(responseData);
- }
- #endregion
-
- try
- {
- // 1. 创建插件程序集加载上下文, 添加到 PluginsLoadContexts
- _pluginManager.LoadPlugin(pluginId);
- // 2. 添加到 pluginConfigModel.EnabledPlugins
- pluginConfigModel.EnabledPlugins.Add(pluginId);
- // 4.保存到 plugin.config.json
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- // 5. 找到此插件实例
- IPlugin plugin = _pluginFinder.Plugin(pluginId);
- if (plugin == null)
- {
- // 7.启用不成功, 回滚插件状态: (1)释放插件上下文 (2)更新 plugin.config.json
- try
- {
- _pluginManager.UnloadPlugin(pluginId);
- }
- catch (Exception ex)
- { }
-
- // 从 pluginConfigModel.EnabledPlugins 移除
- pluginConfigModel.EnabledPlugins.Remove(pluginId);
- // 保存到 plugin.config.json
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- responseData.Code = -1;
- responseData.Message = "启用失败: 此插件不存在";
- return await Task.FromResult(responseData);
- }
- // 6.调取插件的 AfterEnable(), 插件开发者可在此回收资源
- var pluginEnableResult = plugin.AfterEnable();
- if (!pluginEnableResult.IsSuccess)
- {
- // 7.启用不成功, 回滚插件状态: (1)释放插件上下文 (2)更新 plugin.config.json
- try
- {
- _pluginManager.UnloadPlugin(pluginId);
- }
- catch (Exception ex)
- { }
-
- // 从 pluginConfigModel.EnabledPlugins 移除
- pluginConfigModel.EnabledPlugins.Remove(pluginId);
- // 保存到 plugin.config.json
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- responseData.Code = -1;
- responseData.Message = "启用失败: 来自插件的错误信息: " + pluginEnableResult.Message;
- return await Task.FromResult(responseData);
- }
-
- // 7. ReBuild
- this._pluginApplicationBuilderManager.ReBuild();
-
- // 8. 尝试复制 插件下的 wwwroot 到 Plugins_wwwroot
- string wwwRootDir = PluginPathProvider.WwwRootDir(pluginId);
- if (Directory.Exists(wwwRootDir))
- {
- string targetDir = PluginPathProvider.PluginWwwRootDir(pluginId);
- Utils.FileUtil.CopyFolder(wwwRootDir, targetDir);
- }
-
- responseData.Code = 1;
- // responseData.Message = "启用成功";
- responseData.Message = pluginEnableResult.Message;
- }
- catch (Exception ex)
- {
- responseData.Code = -2;
- responseData.Message = "启用失败: " + ex.Message;
- Utils.LogUtil.Error(ex, ex.Message);
- }
-
- return await Task.FromResult(responseData);
- }
- #endregion
-
- #region 禁用插件
- [HttpGet, HttpPost]
- public async Task> Disable(string pluginId)
- {
- BaseResponseModel responseData = new BaseResponseModel();
- #region 效验
- pluginId = pluginId.Trim();
- var pluginConfigModel = PluginConfigModelFactory.Create();
- // string[] enablePluginIds = _pluginFinder.EnablePluginIds().ToArray();
- // // 效验是否存在于 已启用插件列表
- // if (!enablePluginIds.Contains(pluginId))
- // {
- // responseData.Code = -1;
- // responseData.Message = "禁用失败: 此插件不存在, 或未启用";
- // return await Task.FromResult(responseData);
- // }
- #endregion
-
- try
- {
- // 1. 找到此插件实例
- IPlugin plugin = _pluginFinder.Plugin(pluginId);
- if (plugin == null)
- {
- responseData.Code = -1;
- responseData.Message = "禁用失败: 此插件不存在, 或未启用";
- return await Task.FromResult(responseData);
- }
- string pluginDisableResultMessage = "";
- try
- {
- // 2.调取插件的 BeforeDisable(), 插件开发者可在此回收资源
- var pluginDisableResult = plugin.BeforeDisable();
- pluginDisableResultMessage = pluginDisableResult.Message;
- if (!pluginDisableResult.IsSuccess)
- {
- responseData.Code = -1;
- responseData.Message = "禁用失败: 来自插件的错误信息: " + pluginDisableResult.Message;
- return await Task.FromResult(responseData);
- }
- // 3.移除插件对应的程序集加载上下文
- _pluginManager.UnloadPlugin(pluginId);
- // 3.1. ReBuild
- this._pluginApplicationBuilderManager.ReBuild();
- if (pluginConfigModel.EnabledPlugins.Contains(pluginId)) {
- // 4.从 pluginConfigModel.EnabledPlugins 移除
- pluginConfigModel.EnabledPlugins.Remove(pluginId);
- // 5.保存到 plugin.config.json
- PluginConfigModelFactory.Save(pluginConfigModel);
- }
- }
- catch (Exception ex)
- {
- Utils.LogUtil.Error(ex, ex.Message);
- responseData.Code = -1;
- responseData.Message = "禁用失败: 此插件不存在, 或未启用";
- return await Task.FromResult(responseData);
- }
-
- // 7. 尝试移除 Plugins_wwwroot/PluginId
- string pluginWwwRootDir = PluginPathProvider.PluginWwwRootDir(pluginId);
- if (Directory.Exists(pluginWwwRootDir))
- {
- Directory.Delete(pluginWwwRootDir, true);
- }
-
-
- responseData.Code = 1;
- // responseData.Message = "禁用成功";
- responseData.Message = pluginDisableResultMessage;
- }
- catch (Exception ex)
- {
- responseData.Code = -2;
- responseData.Message = "禁用失败: " + ex.Message;
- Utils.LogUtil.Error(ex, ex.Message);
- }
-
- return await Task.FromResult(responseData);
- }
- #endregion
-
- #region 上传插件
- ///
- /// 上传插件
- ///
- /// 注意: 参数名一定为 file, 对应前端传过来时以 file 为名
- ///
- [HttpGet, HttpPost]
- public async Task> Upload(IFormFile file)
- {
- BaseResponseModel responseData = new BaseResponseModel();
-
- #region 效验
- if (file == null)
- {
- responseData.Code = -1;
- responseData.Message = "上传的文件不能为空";
- return responseData;
- }
- //文件后缀
- string fileExtension = Path.GetExtension(file.FileName);//获取文件格式,拓展名
- // 类型标记
- UploadFileType uploadFileType = UploadFileType.NoAllowedType;
- switch (fileExtension)
- {
- case ".zip":
- uploadFileType = UploadFileType.Zip;
- break;
- case ".nupkg":
- uploadFileType = UploadFileType.Nupkg;
- break;
- }
-
- if (fileExtension != ".zip" && fileExtension != ".nupkg")
- {
- responseData.Code = -1;
- // nupkg 其实就是 zip
- responseData.Message = "只能上传 zip 或 nupkg 格式文件";
- return responseData;
- }
- // PluginCore.AspNetCore-v1.0.2 起 不再限制插件上传大小
- //判断文件大小
- //var fileSize = file.Length;
- //if (fileSize > 1024 * 1024 * 5) // 5M
- //{
- // responseData.Code = -1;
- // responseData.Message = "上传的文件不能大于5MB";
- // return responseData;
- //}
- #endregion
-
- try
- {
- // 1.先上传到 临时插件上传目录, 用Guid.zip作为保存文件名
- string tempZipFilePath = Path.Combine(PluginPathProvider.TempPluginUploadDir(), Guid.NewGuid() + ".zip");
- using (var fs = System.IO.File.Create(tempZipFilePath))
- {
- file.CopyTo(fs); //将上传的文件文件流,复制到fs中
- fs.Flush();//清空文件流
- }
- // 2.解压
- bool isDecomparessSuccess = false;
- if (uploadFileType == UploadFileType.Zip)
- {
- isDecomparessSuccess = Utils.ZipHelper.DecomparessFile(tempZipFilePath, tempZipFilePath.Replace(".zip", ""));
- }
- else if (uploadFileType == UploadFileType.Nupkg)
- {
- isDecomparessSuccess = NupkgService.DecomparessFile(tempZipFilePath, tempZipFilePath.Replace(".zip", ""));
- }
-
- // 3.删除原压缩包
- System.IO.File.Delete(tempZipFilePath);
- if (!isDecomparessSuccess)
- {
- responseData.Code = -1;
- responseData.Message = "解压插件压缩包失败";
- return responseData;
- }
- // 4.读取其中的info.json, 获取 PluginId 值
- PluginInfoModel pluginInfoModel = PluginInfoModelFactory.ReadPluginDir(tempZipFilePath.Replace(".zip", ""));
- if (pluginInfoModel == null || string.IsNullOrEmpty(pluginInfoModel.PluginId))
- {
- // 记得删除已不再需要的临时插件文件夹
- Directory.Delete(tempZipFilePath.Replace(".zip", ""), true);
-
- responseData.Code = -1;
- responseData.Message = "不合法的插件";
- return responseData;
- }
- string pluginId = pluginInfoModel.PluginId;
- // 5.检索 此 PluginId 是否本地插件已存在
- var pluginConfigModel = PluginConfigModelFactory.Create();
- // 本地已经存在的 PluginId
- IList localExistPluginIds = PluginPathProvider.AllPluginFolderName();
- if (localExistPluginIds.Contains(pluginId))
- {
- // 记得删除已不再需要的临时插件文件夹
- Directory.Delete(tempZipFilePath.Replace(".zip", ""), true);
-
- responseData.Code = -1;
- responseData.Message = $"本地已有此插件 (PluginId: {pluginId}), 请前往插件列表删除后, 再上传";
- return responseData;
- }
- // 6.本地无此插件 -> 移动插件文件夹到 Plugins 下, 并以 PluginId 为插件文件夹名
- string pluginsRootPath = PluginPathProvider.PluginsRootPath();
- string newPluginDir = Path.Combine(pluginsRootPath, pluginId);
- Directory.Move(tempZipFilePath.Replace(".zip", ""), newPluginDir);
-
- // 7. 放入 Plugins 中, 默认为 已禁用
-
- responseData.Code = 1;
- responseData.Message = $"上传插件成功 (PluginId: {pluginId})";
- }
- catch (Exception ex)
- {
- responseData.Code = -1;
- responseData.Message = "上传插件失败: " + ex.Message;
- ex = ex.InnerException;
- while (ex != null)
- {
- responseData.Message += " - " + ex.InnerException.Message;
- ex = ex.InnerException;
- }
- Utils.LogUtil.Error(ex, ex.Message);
- }
-
- return await Task.FromResult(responseData);
- }
- #endregion
-
- #region 查看详细
- [HttpGet, HttpPost]
- public async Task> Details(string pluginId)
- {
- BaseResponseModel responseData = new BaseResponseModel();
-
- try
- {
- #region 效验
- pluginId = pluginId.Trim();
- var pluginConfigModel = PluginConfigModelFactory.Create();
- string[] localPluginIds = PluginPathProvider.AllPluginFolderName().ToArray();
-
- if (!localPluginIds.Contains(pluginId))
- {
- responseData.Code = -1;
- responseData.Message = $"查看详细失败: 不存在 {pluginId} 插件";
- return await Task.FromResult(responseData);
- }
-
- #endregion
-
- PluginInfoModel pluginInfoModel = PluginInfoModelFactory.Create(pluginId);
- string[] enablePluginIds = _pluginFinder.EnablePluginIds().ToArray();
- PluginInfoResponseModel pluginInfoResponseModel = PluginInfoModelToResponseModel(new List() { pluginInfoModel }, pluginConfigModel, enablePluginIds).FirstOrDefault();
-
-
- responseData.Code = 1;
- responseData.Message = "查看详细成功";
- responseData.Data = pluginInfoResponseModel;
- }
- catch (Exception ex)
- {
- responseData.Code = -1;
- responseData.Message = "查看详细失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseData);
- }
- #endregion
-
- #region 查看文档
- [HttpGet, HttpPost]
- public async Task> Readme(string pluginId)
- {
- BaseResponseModel responseData = new BaseResponseModel();
-
- try
- {
- #region 效验
- pluginId = pluginId.Trim();
- // var pluginConfigModel = PluginConfigModelFactory.Create();
- string[] localPluginIds = PluginPathProvider.AllPluginFolderName().ToArray();
-
- if (!localPluginIds.Contains(pluginId))
- {
- responseData.Code = -1;
- responseData.Message = $"查看文档失败: 不存在 {pluginId} 插件";
- return await Task.FromResult(responseData);
- }
-
- #endregion
-
- PluginReadmeModel readmeModel = PluginReadmeModelFactory.Create(pluginId);
- PluginReadmeResponseModel readmeResponseModel = new PluginReadmeResponseModel();
- readmeResponseModel.Content = readmeModel?.Content ?? "";
- readmeResponseModel.PluginId = pluginId;
-
- responseData.Code = 1;
- responseData.Message = "查看文档成功";
- responseData.Data = readmeResponseModel;
- }
- catch (Exception ex)
- {
- responseData.Code = -1;
- responseData.Message = "查看文档失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseData);
- }
- #endregion
-
- #region 设置
- [HttpGet]
- public async Task> Settings(string pluginId)
- {
- BaseResponseModel responseData = new BaseResponseModel();
-
- try
- {
- #region 效验
- pluginId = pluginId.Trim();
- // var pluginConfigModel = PluginConfigModelFactory.Create();
- string[] localPluginIds = PluginPathProvider.AllPluginFolderName().ToArray();
-
- if (!localPluginIds.Contains(pluginId))
- {
- responseData.Code = -1;
- responseData.Message = $"查看设置失败: 不存在 {pluginId} 插件";
- return await Task.FromResult(responseData);
- }
-
- #endregion
-
- string settingsJsonStr = PluginSettingsModelFactory.Create(pluginId);
-
-
- responseData.Code = 1;
- responseData.Message = "查看设置成功";
- responseData.Data = settingsJsonStr ?? "无设置项";
- }
- catch (Exception ex)
- {
- responseData.Code = -1;
- responseData.Message = "查看设置失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseData);
- }
-
- [HttpPost]
- public async Task> Settings(PluginSettingsInputModel inputModel)
- {
- BaseResponseModel responseData = new BaseResponseModel();
-
- try
- {
- #region 效验
- inputModel.PluginId = inputModel.PluginId.Trim();
- // var pluginConfigModel = PluginConfigModelFactory.Create();
- string[] localPluginIds = PluginPathProvider.AllPluginFolderName().ToArray();
-
- if (!localPluginIds.Contains(inputModel.PluginId))
- {
- responseData.Code = -1;
- responseData.Message = $"设置失败: 不存在 {inputModel.PluginId} 插件";
- return await Task.FromResult(responseData);
- }
-
- #endregion
-
- inputModel.Data = inputModel.Data ?? "";
- PluginSettingsModelFactory.Save(pluginSettingsJsonStr: inputModel.Data, pluginId: inputModel.PluginId);
-
-
- responseData.Code = 1;
- responseData.Message = "设置成功";
- responseData.Data = inputModel.Data;
- }
- catch (Exception ex)
- {
- responseData.Code = -1;
- responseData.Message = "设置失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseData);
- }
- #endregion
-
- #endregion
-
-
- #region Helpers
-
- [NonAction]
- private IList PluginInfoModelToResponseModel(IList pluginInfoModels, PluginConfigModel pluginConfigModel, string[] enablePluginIds)
- {
- // 获取 Plugins 下所有插件
- // DirectoryInfo pluginsDir = new DirectoryInfo(PluginPathProvider.PluginsRootPath());
- // List pluginIds = pluginsDir?.GetDirectories()?.Select(m => m.Name)?.ToList() ?? new List();
-
- IList responseModels = new List();
- #region 添加插件状态信息
- foreach (var model in pluginInfoModels)
- {
- PluginInfoResponseModel responseModel = new PluginInfoResponseModel();
- responseModel.Author = model.Author;
- responseModel.Description = model.Description;
- responseModel.DisplayName = model.DisplayName;
- responseModel.PluginId = model.PluginId;
- responseModel.SupportedVersions = model.SupportedVersions;
- responseModel.Version = model.Version;
- responseModel.DependPlugins = model.DependPlugins;
-
- if (pluginConfigModel.EnabledPlugins.Contains(model.PluginId) && !enablePluginIds.Contains(model.PluginId)) {
- // 错误情况: 配置 标识 已启用, 但实际没有启用成功
- pluginConfigModel.EnabledPlugins.Remove(model.PluginId);
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- responseModel.Status = PluginStatus.Disabled;
- } else if(!pluginConfigModel.EnabledPlugins.Contains(model.PluginId) && enablePluginIds.Contains(model.PluginId))
- {
- // 错误情况: 配置没有标识 已启用, 但实际 已启用
- pluginConfigModel.EnabledPlugins.Add(model.PluginId);
- PluginConfigModelFactory.Save(pluginConfigModel);
-
- responseModel.Status = PluginStatus.Enabled;
- } else if (pluginConfigModel.EnabledPlugins.Contains(model.PluginId) && enablePluginIds.Contains(model.PluginId))
- {
- responseModel.Status = PluginStatus.Enabled;
- }
- else
- {
- responseModel.Status = PluginStatus.Disabled;
- }
- responseModels.Add(responseModel);
- }
- #endregion
-
- return responseModels;
- }
-
- public enum UploadFileType
- {
- NoAllowedType = 0,
- Zip = 1,
- Nupkg = 2
- }
-
- #endregion
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/UserController.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/UserController.cs
deleted file mode 100644
index fa6193ed..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Controllers忽略/UserController.cs
+++ /dev/null
@@ -1,143 +0,0 @@
-//===================================================
-// License: GNU LGPLv3
-// Contributors: yiyungent@gmail.com
-// Project: https://yiyungent.github.io/PluginCore
-// GitHub: https://github.com/yiyungent/PluginCore
-//===================================================
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Mvc;
-using PluginCore.AspNetCore.Authorization;
-using PluginCore.Config;
-using PluginCore.AspNetCore.RequestModel.User;
-using PluginCore.AspNetCore.ResponseModel;
-
-namespace PluginCore.AspNetCore.Controllers
-{
- [Route("api/plugincore/admin/[controller]/[action]")]
- [ApiController]
- public class UserController : ControllerBase
- {
- private readonly AccountManager _accountManager;
-
- public string RemoteFronted
- {
- get
- {
- return PluginCore.Config.PluginCoreConfigFactory.Create().RemoteFrontend;
- }
- }
-
- public UserController(AccountManager accountManager)
- {
- _accountManager = accountManager;
- }
-
- [HttpGet, HttpPost]
- public async Task> Login([FromBody] LoginRequestModel requestModel)
- {
- BaseResponseModel responseModel = new BaseResponseModel();
-
- try
- {
- string token = AccountManager.CreateToken(requestModel.UserName, requestModel.Password);
- bool isAdmin = AccountManager.IsAdminToken(token);
- if (!isAdmin)
- {
- responseModel.Code = -1;
- responseModel.Message = "用户名或密码不正确";
-
- return await Task.FromResult(responseModel);
- }
-
- responseModel.Code = 1;
- responseModel.Message = "登录成功";
- responseModel.Data = new
- {
- token = token,
- userName = requestModel.UserName
- };
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseModel);
- }
-
- [HttpGet, HttpPost]
- public async Task> Logout()
- {
- BaseResponseModel responseModel = new BaseResponseModel()
- {
- Code = 1,
- Message = "退出登录成功"
- };
-
- return await Task.FromResult(responseModel);
- }
-
- [PluginCoreAdminAuthorize]
- [HttpGet, HttpPost]
- public async Task> Info()
- {
- BaseResponseModel responseModel = new BaseResponseModel();
-
- try
- {
- string adminUserName = PluginCoreConfigFactory.Create().Admin.UserName;
-
- responseModel.Code = 1;
- responseModel.Message = "成功";
- responseModel.Data = new
- {
- name = adminUserName,
- //avatar = this.RemoteFronted + "/images/avatar.gif"
- avatar = ""
- };
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseModel);
- }
-
- [PluginCoreAdminAuthorize]
- [HttpGet, HttpPost]
- public async Task> Update([FromBody] UpdateRequestModel requestModel)
- {
- BaseResponseModel responseModel = new BaseResponseModel();
-
- try
- {
- PluginCoreConfig pluginCoreConfig = PluginCoreConfigFactory.Create();
- pluginCoreConfig.Admin.UserName = requestModel.UserName;
- pluginCoreConfig.Admin.Password = requestModel.Password;
- PluginCoreConfigFactory.Save(pluginCoreConfig);
-
- responseModel.Code = 1;
- responseModel.Message = "修改成功, 需要重新登录";
- }
- catch (Exception ex)
- {
- responseModel.Code = -1;
- responseModel.Message = "失败: " + ex.Message;
- }
-
- return await Task.FromResult(responseModel);
- }
-
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Extensions/IServiceProviderExtensions.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Extensions/IServiceProviderExtensions.cs
deleted file mode 100644
index 0c4d8826..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Extensions/IServiceProviderExtensions.cs
+++ /dev/null
@@ -1,158 +0,0 @@
-// Admin.NET ĿİȨ̱ꡢרȨӦɷıʹñĿӦطɷ֤Ҫ
-//
-// ĿҪѭ MIT ֤ Apache ֤汾 2.0зַʹá֤λԴĿ¼е LICENSE-MIT LICENSE-APACHE ļ
-//
-// ñĿΣҰȫַ˺ϷȨȷɷֹĻκλڱĿοһзɾΣDzеκΣ
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Text;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace PluginCore.AspNetCore.Extensions
-{
- public static class IServiceProviderExtensions
- {
- ///
- /// Get all registered
- ///
- ///
- ///
- public static Dictionary GetAllServiceDescriptors(this IServiceProvider provider)
- {
- var serviceProvider = provider.GetPropertyValue("RootProvider");
- var result = new Dictionary();
-
- var engine = serviceProvider.GetFieldValue("_engine");
- // var callSiteFactory = engine.GetPropertyValue("CallSiteFactory");
- var callSiteFactory = serviceProvider.GetPropertyValue("CallSiteFactory");
- var descriptorLookup = callSiteFactory.GetFieldValue("_descriptorLookup");
- if (descriptorLookup is IDictionary dictionary)
- {
- foreach (DictionaryEntry entry in dictionary)
- {
- result.Add((Type)entry.Key, (ServiceDescriptor)entry.Value.GetPropertyValue("Last"));
- }
- }
-
- return result;
-
- #region Old
- //if (provider is ServiceProvider serviceProvider)
- //{
- // var result = new Dictionary();
-
- // var engine = serviceProvider.GetFieldValue("_engine");
- // var callSiteFactory = engine.GetPropertyValue("CallSiteFactory");
- // var descriptorLookup = callSiteFactory.GetFieldValue("_descriptorLookup");
- // if (descriptorLookup is IDictionary dictionary)
- // {
- // foreach (DictionaryEntry entry in dictionary)
- // {
- // result.Add((Type)entry.Key, (ServiceDescriptor)entry.Value.GetPropertyValue("Last"));
- // }
- // }
-
- // return result;
- //}
-
- //throw new NotSupportedException($"Type '{provider.GetType()}' is not supported!");
- #endregion
- }
- }
-
- public static class ReflectionHelper
- {
- // ##########################################################################################
- // Get / Set Field
- // ##########################################################################################
-
- #region Get / Set Field
-
- public static object GetFieldValue(this object obj, string fieldName)
- {
- if (obj == null)
- throw new ArgumentNullException(nameof(obj));
- Type objType = obj.GetType();
- var fieldInfo = GetFieldInfo(objType, fieldName);
- if (fieldInfo == null)
- throw new ArgumentOutOfRangeException(fieldName,
- $"Couldn't find field {fieldName} in type {objType.FullName}");
- return fieldInfo.GetValue(obj);
- }
-
- public static void SetFieldValue(this object obj, string fieldName, object val)
- {
- if (obj == null)
- throw new ArgumentNullException(nameof(obj));
- Type objType = obj.GetType();
- var fieldInfo = GetFieldInfo(objType, fieldName);
- if (fieldInfo == null)
- throw new ArgumentOutOfRangeException(fieldName,
- $"Couldn't find field {fieldName} in type {objType.FullName}");
- fieldInfo.SetValue(obj, val);
- }
-
- private static FieldInfo GetFieldInfo(Type type, string fieldName)
- {
- FieldInfo fieldInfo = null;
- do
- {
- fieldInfo = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
- type = type.BaseType;
- } while (fieldInfo == null && type != null);
-
- return fieldInfo;
- }
-
- #endregion
-
- // ##########################################################################################
- // Get / Set Property
- // ##########################################################################################
-
- #region Get / Set Property
-
- public static object GetPropertyValue(this object obj, string propertyName)
- {
- if (obj == null)
- throw new ArgumentNullException(nameof(obj));
- Type objType = obj.GetType();
- var propertyInfo = GetPropertyInfo(objType, propertyName);
- if (propertyInfo == null)
- throw new ArgumentOutOfRangeException(propertyName,
- $"Couldn't find property {propertyName} in type {objType.FullName}");
- return propertyInfo.GetValue(obj, null);
- }
-
- public static void SetPropertyValue(this object obj, string propertyName, object val)
- {
- if (obj == null)
- throw new ArgumentNullException(nameof(obj));
- Type objType = obj.GetType();
- var propertyInfo = GetPropertyInfo(objType, propertyName);
- if (propertyInfo == null)
- throw new ArgumentOutOfRangeException(propertyName,
- $"Couldn't find property {propertyName} in type {objType.FullName}");
- propertyInfo.SetValue(obj, val, null);
- }
-
- private static PropertyInfo GetPropertyInfo(Type type, string propertyName)
- {
- PropertyInfo propertyInfo = null;
- do
- {
- propertyInfo = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
- type = type.BaseType;
- } while (propertyInfo == null && type != null);
-
- return propertyInfo;
- }
-
- #endregion
- }
-}
-
-
diff --git a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Extensions/PluginCoreStartupExtensions.cs b/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Extensions/PluginCoreStartupExtensions.cs
deleted file mode 100644
index 6b03a645..00000000
--- a/Admin.NET/Plugins/PluginCore/PluginCore.AspNetCore/Extensions/PluginCoreStartupExtensions.cs
+++ /dev/null
@@ -1,415 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-
-
-using PluginCore.Models;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Mvc.Infrastructure;
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Authorization;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.DependencyInjection.Extensions;
-using Microsoft.Extensions.FileProviders;
-using PluginCore.AspNetCore.Authorization;
-using PluginCore.AspNetCore.AdminUI;
-using PluginCore.Infrastructure;
-using PluginCore.Interfaces;
-using PluginCore.AspNetCore.Middlewares;
-using PluginCore.AspNetCore.BackgroundServices;
-using PluginCore.IPlugins;
-using PluginCore.AspNetCore.Interfaces;
-using PluginCore.lmplements;
-using PluginCore.AspNetCore.lmplements;
-
-namespace PluginCore.AspNetCore.Extensions
-{
- ///
- ///
- ///
- public static class PluginCoreStartupExtensions
- {
- private static IWebHostEnvironment _webHostEnvironment;
-
- private static IServiceCollection _services;
-
- private static IServiceProvider _serviceProvider;
-
- ///
- /// 若需要替换默认实现, 请在 之前, 若在之后, 则无法影响 主程序启动时默认行为
- ///
- ///
- public static void AddPluginCore(this IServiceCollection services)
- {
- services.AddPluginCoreServices();
-
- services.AddPluginCoreLog();
-
- services.AddPluginCorePlugins();
-
- #region PluginCore Admin 权限
- // 1. 先 Authentication (我是谁) 2. 再 Authorization (我能做什么)
-
- // Authentication
- //注销内置认证 by tomny
- // services.AddPluginCoreAuthentication();
- //注销内置授权 by tomny
- // Authorization
- //services.AddPluginCoreAuthorization();
- #endregion
-
- services.AddPluginCoreStartupPlugin();
-
- // AddBackgroundServices
- services.AddBackgroundServices();
-
- // 一定要在最后
- _services = services;
- _serviceProvider = services.BuildServiceProvider();
- }
-
- public static IApplicationBuilder UsePluginCore(this IApplicationBuilder app)
- {
- // 一定在 PluginCore 添加的中间件中 第一个
- app.UseMiddleware();
-
- app.UsePluginCoreLanguageMiddleware();
- //注销内置管理页面 by tomny
- // app.UsePluginCoreAdminUI();
-
- app.UsePluginCoreStaticFiles();
-
- // 发现 UseAuthentication 认证中间件重复添加, 也只会执行一次 认证
- // 但 UseAuthorization 重复添加2次, 则会执行 2次 授权
- //注销内置认证授权 by tomny
- //app.UseAuthentication();
- //app.UseAuthorization();
-
- #region Plugin Middleware
- // Plugin Middleware
- //app.UseMiddleware();
-
-
- // 一定在 PluginCore 添加的中间件中 最后一个
- app.UseMiddleware();
- #endregion
-
- app.UsePluginCoreStartupPlugin();
-
- app.UsePluginCoreAppStart();
-
- // Log
- app.UsePluginCoreLog();
-
- return app;
- }
-
-
- public static void AddPluginCoreServices(this IServiceCollection services)
- {
- #region 注册服务
-
- #region 仅适用于 ASP.NET Core
- // start: 仅用于 ASP.NET Core
- // 用于添加插件Controller 时,通知Controller.Action发生变化
- services.AddSingleton(PluginActionDescriptorChangeProvider.Instance);
- services.AddSingleton(PluginActionDescriptorChangeProvider.Instance);
-
- services.TryAddTransient();
- services.TryAddTransient();
-
- services.TryAddTransient();
- services.TryAddTransient();
- // end: 仅用于 ASP.NET Core
- #endregion
-
- #region 通用
-
- // v1 旧版
- //services.TryAddTransient();
- //services.TryAddTransient();
- //services.TryAddTransient();
- //services.TryAddTransient();
-
- services.TryAddTransient();
- services.TryAddTransient();
- //注销内置插件管理 by tomny
- services.TryAddTransient();
- services.TryAddTransient();
-
- services.TryAddTransient();
- services.TryAddTransient();
- services.TryAddTransient();
- services.TryAddTransient