!92 feat(#I4M1N3): 增加 Blazor 工程准备集成 BootstrapBlazor 组件库
* chore: 更新过滤解决方案文件 * refactor: 重新整理项目结构 * refactor: 改用 Update 方法 * refactor: 代码重构 * chore: 移除不使用的组件 * chore: 更新数据服务 * wip: 临时提交 * chore: 首页更新路由 * chore: 增加过滤项目文件 * feat: 更新菜单组件 * refactor: 移除不用的组件 * feat: 增加 BootstrapAppContext 服务 * refactor: 移除命名空间 * !91 feat(#I4LVUZ): 增加用户维护界面 * !90 feat(#I4LVUW): 增加字典表维护页面 * feat: 初始化 Blazor 版本
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"solution": {
|
||||
"path": "BootstrapAdmin.sln",
|
||||
"projects": [
|
||||
"src\\blazor\\admin\\Bootstrap.Admin.Blazor.DataAccess\\Bootstrap.Admin.Blazor.DataAccess.csproj",
|
||||
"src\\blazor\\admin\\Bootstrap.Admin.Blazor\\Bootstrap.Admin.Blazor.csproj",
|
||||
"src\\mvc\\admin\\Bootstrap.Admin\\Bootstrap.Admin.csproj",
|
||||
"src\\mvc\\admin\\Bootstrap.DataAccess\\Bootstrap.DataAccess.csproj"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29215.179
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SQLServer", "SQLServer", "{87319AF5-7C40-4362-B67C-35F9DD737DB4}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
|
@ -10,15 +10,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SQLServer", "SQLServer", "{
|
|||
db\SqlServer\Install.sql = db\SqlServer\Install.sql
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Admin", "src\admin\Bootstrap.Admin\Bootstrap.Admin.csproj", "{7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Admin", "src\mvc\admin\Bootstrap.Admin\Bootstrap.Admin.csproj", "{7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "db", "db", "{586410F2-C1F0-47CD-AB28-2CF506DED2C8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client", "src\client\Bootstrap.Client\Bootstrap.Client.csproj", "{C82A6E45-AB90-43D1-8429-5CBE953D8151}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client", "src\mvc\client\Bootstrap.Client\Bootstrap.Client.csproj", "{C82A6E45-AB90-43D1-8429-5CBE953D8151}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "client", "client", "{C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.DataAccess", "src\admin\Bootstrap.DataAccess\Bootstrap.DataAccess.csproj", "{8D62BE79-BE13-43C8-969B-C9B00B3C84B7}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.DataAccess", "src\mvc\admin\Bootstrap.DataAccess\Bootstrap.DataAccess.csproj", "{8D62BE79-BE13-43C8-969B-C9B00B3C84B7}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SQLite", "SQLite", "{523515EC-2AD7-4282-9AF4-9D20371183B0}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
|
@ -26,7 +26,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SQLite", "SQLite", "{523515
|
|||
db\SQLite\Install.sql = db\SQLite\Install.sql
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.DataAccess.MongoDB", "src\admin\Bootstrap.DataAccess.MongoDB\Bootstrap.DataAccess.MongoDB.csproj", "{8336F096-4B4A-4710-A1FA-0F5E44CD8D26}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.DataAccess.MongoDB", "src\mvc\admin\Bootstrap.DataAccess.MongoDB\Bootstrap.DataAccess.MongoDB.csproj", "{8336F096-4B4A-4710-A1FA-0F5E44CD8D26}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MongoDB", "MongoDB", "{A06A0AD8-A246-4329-B024-7174AE4A3EDE}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
|
@ -57,9 +57,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Postgresql", "Postgresql",
|
|||
db\Postgresql\install.sql = db\Postgresql\install.sql
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client.DataAccess", "src\client\Bootstrap.Client.DataAccess\Bootstrap.Client.DataAccess.csproj", "{843811A2-FE49-410F-BF9F-9F1FB14A1DEE}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client.DataAccess", "src\mvc\client\Bootstrap.Client.DataAccess\Bootstrap.Client.DataAccess.csproj", "{843811A2-FE49-410F-BF9F-9F1FB14A1DEE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client.DataAccess.MongoDB", "src\client\Bootstrap.Client.DataAccess.MongoDB\Bootstrap.Client.DataAccess.MongoDB.csproj", "{BC1C6D63-ADA9-4C3B-89F0-CEB191A86BF5}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client.DataAccess.MongoDB", "src\mvc\client\Bootstrap.Client.DataAccess.MongoDB\Bootstrap.Client.DataAccess.MongoDB.csproj", "{BC1C6D63-ADA9-4C3B-89F0-CEB191A86BF5}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{6AD32A76-F3AA-423E-96EA-E5CC679934D1}"
|
||||
EndProject
|
||||
|
@ -74,9 +74,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{E057452E-0
|
|||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{85574E7C-7D58-4135-AB4B-76678552D271}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
src\admin\Bootstrap.Admin\Dockerfile = src\admin\Bootstrap.Admin\Dockerfile
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "srcipts", "srcipts", "{72C103DB-E1D3-449F-97C2-DF12CA111FD4}"
|
||||
EndProject
|
||||
|
@ -130,9 +127,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "git", "git", "{64EACBD1-23D
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "blazor", "blazor", "{DAE3826B-AAAB-468A-9A06-2F56EF5C0767}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client.Blazor", "src\blazor\Bootstrap.Client.Blazor\Bootstrap.Client.Blazor.csproj", "{90BC5C25-0F93-4CDE-833C-3D8243E19D3B}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client.Blazor", "src\blazor\client\Bootstrap.Client.Blazor\Bootstrap.Client.Blazor.csproj", "{90BC5C25-0F93-4CDE-833C-3D8243E19D3B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client.Blazor.Shared", "src\blazor\Bootstrap.Client.Blazor.Shared\Bootstrap.Client.Blazor.Shared.csproj", "{B306BD58-1C73-40F2-86F7-E1763344007B}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client.Blazor.Shared", "src\blazor\client\Bootstrap.Client.Blazor.Shared\Bootstrap.Client.Blazor.Shared.csproj", "{B306BD58-1C73-40F2-86F7-E1763344007B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "github", "github", "{C07631B9-5E5E-417A-9A16-3C88956D574E}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
|
@ -140,6 +137,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "github", "github", "{C07631
|
|||
.github\workflows\docker.yml = .github\workflows\docker.yml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Admin.Blazor", "src\blazor\admin\Bootstrap.Admin.Blazor\Bootstrap.Admin.Blazor.csproj", "{485C1B75-7E3C-4AFC-8A91-2347FFEC1E96}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mvc", "mvc", "{C996F427-DA93-49D6-9804-4E665D195FC2}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "admin", "admin", "{45ADEF9B-C8BD-4224-9E12-F6716E85A22C}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "client", "client", "{55A2459A-6BDE-4493-B2C0-5BE1673E99EE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bootstrap.Admin.Blazor.DataAccess", "src\blazor\admin\Bootstrap.Admin.Blazor.DataAccess\Bootstrap.Admin.Blazor.DataAccess.csproj", "{75730767-A53A-4CFB-BACB-B90401288FA6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -182,6 +189,14 @@ Global
|
|||
{B306BD58-1C73-40F2-86F7-E1763344007B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B306BD58-1C73-40F2-86F7-E1763344007B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B306BD58-1C73-40F2-86F7-E1763344007B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{485C1B75-7E3C-4AFC-8A91-2347FFEC1E96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{485C1B75-7E3C-4AFC-8A91-2347FFEC1E96}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{485C1B75-7E3C-4AFC-8A91-2347FFEC1E96}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{485C1B75-7E3C-4AFC-8A91-2347FFEC1E96}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{75730767-A53A-4CFB-BACB-B90401288FA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{75730767-A53A-4CFB-BACB-B90401288FA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{75730767-A53A-4CFB-BACB-B90401288FA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{75730767-A53A-4CFB-BACB-B90401288FA6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -190,7 +205,7 @@ Global
|
|||
{87319AF5-7C40-4362-B67C-35F9DD737DB4} = {586410F2-C1F0-47CD-AB28-2CF506DED2C8}
|
||||
{7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A} = {E03B7391-B52F-4449-B400-5CD9DE01F085}
|
||||
{C82A6E45-AB90-43D1-8429-5CBE953D8151} = {C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0}
|
||||
{C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0} = {41B6D37A-5E5E-42B3-85E4-D81A81E3D757}
|
||||
{C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0} = {C996F427-DA93-49D6-9804-4E665D195FC2}
|
||||
{8D62BE79-BE13-43C8-969B-C9B00B3C84B7} = {E03B7391-B52F-4449-B400-5CD9DE01F085}
|
||||
{523515EC-2AD7-4282-9AF4-9D20371183B0} = {586410F2-C1F0-47CD-AB28-2CF506DED2C8}
|
||||
{8336F096-4B4A-4710-A1FA-0F5E44CD8D26} = {E03B7391-B52F-4449-B400-5CD9DE01F085}
|
||||
|
@ -200,7 +215,7 @@ Global
|
|||
{6F61C2AC-84D4-48A9-8A48-680657CC8175} = {586410F2-C1F0-47CD-AB28-2CF506DED2C8}
|
||||
{843811A2-FE49-410F-BF9F-9F1FB14A1DEE} = {C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0}
|
||||
{BC1C6D63-ADA9-4C3B-89F0-CEB191A86BF5} = {C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0}
|
||||
{E03B7391-B52F-4449-B400-5CD9DE01F085} = {41B6D37A-5E5E-42B3-85E4-D81A81E3D757}
|
||||
{E03B7391-B52F-4449-B400-5CD9DE01F085} = {C996F427-DA93-49D6-9804-4E665D195FC2}
|
||||
{C6F2DCA0-7941-4C28-9328-2D495F5DCB00} = {72C103DB-E1D3-449F-97C2-DF12CA111FD4}
|
||||
{FDCFC3E3-14CF-40B2-9FE5-5BC239AAC110} = {72C103DB-E1D3-449F-97C2-DF12CA111FD4}
|
||||
{5F732D4E-133B-4DA6-811B-C369CDC3FB89} = {72C103DB-E1D3-449F-97C2-DF12CA111FD4}
|
||||
|
@ -208,8 +223,13 @@ Global
|
|||
{41E078CA-F005-4B66-B440-FD7EB731AD61} = {586410F2-C1F0-47CD-AB28-2CF506DED2C8}
|
||||
{64EACBD1-23DD-4168-BEED-55D47DB1A8BB} = {72C103DB-E1D3-449F-97C2-DF12CA111FD4}
|
||||
{DAE3826B-AAAB-468A-9A06-2F56EF5C0767} = {41B6D37A-5E5E-42B3-85E4-D81A81E3D757}
|
||||
{90BC5C25-0F93-4CDE-833C-3D8243E19D3B} = {DAE3826B-AAAB-468A-9A06-2F56EF5C0767}
|
||||
{B306BD58-1C73-40F2-86F7-E1763344007B} = {DAE3826B-AAAB-468A-9A06-2F56EF5C0767}
|
||||
{90BC5C25-0F93-4CDE-833C-3D8243E19D3B} = {55A2459A-6BDE-4493-B2C0-5BE1673E99EE}
|
||||
{B306BD58-1C73-40F2-86F7-E1763344007B} = {55A2459A-6BDE-4493-B2C0-5BE1673E99EE}
|
||||
{485C1B75-7E3C-4AFC-8A91-2347FFEC1E96} = {45ADEF9B-C8BD-4224-9E12-F6716E85A22C}
|
||||
{C996F427-DA93-49D6-9804-4E665D195FC2} = {41B6D37A-5E5E-42B3-85E4-D81A81E3D757}
|
||||
{45ADEF9B-C8BD-4224-9E12-F6716E85A22C} = {DAE3826B-AAAB-468A-9A06-2F56EF5C0767}
|
||||
{55A2459A-6BDE-4493-B2C0-5BE1673E99EE} = {DAE3826B-AAAB-468A-9A06-2F56EF5C0767}
|
||||
{75730767-A53A-4CFB-BACB-B90401288FA6} = {45ADEF9B-C8BD-4224-9E12-F6716E85A22C}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {221EAE38-5F75-4391-9A48-E462A9F3B8FC}
|
||||
|
|
|
@ -11,17 +11,17 @@
|
|||
|
||||
<Target Condition=" $(IsWebProject) == true Or $(IsTestProject) == true" Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Message Text="Copy lic file -> $(TargetDir)" Importance="high" />
|
||||
<Copy Condition="'$(OS)' == 'Windows_NT'" DestinationFolder="$(TargetDir)" SourceFiles="$(MSBuildThisFileDirectory)src\admin\keys\Longbow.lic" SkipUnchangedFiles="true" />
|
||||
<Copy Condition="'$(OS)' == 'UNIX'" DestinationFolder="$(TargetDir)" SourceFiles="$(MSBuildThisFileDirectory)src/admin/keys/Longbow.lic" SkipUnchangedFiles="true" />
|
||||
<Copy Condition="'$(OS)' == 'Windows_NT'" DestinationFolder="$(TargetDir)" SourceFiles="$(MSBuildThisFileDirectory)src\mvc\admin\keys\Longbow.lic" SkipUnchangedFiles="true" />
|
||||
<Copy Condition="'$(OS)' == 'UNIX'" DestinationFolder="$(TargetDir)" SourceFiles="$(MSBuildThisFileDirectory)src/mvc/admin/keys/Longbow.lic" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
|
||||
<Target Condition=" $(IsWebProject) == true " Name="PostPublish" AfterTargets="Publish">
|
||||
<Message Text="Publish lic file -> $(PublishDir)" Importance="high" />
|
||||
<Copy Condition="'$(OS)' == 'Windows_NT'" DestinationFolder="$(PublishDir)" SourceFiles="$(MSBuildThisFileDirectory)src\admin\keys\Longbow.lic" SkipUnchangedFiles="true" />
|
||||
<Copy Condition="'$(OS)' == 'UNIX'" DestinationFolder="$(PublishDir)" SourceFiles="$(MSBuildThisFileDirectory)src/admin/keys/Longbow.lic" SkipUnchangedFiles="true" />
|
||||
<Copy Condition="'$(OS)' == 'Windows_NT'" DestinationFolder="$(PublishDir)" SourceFiles="$(MSBuildThisFileDirectory)src\mvc\admin\keys\Longbow.lic" SkipUnchangedFiles="true" />
|
||||
<Copy Condition="'$(OS)' == 'UNIX'" DestinationFolder="$(PublishDir)" SourceFiles="$(MSBuildThisFileDirectory)src/mvc/admin/keys/Longbow.lic" SkipUnchangedFiles="true" />
|
||||
<Message Text="Publish db file -> $(PublishDir)" Importance="high" />
|
||||
<Copy Condition="'$(OS)' == 'Windows_NT'" DestinationFolder="$(PublishDir)" SourceFiles="$(MSBuildThisFileDirectory)src\admin\Bootstrap.Admin\BootstrapAdmin.db" SkipUnchangedFiles="true" />
|
||||
<Copy Condition="'$(OS)' == 'UNIX'" DestinationFolder="$(PublishDir)" SourceFiles="$(MSBuildThisFileDirectory)src/admin/Bootstrap.Admin/BootstrapAdmin.db" SkipUnchangedFiles="true" />
|
||||
<Copy Condition="'$(OS)' == 'Windows_NT'" DestinationFolder="$(PublishDir)" SourceFiles="$(MSBuildThisFileDirectory)src\mvc\admin\Bootstrap.Admin\BootstrapAdmin.db" SkipUnchangedFiles="true" />
|
||||
<Copy Condition="'$(OS)' == 'UNIX'" DestinationFolder="$(PublishDir)" SourceFiles="$(MSBuildThisFileDirectory)src/mvc/admin/Bootstrap.Admin/BootstrapAdmin.db" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
<Import Project="..\Directory.Build.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<PackageProjectUrl>https://gitee.com/LongbowEnterprise/BootstrapAdmin</PackageProjectUrl>
|
||||
<RepositoryUrl>https://gitee.com/LongbowEnterprise/BootstrapAdmin.git</RepositoryUrl>
|
||||
|
@ -10,8 +14,4 @@
|
|||
<DocumentationFile>$(MSBuildProjectName).xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="PetaPoco.Extensions" Version="5.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
|
||||
using PetaPoco;
|
||||
|
||||
namespace Bootstrap.Admin.Blazor.DataAccess
|
||||
{
|
||||
/// <summary>
|
||||
/// 字典配置项
|
||||
/// </summary>
|
||||
[TableName("Dicts")]
|
||||
public class Dict
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 字典主键 数据库自增列
|
||||
/// </summary>
|
||||
public string? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 字典分类
|
||||
/// </summary>
|
||||
public string Category { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 字典名称
|
||||
/// </summary>
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 字典字典值
|
||||
/// </summary>
|
||||
public string Code { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 字典定义值 0 表示系统使用,1 表示用户自定义 默认为 1
|
||||
/// </summary>
|
||||
public int Define { get; set; } = 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<BootstrapBlazorRoot>
|
||||
<Router AppAssembly="@typeof(App).Assembly">
|
||||
<Found Context="routeData">
|
||||
<PageTitle>@Title</PageTitle>
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
</Found>
|
||||
<NotFound>
|
||||
<LayoutView Layout="@typeof(NotFoundLayout)" />
|
||||
</NotFound>
|
||||
</Router>
|
||||
</BootstrapBlazorRoot>
|
|
@ -0,0 +1,27 @@
|
|||
namespace Bootstrap.Admin.Blazor
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class App
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string? Title { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private BootstrapAppContext? AppContext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
//Title = DictHelper.RetrieveWebTitle(AppContext.AppId);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor" Version="6.1.1-beta01" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Bootstrap.Admin.Blazor.DataAccess\Bootstrap.Admin.Blazor.DataAccess.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Bootstrap.Admin.Blazor.Models" />
|
||||
<Using Include="Bootstrap.Admin.Blazor.Services" />
|
||||
<Using Include="BootstrapBlazor.Components" />
|
||||
<Using Include="Microsoft.AspNetCore.Components" />
|
||||
<Using Include="System.Diagnostics.CodeAnalysis" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,18 @@
|
|||
@typeparam TItem
|
||||
|
||||
<Table TItem="TItem" IsBordered="true" IsStriped="true" IsMultipleSelect="true"
|
||||
IsPagination="IsPagination" PageItemsSource="PageItemsSource"
|
||||
UseInjectDataService="true" DataService="DataService" OnQueryAsync="OnQueryAsync!"
|
||||
ShowToolbar="true" ShowExtendButtons="true" ShowSearch="true"
|
||||
ShowCardView="true" ShowColumnList="true"
|
||||
CustomerSearchModel="@TableSearchModel">
|
||||
<TableToolbarTemplate>
|
||||
@TableToolbarTemplate
|
||||
</TableToolbarTemplate>
|
||||
<TableColumns>
|
||||
@ColumnsTemplete(context)
|
||||
</TableColumns>
|
||||
<CustomerSearchTemplate>
|
||||
@CustomerSearchTemplate(context)
|
||||
</CustomerSearchTemplate>
|
||||
</Table>
|
|
@ -0,0 +1,60 @@
|
|||
namespace Bootstrap.Admin.Blazor.Components
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[CascadingTypeParameter(nameof(TItem))]
|
||||
public partial class BlazorTable<TItem> where TItem : class, new()
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public IEnumerable<int>? PageItemsSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
[Parameter]
|
||||
public RenderFragment<TItem>? ColumnsTemplete { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
[Parameter]
|
||||
public RenderFragment<ITableSearchModel>? CustomerSearchTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
[Parameter]
|
||||
public RenderFragment? TableToolbarTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool IsPagination { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public ITableSearchModel? TableSearchModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public IDataService<TItem>? DataService { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<QueryPageOptions, Task<QueryData<TItem>>>? OnQueryAsync { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<div class="row g-3">
|
||||
<div class="col-sm-6 col-md-6">
|
||||
<BootstrapInput @bind-Value="Value.Name" ShowLabel="true" DisplayText="字典名称" />
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-6">
|
||||
<BootstrapInput @bind-Value="Value.Category" ShowLabel="true" DisplayText="字典标签" />
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-6">
|
||||
<Select Items="@Items" @bind-Value="Value.Define" ShowLabel="true" DisplayText="字典类型"></Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private IEnumerable<SelectedItem>? Items { get; set; } = new List<SelectedItem>()
|
||||
{
|
||||
new SelectedItem("","全部"),
|
||||
new SelectedItem("0","系统使用"),
|
||||
new SelectedItem("1","自定义"),
|
||||
};
|
||||
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public DictsSearchModel? Value { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<DictsSearchModel> ValueChanged { get; set; }
|
||||
}
|
|
@ -0,0 +1,238 @@
|
|||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers
|
||||
{
|
||||
///// <summary>
|
||||
///// Account controller.
|
||||
///// </summary>
|
||||
//[AllowAnonymous]
|
||||
//[AutoValidateAntiforgeryToken]
|
||||
//public class AccountController : Controller
|
||||
//{
|
||||
//private const string MobileSchema = "Mobile";
|
||||
///// <summary>
|
||||
///// 系统锁屏界面
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//[HttpGet]
|
||||
//public async Task<ActionResult> Lock()
|
||||
//{
|
||||
// if (!User.Identity!.IsAuthenticated) return Login();
|
||||
|
||||
// var authenticationType = User.Identity.AuthenticationType;
|
||||
// await HttpContext.SignOutAsync();
|
||||
// var urlReferrer = Request.Headers["Referer"].FirstOrDefault();
|
||||
// if (urlReferrer?.Contains("/Pages", StringComparison.OrdinalIgnoreCase) ?? false) urlReferrer = "/Pages";
|
||||
// return View(new LockModel(User.Identity.Name)
|
||||
// {
|
||||
// AuthenticationType = authenticationType,
|
||||
// ReturnUrl = WebUtility.UrlEncode(string.IsNullOrEmpty(urlReferrer) ? CookieAuthenticationDefaults.LoginPath.Value : urlReferrer)
|
||||
// });
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 系统锁屏界面
|
||||
///// </summary>
|
||||
///// <param name="provider"></param>
|
||||
///// <param name="userName"></param>
|
||||
///// <param name="password"></param>
|
||||
///// <param name="authType"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpPost]
|
||||
//[IgnoreAntiforgeryToken]
|
||||
//public Task<IActionResult> Lock([FromServices] ISMSProvider provider, string userName, string password, string authType)
|
||||
//{
|
||||
// // 根据不同的登陆方式
|
||||
// Task<IActionResult> ret;
|
||||
// if (authType == MobileSchema) ret = Mobile(provider, userName, password);
|
||||
// else ret = Login(userName, password, string.Empty);
|
||||
// return ret;
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 系统登录方法
|
||||
///// </summary>
|
||||
///// <param name="appId"></param>
|
||||
///// <param name="view"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpGet]
|
||||
//public ActionResult Login([FromQuery] string? appId = null, [FromQuery] string view = "")
|
||||
//{
|
||||
// if (DictHelper.RetrieveSystemModel())
|
||||
// {
|
||||
// ViewBag.UserName = "Admin";
|
||||
// ViewBag.Password = "123789";
|
||||
// }
|
||||
// return User.Identity!.IsAuthenticated ? (ActionResult)Redirect("~/Home/Index") : LoginView(view, new LoginModel(appId));
|
||||
//}
|
||||
|
||||
//private ViewResult LoginView(string view, LoginModel model)
|
||||
//{
|
||||
// if (string.IsNullOrEmpty(view))
|
||||
// {
|
||||
// // retrieve login view from db
|
||||
// view = DictHelper.RetrieveLoginView();
|
||||
// }
|
||||
// return View(view, model);
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 短信验证登陆方法
|
||||
///// </summary>
|
||||
///// <param name="provider"></param>
|
||||
///// <param name="phone"></param>
|
||||
///// <param name="code"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpPost()]
|
||||
//public async Task<IActionResult> Mobile([FromServices] ISMSProvider provider, string phone, string code)
|
||||
//{
|
||||
// if (string.IsNullOrEmpty(phone) || string.IsNullOrEmpty(code)) return RedirectLogin();
|
||||
|
||||
// var auth = provider.Validate(phone, code);
|
||||
// await HttpContext.Log(phone, auth);
|
||||
// if (auth)
|
||||
// {
|
||||
// var user = UserHelper.Retrieves().FirstOrDefault(u => u.UserName == phone);
|
||||
// if (user == null)
|
||||
// {
|
||||
// user = new User()
|
||||
// {
|
||||
// ApprovedBy = "Mobile",
|
||||
// ApprovedTime = DateTime.Now,
|
||||
// DisplayName = "手机用户",
|
||||
// UserName = phone,
|
||||
// Password = code,
|
||||
// Icon = "default.jpg",
|
||||
// Description = "手机用户",
|
||||
// App = provider.Options.App
|
||||
// };
|
||||
// if (UserHelper.Save(user) && !string.IsNullOrEmpty(user.Id))
|
||||
// {
|
||||
// // 根据配置文件设置默认角色
|
||||
// var roles = RoleHelper.Retrieves().Where(r => provider.Options.Roles.Any(rl => rl.Equals(r.RoleName, StringComparison.OrdinalIgnoreCase))).Select(r => r.Id!);
|
||||
// RoleHelper.SaveByUserId(user.Id, roles);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return auth ? await SignInAsync(phone, true, MobileSchema) : RedirectLogin();
|
||||
//}
|
||||
|
||||
//private IActionResult RedirectLogin()
|
||||
//{
|
||||
// var query = Request.Query.Aggregate(new Dictionary<string, string?>(), (d, v) =>
|
||||
// {
|
||||
// d.Add(v.Key, v.Value.ToString());
|
||||
// return d;
|
||||
// });
|
||||
// return Redirect(QueryHelpers.AddQueryString(Request.PathBase + CookieAuthenticationDefaults.LoginPath, query));
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// Login the specified userName, password and remember.
|
||||
///// </summary>
|
||||
///// <returns>The login.</returns>
|
||||
///// <param name="userName">User name.</param>
|
||||
///// <param name="password">Password.</param>
|
||||
///// <param name="remember">Remember.</param>
|
||||
//[HttpPost]
|
||||
//public async Task<IActionResult> Login(string userName, string password, string remember)
|
||||
//{
|
||||
// if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password)) return RedirectLogin();
|
||||
|
||||
// var auth = UserHelper.Authenticate(userName, password);
|
||||
// await HttpContext.Log(userName, auth);
|
||||
// return auth ? await SignInAsync(userName, remember == "true") : LoginView("", new LoginModel() { AuthFailed = true });
|
||||
//}
|
||||
|
||||
//private async Task<IActionResult> SignInAsync(string userName, bool persistent, string authenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme)
|
||||
//{
|
||||
// var identity = new ClaimsIdentity(authenticationScheme);
|
||||
// identity.AddClaim(new Claim(ClaimTypes.Name, userName));
|
||||
// await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), new AuthenticationProperties { ExpiresUtc = DateTimeOffset.Now.AddDays(DictHelper.RetrieveCookieExpiresPeriod()), IsPersistent = persistent });
|
||||
|
||||
// // redirect origin url
|
||||
// var originUrl = Request.Query[CookieAuthenticationDefaults.ReturnUrlParameter].FirstOrDefault() ?? "~/Home/Index";
|
||||
// return Redirect(originUrl);
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// Logout this instance.
|
||||
///// </summary>
|
||||
///// <param name="appId"></param>
|
||||
///// <returns>The logout.</returns>
|
||||
//[HttpGet]
|
||||
//public async Task<IActionResult> Logout([FromQuery] string appId)
|
||||
//{
|
||||
// await HttpContext.SignOutAsync();
|
||||
// return Redirect(QueryHelpers.AddQueryString(Request.PathBase + CookieAuthenticationDefaults.LoginPath, "AppId", appId ?? BootstrapAppContext.AppId));
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// Accesses the denied.
|
||||
///// </summary>
|
||||
///// <returns>The denied.</returns>
|
||||
//[ResponseCache(Duration = 600)]
|
||||
//[HttpGet]
|
||||
//public ActionResult AccessDenied() => View("Error", ErrorModel.CreateById(403));
|
||||
|
||||
///// <summary>
|
||||
///// Gitee 认证
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//[HttpGet]
|
||||
//public IActionResult Gitee([FromServices] IConfiguration config)
|
||||
//{
|
||||
// var enabled = config.GetValue($"{nameof(GiteeOptions)}:Enabled", false);
|
||||
// return Challenge(enabled ? GiteeDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// GitHub 认证
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//[HttpGet]
|
||||
//public IActionResult GitHub([FromServices] IConfiguration config)
|
||||
//{
|
||||
// var enabled = config.GetValue($"{nameof(GitHubOptions)}:Enabled", false);
|
||||
// return Challenge(enabled ? GitHubDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// Tencent 认证
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//[HttpGet]
|
||||
//public IActionResult Tencent([FromServices] IConfiguration config)
|
||||
//{
|
||||
// var enabled = config.GetValue($"{nameof(TencentOptions)}:Enabled", false);
|
||||
// return Challenge(enabled ? TencentDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// Alipay 认证
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//[HttpGet]
|
||||
//public IActionResult Alipay([FromServices] IConfiguration config)
|
||||
//{
|
||||
// var enabled = config.GetValue($"{nameof(AlipayOptions)}:Enabled", false);
|
||||
// return Challenge(enabled ? AlipayDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// WeChat 认证
|
||||
///// </summary>
|
||||
///// <returns></returns>
|
||||
//[HttpGet]
|
||||
//public IActionResult WeChat([FromServices] IConfiguration config)
|
||||
//{
|
||||
// var enabled = config.GetValue($"{nameof(WeChatOptions)}:Enabled", false);
|
||||
// return Challenge(enabled ? WeChatDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
//}
|
||||
//}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
// Website: https://www.blazor.zone or https://argozhang.github.io/
|
||||
|
||||
using PetaPoco;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace BootstrapBlazor.DataAcces.PetaPoco
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class DatabaseExtensions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Task<List<TModel>> FetchAsync<TModel>(this IDatabase db, IEnumerable<IFilterAction> where, string? sortName = null, SortOrder sortOrder = SortOrder.Unset)
|
||||
{
|
||||
var exp = where.GetFilterLambda<TModel>();
|
||||
var sql = new Sql();
|
||||
AnalysisExpression(exp, db, sql);
|
||||
|
||||
if (!string.IsNullOrEmpty(sortName) && sortOrder != SortOrder.Unset)
|
||||
{
|
||||
sql.OrderBy(sortOrder == SortOrder.Asc ? sortName : $"{sortName} desc");
|
||||
}
|
||||
return db.FetchAsync<TModel>(sql);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Task<Page<TModel>> PageAsync<TModel>(this IDatabase db, long pageIndex, long pageItems, IEnumerable<IFilterAction> where, string? sortName = null, SortOrder sortOrder = SortOrder.Unset)
|
||||
{
|
||||
var exp = where.GetFilterLambda<TModel>();
|
||||
var sql = new Sql();
|
||||
AnalysisExpression(exp, db, sql);
|
||||
|
||||
if (!string.IsNullOrEmpty(sortName) && sortOrder != SortOrder.Unset)
|
||||
{
|
||||
sql.OrderBy(sortOrder == SortOrder.Asc ? sortName : $"{sortName} desc");
|
||||
}
|
||||
return db.PageAsync<TModel>(pageIndex, pageItems, sql);
|
||||
}
|
||||
|
||||
private static void AnalysisExpression(Expression expression, IDatabase db, Sql sql)
|
||||
{
|
||||
switch (expression.NodeType)
|
||||
{
|
||||
case ExpressionType.Lambda:
|
||||
if (expression is LambdaExpression exp)
|
||||
{
|
||||
AnalysisExpression(exp.Body, db, sql);
|
||||
}
|
||||
break;
|
||||
case ExpressionType.AndAlso:
|
||||
if (expression is BinaryExpression andExp)
|
||||
{
|
||||
AnalysisExpression(andExp.Left, db, sql);
|
||||
AnalysisExpression(andExp.Right, db, sql);
|
||||
}
|
||||
break;
|
||||
case ExpressionType.Call:
|
||||
if (expression is MethodCallExpression callExp)
|
||||
{
|
||||
if (callExp.Method.Name == "Contains")
|
||||
{
|
||||
if (callExp.Object is MemberExpression callLeft)
|
||||
{
|
||||
var callColName = GetColumnName(callLeft.Member) ?? callLeft.Member.Name;
|
||||
var p = (callExp.Arguments[0] as ConstantExpression)?.Value;
|
||||
if (p != null)
|
||||
{
|
||||
sql.Where($"{db.Provider.EscapeSqlIdentifier(callColName)} like @0", $"%{p}%");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ExpressionType.Equal:
|
||||
case ExpressionType.NotEqual:
|
||||
case ExpressionType.GreaterThan:
|
||||
case ExpressionType.GreaterThanOrEqual:
|
||||
case ExpressionType.LessThan:
|
||||
case ExpressionType.LessThanOrEqual:
|
||||
var binaryExp = (expression as BinaryExpression)!;
|
||||
var left = (binaryExp.Left as MemberExpression)!;
|
||||
|
||||
// 查找 PetaPoco.Column 标签
|
||||
var columnName = GetColumnName(left.Member) ?? left.Member.Name;
|
||||
|
||||
// 查找操作符右侧
|
||||
var right = (binaryExp.Right as ConstantExpression)!;
|
||||
var v = right.Value;
|
||||
|
||||
if (v != null)
|
||||
{
|
||||
var operatorExp = GetOperatorExpression(expression);
|
||||
sql.Where($"{db.Provider.EscapeSqlIdentifier(columnName)} {operatorExp} @0", v);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static string? GetColumnName(MemberInfo member) => member.CustomAttributes
|
||||
.FirstOrDefault(i => i.AttributeType == typeof(ColumnAttribute))?.NamedArguments
|
||||
.FirstOrDefault(i => i.MemberName == "Name").TypedValue.Value?.ToString();
|
||||
|
||||
private static string GetOperatorExpression(Expression expression) => expression.NodeType switch
|
||||
{
|
||||
ExpressionType.Equal => "=",
|
||||
ExpressionType.NotEqual => "!=",
|
||||
ExpressionType.GreaterThan => ">",
|
||||
ExpressionType.GreaterThanOrEqual => ">=",
|
||||
ExpressionType.LessThan => "<",
|
||||
ExpressionType.LessThanOrEqual => "<=",
|
||||
_ => ""
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
using BootstrapBlazor.DataAcces.PetaPoco;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class ServicesExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加示例后台任务
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
public static IServiceCollection AddBootstrapBlazorAdminServices(this IServiceCollection services)
|
||||
{
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
|
||||
// 增加后台任务服务
|
||||
//services.AddTaskServices();
|
||||
|
||||
//services.AddLogging(logging => logging.AddFileLogger().AddCloudLogger().AddDBLogger(ExceptionsHelper.Log));
|
||||
services.AddCors();
|
||||
services.AddResponseCompression();
|
||||
//services.AddCodePageProvider();
|
||||
|
||||
//services.AddCacheManager();
|
||||
//services.AddDbAdapter();
|
||||
//services.AddIPLocator(DictHelper.ConfigIPLocator);
|
||||
//services.AddOnlineUsers();
|
||||
//services.AddSignalR().AddJsonProtocol(op => op.PayloadSerializerOptions.AddDefaultConverters());
|
||||
//services.AddBootstrapAdminAuthentication(Configuration)
|
||||
// .AddGitee(OAuthHelper.Configure)
|
||||
// .AddGitHub(OAuthHelper.Configure)
|
||||
// .AddTencent(OAuthHelper.Configure)
|
||||
// .AddAlipay(OAuthHelper.Configure);
|
||||
//services.AddAuthorization(options => options.DefaultPolicy = new AuthorizationPolicyBuilder().RequireBootstrapAdminAuthorizate().Build());
|
||||
//services.AddButtonAuthorization(MenuHelper.AuthorizateButtons);
|
||||
//services.AddBootstrapAdminBackgroundTask();
|
||||
//services.AddHttpClient<GiteeHttpClient>();
|
||||
//services.AddAdminHealthChecks();
|
||||
//services.AddSMSProvider();
|
||||
|
||||
//services.AddSwagger();
|
||||
//services.AddApiVersioning(option =>
|
||||
//{
|
||||
// option.DefaultApiVersion = new ApiVersion(1, 0);
|
||||
// option.ReportApiVersions = true;
|
||||
// option.AssumeDefaultVersionWhenUnspecified = true;
|
||||
// option.ApiVersionReader = ApiVersionReader.Combine(new HeaderApiVersionReader("api-version"), new QueryStringApiVersionReader("api-version"));
|
||||
//});
|
||||
//services.AddExceptionless();
|
||||
//services.AddControllersWithViews(options =>
|
||||
//{
|
||||
// options.Filters.Add<BootstrapAdminAuthorizeFilter>();
|
||||
// options.Filters.Add<ExceptionFilter>();
|
||||
// options.Filters.Add<SignalRExceptionFilter<SignalRHub>>();
|
||||
//}).AddJsonOptions(op => op.JsonSerializerOptions.AddDefaultConverters());
|
||||
//services.AddControllersWithViews().AddJsonOptions(op => op.JsonSerializerOptions.AddDefaultConverters());
|
||||
|
||||
// 增加 BootstrapBlazor 组件
|
||||
services.AddBootstrapBlazor();
|
||||
|
||||
// 增加数据服务
|
||||
services.AddSingleton(typeof(IDataService<>), typeof(DefaultDataService<>));
|
||||
|
||||
// 增加 BootstrapApp 上下文服务
|
||||
services.AddSingleton<BootstrapAppContext>();
|
||||
|
||||
// 增加数据服务
|
||||
services.AddSingleton<IBootstrapMenuService, IBootstrapMenuService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
using Bootstrap.Admin.Blazor.DataAccess;
|
||||
|
||||
namespace Bootstrap.Admin.Blazor.Models
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class DictsSearchModel : ITableSearchModel
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string? Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int? Define { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<IFilterAction> GetSearchs()
|
||||
{
|
||||
var ret = new List<IFilterAction>();
|
||||
|
||||
if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
ret.Add(new SearchFilterAction(nameof(Dict.Name), Name));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Category))
|
||||
{
|
||||
ret.Add(new SearchFilterAction(nameof(Dict.Category), Category));
|
||||
}
|
||||
|
||||
if (Define.HasValue)
|
||||
{
|
||||
ret.Add(new SearchFilterAction(nameof(Dict.Define), Define, FilterAction.Equal));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public void Reset()
|
||||
{
|
||||
Category = null;
|
||||
Name = null;
|
||||
Define = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
namespace Bootstrap.Admin.Blazor.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 登陆页面 Model
|
||||
/// </summary>
|
||||
public class LoginModel
|
||||
{
|
||||
///// <summary>
|
||||
///// 默认构造函数
|
||||
///// </summary>
|
||||
///// <param name="appId"></param>
|
||||
//public LoginModel(string? appId = null)
|
||||
//{
|
||||
// //ImageLibUrl = DictHelper.RetrieveImagesLibUrl();
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 验证码图床地址
|
||||
/// </summary>
|
||||
public string? ImageLibUrl { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否登录认证失败 为真时客户端弹出滑块验证码
|
||||
/// </summary>
|
||||
public bool AuthFailed { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
@page "/admin/dicts"
|
||||
|
||||
<BlazorTable TItem="Dict" IsPagination="false" TableSearchModel="@DictsSearchModel">
|
||||
<ColumnsTemplete>
|
||||
<TableColumn @bind-Field="context.Category" Text="字典标签" Filterable="true" Searchable="true" Sortable="true"></TableColumn>
|
||||
<TableColumn @bind-Field="context.Name" Text="字典名称" Filterable="true" Searchable="true" Sortable="true"></TableColumn>
|
||||
<TableColumn @bind-Field="context.Code" Text="字典代码" Filterable="true" Searchable="true" Sortable="true"></TableColumn>
|
||||
<TableColumn @bind-Field="context.Define" Text="字典类型" Filterable="true" Searchable="true" Sortable="true" Lookup="@LookUp">
|
||||
<EditTemplate Context="v">
|
||||
<div class="col-sm-6 col-md-6">
|
||||
<Select Items="@EditDefines" @bind-Value="v!.Define" DisplayText="字典类型"></Select>
|
||||
</div>
|
||||
</EditTemplate>
|
||||
</TableColumn>
|
||||
</ColumnsTemplete>
|
||||
<CustomerSearchTemplate>
|
||||
@if (context is DictsSearchModel searchModel)
|
||||
{
|
||||
<DictSearch @bind-Value="@searchModel"></DictSearch>
|
||||
}
|
||||
</CustomerSearchTemplate>
|
||||
</BlazorTable>
|
|
@ -0,0 +1,30 @@
|
|||
namespace Bootstrap.Admin.Blazor.Pages.Admin
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class Dicts
|
||||
{
|
||||
private IEnumerable<SelectedItem>? EditDefines { get; set; }
|
||||
|
||||
private IEnumerable<SelectedItem>? LookUp { get; set; }
|
||||
|
||||
private ITableSearchModel? DictsSearchModel { get; set; } = new DictsSearchModel();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
EditDefines = new List<SelectedItem>()
|
||||
{
|
||||
new SelectedItem("0","系统使用"),
|
||||
new SelectedItem("1","自定义"),
|
||||
};
|
||||
|
||||
LookUp = EditDefines;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
@page "/"
|
||||
@page "/admin"
|
||||
@page "/admin/index"
|
||||
@attribute [TabItemOption(Text = "后台管理")]
|
||||
|
||||
<h4>欢迎使用后台管理</h4>
|
|
@ -0,0 +1,17 @@
|
|||
@page "/admin/users"
|
||||
|
||||
@*<BlazorTable TItem="User">
|
||||
<TableToolbarTemplate>
|
||||
<TableToolbarButton TItem="User" Color="Color.Info" Icon="fa fa-bank" Text="分配部门" OnClickCallback="OnAssignmentDept" />
|
||||
<TableToolbarButton TItem="User" Color="Color.Warning" Icon="fa fa-sitemap" Text="分配角色" OnClickCallback="OnAssignmentRoles" />
|
||||
</TableToolbarTemplate>
|
||||
<ColumnsTemplete>
|
||||
<TableColumn @bind-Field="@context.UserName" Text="登录名称" Sortable="true" Filterable="true" Searchable="true"></TableColumn>
|
||||
<TableColumn @bind-Field="@context.DisplayName" Text="显示名称" Sortable="true" Filterable="true" Searchable="true"></TableColumn>
|
||||
<TableColumn @bind-Field="@context.RegisterTime" Text="注册时间" Sortable="true" Filterable="true"></TableColumn>
|
||||
<TableColumn @bind-Field="@context.ApprovedTime" Text="授权时间" Sortable="true" Filterable="true"></TableColumn>
|
||||
<TableColumn @bind-Field="@context.ApprovedBy" Text="授权人" Sortable="true" Filterable="true"></TableColumn>
|
||||
<TableColumn @bind-Field="@context.Description" Text="说明" Sortable="true" Filterable="true"></TableColumn>
|
||||
</ColumnsTemplete>
|
||||
</BlazorTable>
|
||||
*@
|
|
@ -0,0 +1,60 @@
|
|||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
namespace Bootstrap.Admin.Blazor.Pages.Admin
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class Users
|
||||
{
|
||||
//[Inject]
|
||||
//[NotNull]
|
||||
//private DialogService? DialogService { get; set; }
|
||||
|
||||
//[Inject]
|
||||
//[NotNull]
|
||||
//private ToastService? ToastService { get; set; }
|
||||
|
||||
//private async Task OnAssignmentDept(IEnumerable<User> users)
|
||||
//{
|
||||
// if (users.Count() == 1)
|
||||
// {
|
||||
// var option = new DialogOption()
|
||||
// {
|
||||
// Title = "部门授权",
|
||||
// BodyTemplate = BootstrapDynamicComponent.CreateComponent<CheckboxList<string>>(new Dictionary<string, object>
|
||||
// {
|
||||
// [nameof(CheckboxList<string>.Items)] = GroupHelper.Retrieves().Select(s => new SelectedItem(s.GroupCode, s.GroupName))
|
||||
// }).Render()
|
||||
// };
|
||||
|
||||
// await DialogService.Show(option);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// await ToastService.Warning("部门授权", "请选择一个用户");
|
||||
// }
|
||||
//}
|
||||
|
||||
//private async Task OnAssignmentRoles(IEnumerable<User> users)
|
||||
//{
|
||||
// if (users.Count() != 0)
|
||||
// {
|
||||
// var option = new DialogOption()
|
||||
// {
|
||||
// Title = "分配角色",
|
||||
// BodyTemplate = BootstrapDynamicComponent.CreateComponent<CheckboxList<string>>(new Dictionary<string, object>
|
||||
// {
|
||||
// [nameof(CheckboxList<string>.Items)] = RoleHelper.Retrieves().Select(s => new SelectedItem(s.Id!, s.RoleName) { Active = s.Checked == "" ? false : true })
|
||||
// }).Render()
|
||||
// };
|
||||
|
||||
// await DialogService.Show(option);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// await ToastService.Warning("分配角色", "请选择一个用户");
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
@attribute [Authorize]
|
|
@ -0,0 +1,3 @@
|
|||
@page "/home"
|
||||
@page "/home/index"
|
||||
@attribute [TabItemOption(Text = "首页")]
|
|
@ -0,0 +1,8 @@
|
|||
@page "/"
|
||||
@namespace Bootstrap.Admin.Blazor.Pages
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
||||
|
||||
<component type="typeof(App)" render-mode="ServerPrerendered" />
|
|
@ -0,0 +1,42 @@
|
|||
@using Microsoft.AspNetCore.Components.Web
|
||||
@namespace Bootstrap.Admin.Blazor.Pages
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" href="~/favicon.ico" type="image/x-icon" />
|
||||
<link rel="shortcut icon" href="~/favicon.ico" type="image/x-icon" />
|
||||
<link rel="apple-touch-icon" href="~/favicon.png" />
|
||||
<base href="~/" />
|
||||
<link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
|
||||
<link href="_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css" rel="stylesheet">
|
||||
<link href="_content/BootstrapBlazor/css/motronic.min.css" rel="stylesheet">
|
||||
<link href="css/site.css" rel="stylesheet" />
|
||||
<link href="css/motronic.css" rel="stylesheet" />
|
||||
<link href="Bootstrap.Admin.Blazor.styles.css" rel="stylesheet" />
|
||||
|
||||
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
|
||||
</head>
|
||||
<body>
|
||||
@RenderBody()
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
<environment include="Staging,Production">
|
||||
An error has occurred. This application may no longer respond until reloaded.
|
||||
</environment>
|
||||
<environment include="Development">
|
||||
An unhandled exception has occurred. See browser dev tools for details.
|
||||
</environment>
|
||||
<a href="" class="reload">Reload</a>
|
||||
<a class="dismiss">🗙</a>
|
||||
</div>
|
||||
|
||||
<script src="_framework/blazor.server.js"></script>
|
||||
<script src="_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,30 @@
|
|||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.AddServerSideBlazor();
|
||||
|
||||
// 注入项目服务
|
||||
builder.Services.AddBootstrapBlazorAdminServices();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseExceptionHandler("/Error");
|
||||
}
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
// 开启缓存中间件
|
||||
//app.UseCacheManager();
|
||||
|
||||
// 开启 webapi
|
||||
app.MapDefaultControllerRoute();
|
||||
app.MapBlazorHub();
|
||||
app.MapFallbackToPage("/_Host");
|
||||
|
||||
app.Run();
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:24748",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"Bootstrap.Admin.Blazor": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "http://localhost:5110",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
namespace Bootstrap.Admin.Blazor.Services
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BootstrapAppContext
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string AppId { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="configuration"></param>
|
||||
public BootstrapAppContext(IConfiguration configuration)
|
||||
{
|
||||
AppId = configuration.GetValue("AppId", "demo");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace Bootstrap.Admin.Blazor.Services
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BootstrapMenuService : IBootstrapMenuService
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
// Website: https://www.blazor.zone or https://argozhang.github.io/
|
||||
|
||||
using PetaPoco;
|
||||
using PetaPoco.Extensions;
|
||||
using PetaPoco.Providers;
|
||||
|
||||
namespace BootstrapBlazor.DataAcces.PetaPoco
|
||||
{
|
||||
/// <summary>
|
||||
/// PetaPoco ORM 的 IDataService 接口实现
|
||||
/// </summary>
|
||||
internal class DefaultDataService<TModel> : DataServiceBase<TModel> where TModel : class, new()
|
||||
{
|
||||
private readonly IDatabase _db;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public DefaultDataService(IConfiguration configuration)
|
||||
{
|
||||
//TODO: 后期改造成自定适配
|
||||
var connString = configuration.GetConnectionString("bb");
|
||||
_db = new Database<SQLiteDatabaseProvider>(connString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除方法
|
||||
/// </summary>
|
||||
/// <param name="models"></param>
|
||||
/// <returns></returns>
|
||||
public override Task<bool> DeleteAsync(IEnumerable<TModel> models)
|
||||
{
|
||||
// 通过模型获取主键列数据
|
||||
// 支持批量删除
|
||||
_db.DeleteBatch(models);
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存方法
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <param name="changedType"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<bool> SaveAsync(TModel model, ItemChangedType changedType)
|
||||
{
|
||||
if (changedType == ItemChangedType.Add)
|
||||
{
|
||||
await _db.InsertAsync(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _db.UpdateAsync(model);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询方法
|
||||
/// </summary>
|
||||
/// <param name="option"></param>
|
||||
/// <returns></returns>
|
||||
public override async Task<QueryData<TModel>> QueryAsync(QueryPageOptions option)
|
||||
{
|
||||
var ret = new QueryData<TModel>()
|
||||
{
|
||||
IsSorted = true,
|
||||
IsFiltered = true,
|
||||
IsSearch = true
|
||||
};
|
||||
|
||||
var filters = option.Filters.Concat(option.Searchs).Concat(option.CustomerSearchs);
|
||||
if (option.IsPage)
|
||||
{
|
||||
var items = await _db.PageAsync<TModel>(option.PageIndex, option.PageItems, filters, option.SortName, option.SortOrder);
|
||||
|
||||
ret.TotalCount = Convert.ToInt32(items.TotalItems);
|
||||
ret.Items = items.Items;
|
||||
}
|
||||
else
|
||||
{
|
||||
var items = await _db.FetchAsync<TModel>(filters, option.SortName, option.SortOrder);
|
||||
ret.TotalCount = items.Count;
|
||||
ret.Items = items;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace Bootstrap.Admin.Blazor.Services
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IBootstrapMenuService
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
@inherits LayoutComponentBase
|
||||
|
||||
<Layout SideWidth="0" IsPage="true" IsFullSide="true" IsFixedHeader="true" IsFixedFooter="false"
|
||||
ShowFooter="true" ShowGotoTop="true" ShowCollapseBar="true" Menus="@MenuItems"
|
||||
UseTabSet="true" TabDefaultUrl="/admin/index">
|
||||
<Header>
|
||||
<span class="ms-3 flex-fill">Bootstrap of Blazor</span>
|
||||
<img src="/images/Argo.png" class="layout-avatar-right" />
|
||||
<span class="mx-3 d-none d-sm-block">超级管理员</span>
|
||||
<div class="layout-drawer"><i class="fa fa-gears"></i></div>
|
||||
</Header>
|
||||
<Side>
|
||||
<div class="layout-banner">
|
||||
<img class="layout-logo" src="/images/brand.png" />
|
||||
<div class="layout-title">
|
||||
<span>后台管理</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layout-user">
|
||||
<img class="layout-avatar" src="/images/Argo-C.png">
|
||||
<div class="layout-title">
|
||||
<span>管理员</span>
|
||||
</div>
|
||||
<div class="layout-user-state"></div>
|
||||
</div>
|
||||
</Side>
|
||||
<Main>
|
||||
@Body
|
||||
</Main>
|
||||
<Footer>
|
||||
<div class="flex-fill text-center text-dark">Bootstrap Admin Blazor 版 ©</div>
|
||||
</Footer>
|
||||
</Layout>
|
|
@ -0,0 +1,32 @@
|
|||
namespace Bootstrap.Admin.Blazor.Shared
|
||||
{
|
||||
/// <summary>
|
||||
/// MainLayout 布局类
|
||||
/// </summary>
|
||||
public partial class MainLayout
|
||||
{
|
||||
private IEnumerable<MenuItem>? MenuItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
|
||||
// TODO: 暂时写死 Admin 账号
|
||||
//MenuItems = DataAccess.MenuHelper.RetrieveSystemMenus("Admin").Select(s => new MenuItem()
|
||||
//{
|
||||
// Url = s.Url.Replace("~", ""),
|
||||
// Text = s.Name,
|
||||
// Icon = s.Icon,
|
||||
// Items = s.Menus.Select(x => new MenuItem
|
||||
// {
|
||||
// Url = x.Url.Replace("~", ""),
|
||||
// Text = x.Name,
|
||||
// Icon = x.Icon
|
||||
// })
|
||||
//});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
@inherits LayoutComponentBase
|
||||
|
||||
<div class="error">
|
||||
<div class="bg">
|
||||
<img alt="404" src="@Image" />
|
||||
</div>
|
||||
<h3>请求资源未找到</h3>
|
||||
<p>资源不存在或者没有访问权限,点击这里 <a href="/">返回首页</a> <span>或者</span> <a href="/healths-ui">系统自检</a></p>
|
||||
</div>
|
|
@ -0,0 +1,12 @@
|
|||
namespace Bootstrap.Admin.Blazor.Shared
|
||||
{
|
||||
/// <summary>
|
||||
/// NotFoundLayout 模板类
|
||||
/// </summary>
|
||||
public partial class NotFoundLayout
|
||||
{
|
||||
private string Image { get; set; } = "images/404.png";
|
||||
|
||||
private bool IsNotAuthorizated { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
.error {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.28rem;
|
||||
font-weight: bold;
|
||||
margin: 1.125rem 0;
|
||||
}
|
||||
|
||||
.bg {
|
||||
background-image: url('../images/bg404.png');
|
||||
width: 458px;
|
||||
height: 215px;
|
||||
text-align: center;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
@using System.Net.Http
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.JSInterop
|
||||
|
||||
@using BootstrapBlazor.Components
|
||||
|
||||
@using Bootstrap.Admin.Blazor
|
||||
@using Bootstrap.Admin.Blazor.Components
|
||||
@using Bootstrap.Admin.Blazor.Models
|
||||
@using Bootstrap.Admin.Blazor.Shared
|
||||
|
||||
@using Bootstrap.Admin.Blazor.DataAccess
|
|
@ -0,0 +1,331 @@
|
|||
{
|
||||
"DetailedErrors": true,
|
||||
"AutoGenerateDatabase": true,
|
||||
"DB": [
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "SqlServer",
|
||||
"SqlFolder": "..\\..\\..\\db\\SqlServer",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"ProviderName": "Sqlite",
|
||||
"SqlFolder": "..\\..\\..\\db\\SQLite",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=BootstrapAdmin.db;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "MySql",
|
||||
"SqlFolder": "..\\..\\..\\db\\MySQL",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Server=localhost;Database=BA;Uid=argozhang;Pwd=argo@163.com;SslMode=none;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "Oracle",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=XXXXXX)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL)));User Id=XX;Password=XX"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "Npgsql",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Server=localhost;Database=BootstrapAdmin;User ID=argozhang;Password=argo@163.com;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"Widget": "Bootstrap.DataAccess.MongoDB",
|
||||
"ProviderName": "MongoDB",
|
||||
"SqlFolder": "..\\..\\..\\db\\MongoDB",
|
||||
"ConnectionStrings": {
|
||||
"ba": "mongodb://localhost:27017/BootstrapAdmin"
|
||||
}
|
||||
}
|
||||
],
|
||||
"SwaggerPathBase": "",
|
||||
"GiteeHealthChecks": "true",
|
||||
"AllowOrigins": "http://localhost:49185",
|
||||
"HealthsCloudUrl": "https://client.blazor.zone/api/Interface/Healths",
|
||||
"FileStorageOptions": {
|
||||
"Enabled": true,
|
||||
"Folder": "TaskStorage",
|
||||
"Secure": false
|
||||
},
|
||||
"GiteeOptions": {
|
||||
"Enabled": true,
|
||||
"ClientId": "9bfe9b95d813ca7d613b110a54eda28bf227154b314c95f0c69e7680d64525e1",
|
||||
"ClientSecret": "3427f2d901ba9afc76c1842a7303b2d67f8e098e71acc15051f89fe6f3d265db",
|
||||
"CallbackPath": "/signin-gitee",
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"Scope": [ "user_info", "projects" ],
|
||||
"Roles": [ "Administrators" ],
|
||||
"App": "Demo",
|
||||
"StarredUrl": "https://gitee.com/api/v5/user/starred/LongbowEnterprise/BootstrapAdmin"
|
||||
},
|
||||
"GitHubOptions": {
|
||||
"Enabled": true,
|
||||
"ClientId": "ec53ecfe238558a0423b",
|
||||
"ClientSecret": "ffa759ca599df941b869efecb5e750bc1b27334e",
|
||||
"CallbackPath": "/signin-github",
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"Scope": [ "user_info", "repo" ],
|
||||
"Roles": [ "Administrators" ],
|
||||
"App": "Demo",
|
||||
"StarredUrl": "https://api.github.com/user/starred/ArgoZhang/BootstrapAdmin"
|
||||
},
|
||||
"WeChatOptions": {
|
||||
"Enabled": true,
|
||||
"ClientId": "<ClientId>",
|
||||
"ClientSecret": "<secret>",
|
||||
"CallbackPath": "/signin-weixin",
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"Scope": [ "snsapi_login" ],
|
||||
"Roles": [ "Administrators" ],
|
||||
"App": "Demo"
|
||||
},
|
||||
"TencentOptions": {
|
||||
"Enabled": true,
|
||||
"ClientId": "<ClientId>",
|
||||
"ClientSecret": "<ClientSecret>",
|
||||
"CallbackPath": "/signin-tencent",
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"Scope": [ "get_user_info" ],
|
||||
"Roles": [ "Administrators" ],
|
||||
"App": "Demo"
|
||||
},
|
||||
"SMSOptions": {
|
||||
"CompanyCode": "<CompanyCode>",
|
||||
"MD5Key": "MD5Key",
|
||||
"Roles": [ "Administrators" ],
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"App": "Demo"
|
||||
},
|
||||
"AlipayOptions": {
|
||||
"Enabled": true,
|
||||
"ClientId": "<ClientId>",
|
||||
"ClientSecret": "<ClientSecret>",
|
||||
"CallbackPath": "/signin-alipay",
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"SignKey": "",
|
||||
"Scope": [ "auth_user" ],
|
||||
"Roles": [ "Administrators" ],
|
||||
"App": "Demo"
|
||||
},
|
||||
"TencentSMSOptions": {
|
||||
"AppId": "<TencentAppId>",
|
||||
"AppKey": "<TencentAppKey>",
|
||||
"TplId": 0,
|
||||
"Sign": "<TencentSign>",
|
||||
"Roles": [ "Default" ],
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"App": "Demo",
|
||||
"Debug": true
|
||||
},
|
||||
"AppMenus": [
|
||||
"首页",
|
||||
"测试页面",
|
||||
"关于",
|
||||
"返回码云",
|
||||
"多级菜单",
|
||||
"第二层",
|
||||
"第三层",
|
||||
"第四层"
|
||||
],
|
||||
"LongbowCache": {
|
||||
"Enabled": true,
|
||||
"CorsItems": [
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "ba",
|
||||
"Url": "CacheList.axd",
|
||||
"Desc": "后台管理数据缓存接口",
|
||||
"Self": true
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "App",
|
||||
"Url": "http://localhost:49185/CacheList.axd",
|
||||
"Desc": "测试系统",
|
||||
"Self": false
|
||||
}
|
||||
],
|
||||
"CacheItems": [
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByUserName",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "指定用户角色数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByUrl",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过菜单获得角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "AppHelper-RetrieveAppsByUserName",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "指定用户授权应用数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "BootstrapUser-RetrieveUsersByName",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "登录用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "BootstrapDict-RetrieveDicts",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有字典数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "BootstrapMenu-RetrieveMenus",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "用户所有菜单数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "GroupHelper-RetrieveGroupsByUserName",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "指定用户组数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "UserHelper-RetrieveUsers",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "UserHelper-RetrieveUsersByRoleId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过角色ID获得所有用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "UserHelper-RetrieveUsersByGroupId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过部门ID获得所有用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "UserHelper-RetrieveNewUsers",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "新用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "MenuHelper-RetrieveMenusByRoleId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过角色ID获得所有菜单数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRoles",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByUserId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过用户ID获得所有角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByMenuId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过菜单ID获得所有角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByGroupId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过部门ID获得所有角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "GroupHelper-RetrieveGroups",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有部门数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "GroupHelper-RetrieveGroupsByUserId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过用户ID获得所有部门数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "GroupHelper-RetrieveGroupsByRoleId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过角色ID获得所有部门数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "AppHelper-RetrieveAppsByRoleId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过角色ID获得所有应用程序数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "DictHelper-RetrieveDictsCategory",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "字典分类数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "ExceptionHelper-RetrieveExceptions",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "程序异常数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "MessageHelper-RetrieveMessages",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "站内消息数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "TaskHelper-RetrieveTasks",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有任务数据"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,350 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
},
|
||||
"LgbFile": {
|
||||
"IncludeScopes": true,
|
||||
"LogLevel": {
|
||||
"Default": "Error"
|
||||
},
|
||||
"FileName": "Error\\Log.log"
|
||||
},
|
||||
"Cloud": {
|
||||
"LogLevel": {
|
||||
"Default": "Error"
|
||||
},
|
||||
"Url": "https://client.blazor.zone/api/Interface/Log"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa",
|
||||
"bb": "Data Source=BootstrapAdmin.db;"
|
||||
},
|
||||
"AutoGenerateDatabase": false,
|
||||
"DB": [
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "SqlServer",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"ProviderName": "Sqlite",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Data Source=BootstrapAdmin.db;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "MySql",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Server=localhost;Database=BA;Uid=argozhang;Pwd=argo@163.com;SslMode=none;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"ProviderName": "Npgsql",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Server=localhost;Database=BootstrapAdmin;User ID=argozhang;Password=argo@163.com;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"Widget": "Bootstrap.DataAccess.MongoDB",
|
||||
"ProviderName": "MongoDB",
|
||||
"ConnectionStrings": {
|
||||
"ba": "mongodb://localhost:27017/BootstrapAdmin"
|
||||
}
|
||||
}
|
||||
],
|
||||
"AppId": "BA",
|
||||
"UseHttps": true,
|
||||
"SwaggerPathBase": "",
|
||||
"AllowOrigins": "http://localhost,http://admin.blazor.zone",
|
||||
"HealthsCloudUrl": "https://client.blazor.zone/api/Interface/Healths",
|
||||
"GiteeHealthChecks": false,
|
||||
"Sentry": {
|
||||
"Dsn": "https://70bdfff562e84fa7b9a43d65924ab9ad@sentry.io/1469396"
|
||||
},
|
||||
"BootstrapBlazorOptions": {
|
||||
"DefaultCultureInfo": "zh-CN"
|
||||
},
|
||||
"Exceptionless": {
|
||||
"ApiKey": "AgQlY1MRWpX5qOF2edpK2IZYBhgPYImhr4UnZdAT"
|
||||
},
|
||||
"TokenValidateOption": {
|
||||
"Issuer": "BA",
|
||||
"Audience": "api",
|
||||
"Expires": 5,
|
||||
"SecurityKey": "BootstrapAdmin-V1.1"
|
||||
},
|
||||
"TaskServicesOptions": {
|
||||
"ShutdownTimeout": "00:00:05"
|
||||
},
|
||||
"FileStorageOptions": {
|
||||
"Enabled": true,
|
||||
"Folder": "TaskStorage",
|
||||
"Secure": true
|
||||
},
|
||||
"GiteeOptions": {
|
||||
"Enabled": true,
|
||||
"ClientId": "<ClientId>",
|
||||
"ClientSecret": "<ClientSecret>",
|
||||
"CallbackPath": "/signin-gitee",
|
||||
"HomePath": "/Home/Index",
|
||||
"Scope": [ "user_info", "projects" ],
|
||||
"Roles": [ "Default" ],
|
||||
"App": "Demo"
|
||||
},
|
||||
"GitHubOptions": {
|
||||
"Enabled": true,
|
||||
"ClientId": "<ClientId>",
|
||||
"ClientSecret": "<ClientSecret>",
|
||||
"CallbackPath": "/signin-github",
|
||||
"HomePath": "/Home/Index",
|
||||
"Scope": [ "user_info", "repo" ],
|
||||
"Roles": [ "Default" ],
|
||||
"App": "Demo"
|
||||
},
|
||||
"WeChatOptions": {
|
||||
"Enabled": true,
|
||||
"ClientId": "<ClientId>",
|
||||
"ClientSecret": "<secret>",
|
||||
"CallbackPath": "/signin-weixin",
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"Scope": [ "snsapi_login" ],
|
||||
"Roles": [ "Default" ],
|
||||
"App": "Demo"
|
||||
},
|
||||
"TencentOptions": {
|
||||
"Enabled": true,
|
||||
"ClientId": "<ClientId>",
|
||||
"ClientSecret": "<ClientSecret>",
|
||||
"CallbackPath": "/signin-tencent",
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"Scope": [ "get_user_info" ],
|
||||
"Roles": [ "Administrators" ],
|
||||
"App": "Demo"
|
||||
},
|
||||
"AlipayOptions": {
|
||||
"Enabled": true,
|
||||
"ClientId": "<ClientId>",
|
||||
"ClientSecret": "<ClientSecret>",
|
||||
"CallbackPath": "/signin-alipay",
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"SignKey": "",
|
||||
"Scope": [ "auth_user" ],
|
||||
"Roles": [ "Administrators" ],
|
||||
"App": "Demo"
|
||||
},
|
||||
"SMSOptions": {
|
||||
"CompanyCode": "<CompanyCode>",
|
||||
"MD5Key": "MD5Key",
|
||||
"Roles": [ "Default" ],
|
||||
"HomePath": "/Home/Index",
|
||||
"App": "Demo"
|
||||
},
|
||||
"TencentSMSOptions": {
|
||||
"AppId": "<TencentAppId>",
|
||||
"AppKey": "<TencentAppKey>",
|
||||
"TplId": 0,
|
||||
"Sign": "<TencentSign>",
|
||||
"Roles": [ "Default" ],
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"App": "Demo"
|
||||
},
|
||||
"LongbowCache": {
|
||||
"Enabled": true,
|
||||
"CorsItems": [
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "ba",
|
||||
"Url": "CacheList.axd",
|
||||
"Desc": "后台管理数据缓存接口",
|
||||
"Self": true
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "App",
|
||||
"Url": "../Client/CacheList.axd",
|
||||
"Desc": "测试系统",
|
||||
"Self": false
|
||||
}
|
||||
],
|
||||
"CacheItems": [
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByUserName",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "指定用户角色数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByUrl",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过菜单获得角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "AppHelper-RetrieveAppsByUserName",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "指定用户授权应用数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "BootstrapUser-RetrieveUsersByName",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "登录用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "BootstrapDict-RetrieveDicts",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有字典数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "BootstrapMenu-RetrieveMenus",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "用户所有菜单数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "GroupHelper-RetrieveGroupsByUserName",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "指定用户组数据缓存"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "UserHelper-RetrieveUsers",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "UserHelper-RetrieveUsersByRoleId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过角色ID获得所有用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "UserHelper-RetrieveUsersByGroupId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过部门ID获得所有用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "UserHelper-RetrieveNewUsers",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "新用户数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "MenuHelper-RetrieveMenusByRoleId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过角色ID获得所有菜单数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRoles",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByUserId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过用户ID获得所有角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByMenuId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过菜单ID获得所有角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "RoleHelper-RetrieveRolesByGroupId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过部门ID获得所有角色数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "GroupHelper-RetrieveGroups",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有部门数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "GroupHelper-RetrieveGroupsByUserId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过用户ID获得所有部门数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "GroupHelper-RetrieveGroupsByRoleId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过角色ID获得所有部门数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "AppHelper-RetrieveAppsByRoleId",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "通过角色ID获得所有应用程序数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "DictHelper-RetrieveDictsCategory",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "字典分类数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "ExceptionHelper-RetrieveExceptions",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "程序异常数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "MessageHelper-RetrieveMessages",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "站内消息数据"
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Key": "TaskHelper-RetrieveTasks",
|
||||
"Interval": 600000,
|
||||
"SlidingExpiration": true,
|
||||
"Desc": "所有任务数据"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
.layout.is-page .layout-side {
|
||||
color: #3f4254;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 28px 0 rgb(82 63 105 / 5%);
|
||||
}
|
||||
|
||||
.layout.is-page .layout-user .layout-title {
|
||||
color: #3f4254;
|
||||
}
|
||||
|
||||
.layout.is-page .layout-footer {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.layout-gotop {
|
||||
background: #e9ecef;
|
||||
color: #3f4254;
|
||||
}
|
||||
|
||||
.layout-gotop:hover {
|
||||
background-color: #dee2e6;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.sidebar {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
html, body {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
#blazor-error-ui {
|
||||
background: lightyellow;
|
||||
bottom: 0;
|
||||
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
|
||||
display: none;
|
||||
left: 0;
|
||||
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#blazor-error-ui .dismiss {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 0.75rem;
|
||||
top: 0.5rem;
|
||||
}
|
||||
|
||||
.blazor-error-boundary {
|
||||
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
|
||||
padding: 1rem 1rem 1rem 3.7rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.blazor-error-boundary::after {
|
||||
content: "An error has occurred."
|
||||
}
|
||||
|
||||
.tabs-border-card {
|
||||
box-shadow: none;
|
||||
}
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 112 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 523 KiB After Width: | Height: | Size: 523 KiB |
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 217 KiB After Width: | Height: | Size: 217 KiB |
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 152 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 385 KiB After Width: | Height: | Size: 385 KiB |
After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 124 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 937 B After Width: | Height: | Size: 937 B |
Before Width: | Height: | Size: 314 KiB After Width: | Height: | Size: 314 KiB |
Before Width: | Height: | Size: 288 B After Width: | Height: | Size: 288 B |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 973 B After Width: | Height: | Size: 973 B |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 193 KiB After Width: | Height: | Size: 193 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 203 KiB After Width: | Height: | Size: 203 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 973 B After Width: | Height: | Size: 973 B |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 288 B After Width: | Height: | Size: 288 B |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |