Compare commits
1 Commits
master
...
dev-Locali
Author | SHA1 | Date |
---|---|---|
|
02363c764c |
|
@ -6,22 +6,17 @@ root=true
|
|||
# All files
|
||||
[*]
|
||||
indent_style = space
|
||||
# shell files
|
||||
[*.{cmd,sh,bat}]
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
# Code files
|
||||
[*.{cs,csx,vb,vbx}]
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
charset = utf-8-bom
|
||||
[*.{json,yml,xml,csproj,props}]
|
||||
indent_size = 2
|
||||
###############################
|
||||
# .NET Coding Conventions #
|
||||
###############################
|
||||
[*.{cs,vb}]
|
||||
# Unix-style newlines with a newline ending every file
|
||||
end_of_line = lf
|
||||
# Organize usings
|
||||
dotnet_sort_system_directives_first = false
|
||||
# this. preferences
|
||||
|
@ -123,13 +118,9 @@ csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
|||
# Wrapping preferences
|
||||
csharp_preserve_single_line_statements = true
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_style_namespace_declarations=file_scoped:silent
|
||||
###############################
|
||||
# VB Coding Conventions #
|
||||
###############################
|
||||
[*.vb]
|
||||
# Modifier preferences
|
||||
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
|
||||
[*.cs]
|
||||
# Add file header
|
||||
file_header_template = Copyright (c) Argo Zhang (argo@163.com). All rights reserved.\nLicensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.\nWebsite: https://admin.blazor.zone
|
|
@ -11,6 +11,7 @@
|
|||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
*.sln text eof=crlf
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
name: Auto Build CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.103
|
||||
- name: Build with dotnet
|
||||
run: dotnet build src/admin/Bootstrap.Admin/ --configuration Release
|
|
@ -1,15 +0,0 @@
|
|||
name: Docker Image CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Build the Docker image
|
||||
run: docker build . --file src/admin/Bootstrap.Admin/Dockerfile --tag ba:$(date +%s)
|
|
@ -85,6 +85,7 @@ StyleCopReport.xml
|
|||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
|
@ -346,11 +347,11 @@ ASALocalRun/
|
|||
**/[tT]humbs.db
|
||||
|
||||
# Net Core Keys
|
||||
**/[Kk]eys/*.xml
|
||||
Bootstrap*.xml
|
||||
[Kk]eys/
|
||||
Bootstrap.Admin.xml
|
||||
|
||||
###### -- Custom Ignore Section, Make sure all files you add to the git repo are below this line -- ######
|
||||
|
||||
# Coverage
|
||||
coverage*.xml
|
||||
tools/
|
||||
tools/
|
|
@ -3,7 +3,7 @@
|
|||
# (note that '\' need to be escaped).
|
||||
|
||||
[issuetracker "Gitee-Issue"]
|
||||
regex = "#((?!.*Issue|issue|Comme|comme)[A-Za-z0-9]+)"
|
||||
regex = "#((?!.*Issue|issue|Comme|comme).{5})"
|
||||
url = "https://gitee.com/LongbowEnterprise/BootstrapAdmin/issues/$1?from=project-issue"
|
||||
|
||||
[issuetracker "Gitee-Url"]
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>..\Keys\Longbow.Utility.snk</AssemblyOriginatorKeyFile>
|
||||
<MvcRazorCompileOnPublish>true</MvcRazorCompileOnPublish>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<DocumentationFile>..\Bootstrap.Admin\Bootstrap.Admin.xml</DocumentationFile>
|
||||
<DockerDefaultTargetOS>Windows</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.7.9" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" PrivateAssets="All" />
|
||||
<PackageReference Include="Sentry.AspNetCore" Version="1.2.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\Keys\Longbow.Utility.snk" Link="Longbow.Utility.snk" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Bootstrap.DataAccess\Bootstrap.DataAccess.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
Binary file not shown.
|
@ -0,0 +1,97 @@
|
|||
using Bootstrap.Admin.Models;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Account controller.
|
||||
/// </summary>
|
||||
[AllowAnonymous]
|
||||
[AutoValidateAntiforgeryToken]
|
||||
public class AccountController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public ActionResult Login()
|
||||
{
|
||||
if (DictHelper.RetrieveSystemModel())
|
||||
{
|
||||
ViewBag.UserName = "Admin";
|
||||
ViewBag.Password = "123789";
|
||||
}
|
||||
return User.Identity.IsAuthenticated ? (ActionResult)Redirect("~/Home/Index") : View("Login", new LoginModel());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Login the specified userName, password and remember.
|
||||
/// </summary>
|
||||
/// <returns>The login.</returns>
|
||||
/// <param name="onlineUserSvr"></param>
|
||||
/// <param name="ipLocator"></param>
|
||||
/// <param name="userName">User name.</param>
|
||||
/// <param name="password">Password.</param>
|
||||
/// <param name="remember">Remember.</param>
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Login([FromServices]IOnlineUsers onlineUserSvr, [FromServices]IIPLocatorProvider ipLocator, string userName, string password, string remember)
|
||||
{
|
||||
if (UserHelper.Authenticate(userName, password, loginUser => CreateLoginUser(onlineUserSvr, ipLocator, HttpContext, loginUser)))
|
||||
{
|
||||
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.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 = remember == "true" });
|
||||
// redirect origin url
|
||||
var originUrl = Request.Query[CookieAuthenticationDefaults.ReturnUrlParameter].FirstOrDefault() ?? "~/Home/Index";
|
||||
return Redirect(originUrl);
|
||||
}
|
||||
return View("Login", new LoginModel() { AuthFailed = true });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="onlineUserSvr"></param>
|
||||
/// <param name="ipLocator"></param>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="loginUser"></param>
|
||||
internal static void CreateLoginUser(IOnlineUsers onlineUserSvr, IIPLocatorProvider ipLocator, HttpContext context, LoginUser loginUser)
|
||||
{
|
||||
loginUser.UserAgent = context.Request.Headers["User-Agent"];
|
||||
var agent = new UserAgent(loginUser.UserAgent);
|
||||
loginUser.Ip = (context.Connection.RemoteIpAddress ?? IPAddress.IPv6Loopback).ToString();
|
||||
loginUser.City = ipLocator.Locate(loginUser.Ip);
|
||||
loginUser.Browser = $"{agent.Browser?.Name} {agent.Browser?.Version}";
|
||||
loginUser.OS = $"{agent.OS?.Name} {agent.OS?.Version}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logout this instance.
|
||||
/// </summary>
|
||||
/// <returns>The logout.</returns>
|
||||
public async Task<IActionResult> Logout()
|
||||
{
|
||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
return Redirect("~" + CookieAuthenticationDefaults.LoginPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accesses the denied.
|
||||
/// </summary>
|
||||
/// <returns>The denied.</returns>
|
||||
[ResponseCache(Duration = 600)]
|
||||
public ActionResult AccessDenied() => View("Error", ErrorModel.CreateById(403));
|
||||
}
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.Admin.Models;
|
||||
using Bootstrap.Admin.Models;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
@ -11,85 +7,72 @@ using System;
|
|||
namespace Bootstrap.Admin.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// 后台管理控制器
|
||||
///
|
||||
/// </summary>
|
||||
[Authorize]
|
||||
public class AdminController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 后台管理首页
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Index() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 用户维护
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Users() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 部门维护
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Groups() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 字典表维护
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Dicts() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 角色维护
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Roles() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 菜单维护
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Menus() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 操作日志
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Logs() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 脚本日志
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult SQL() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 访问日志
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Traces() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 登录日志
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Logins() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// FA 图标页面
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult FAIcon() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 健康检查
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Healths() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 图标视图
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
|
@ -97,51 +80,44 @@ namespace Bootstrap.Admin.Controllers
|
|||
public PartialViewResult IconView() => PartialView("IconView");
|
||||
|
||||
/// <summary>
|
||||
/// 侧边栏局部视图
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remark>菜单维护页面增删菜单时局部刷新时调用</remark>
|
||||
public PartialViewResult Sidebar() => PartialView("Sidebar", new NavigatorBarModel(this));
|
||||
public ActionResult Settings() => View(new ThemeModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 网站设置
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Settings() => View(new SettingsModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 通知管理
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Notifications() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 个人中心
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="host"></param>
|
||||
/// <returns></returns>
|
||||
public ActionResult Profiles([FromServices]IWebHostEnvironment host) => View(new ProfilesModel(this, host));
|
||||
public ActionResult Profiles([FromServices]IHostingEnvironment host) => View(new ProfilesModel(this, host));
|
||||
|
||||
/// <summary>
|
||||
/// 程序异常
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Exceptions() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 消息通知
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Messages() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 任务管理
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Tasks() => View(new TaskModel(this));
|
||||
public ActionResult Tasks() => View(new NavigatorBarModel(this));
|
||||
|
||||
/// <summary>
|
||||
/// 客户端测试页面
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ActionResult Mobile() => View(new NavigatorBarModel(this));
|
|
@ -1,9 +1,4 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -12,19 +7,18 @@ using System.Linq;
|
|||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// 网站分析控制器
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class AnalyseController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 通过 logType 查询分析数据接口
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet()]
|
||||
public ActionResult<AnalyseData> Get([FromQuery]string logType)
|
||||
public ActionResult<AnalyseData> Get([FromQuery]string logType = "")
|
||||
{
|
||||
var ret = new AnalyseData();
|
||||
if (logType.Equals("LoginUsers", StringComparison.OrdinalIgnoreCase))
|
||||
|
@ -64,19 +58,19 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分析数据实体类
|
||||
///
|
||||
/// </summary>
|
||||
public class AnalyseData
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 折线数据集合
|
||||
///
|
||||
/// </summary>
|
||||
public IEnumerable<string> Polylines { get; set; } = new string[0];
|
||||
public IEnumerable<string> Polylines { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得 数据集合
|
||||
///
|
||||
/// </summary>
|
||||
public List<KeyValuePair<string, string>> Datas { get; } = new List<KeyValuePair<string, string>>();
|
||||
public List<KeyValuePair<string, string>> Datas { get; set; } = new List<KeyValuePair<string, string>>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class AppsController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{id}")]
|
||||
public IEnumerable<App> Get(string id) => AppHelper.RetrievesByRoleId(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据字典分类
|
||||
/// </summary>
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class CategoryController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取字典表中所有Category数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[AllowAnonymous]
|
||||
public IEnumerable<string> RetrieveDictCategorys()
|
||||
{
|
||||
return DictHelper.RetrieveCategories();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public IEnumerable<string> RetrieveMenus()
|
||||
{
|
||||
return MenuHelper.RetrieveAllMenus(User.Identity.Name).OrderBy(m => m.Name).Select(m => m.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public IEnumerable<string> RetrieveParentMenus()
|
||||
{
|
||||
return MenuHelper.RetrieveMenus(User.Identity.Name).Where(m => m.Menus.Count() > 0).OrderBy(m => m.Name).Select(m => m.Name);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,28 +1,22 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.Admin.Query;
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.Security;
|
||||
using Longbow.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// 字典表维护控制器
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class DictsController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取所有字典表数据方法
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
|
@ -32,7 +26,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
return value.RetrieveData();
|
||||
}
|
||||
/// <summary>
|
||||
/// 保存字典方法
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
[HttpPost]
|
||||
|
@ -42,7 +36,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
return DictHelper.Save(value);
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除字典项方法
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
[HttpDelete]
|
||||
|
@ -53,4 +47,4 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
return DictHelper.Delete(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
using Bootstrap.Admin.Query;
|
||||
using Longbow.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class ExceptionsController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 显示所有异常
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public QueryData<object> Get([FromQuery]QueryExceptionOption value)
|
||||
{
|
||||
return value.Retrieves();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异常程序页面点击服务器日志按钮获取所有物理日志文件列表方法
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ButtonAuthorize(Url = "~/Admin/Exceptions", Auth = "log")]
|
||||
public IEnumerable<string> Post()
|
||||
{
|
||||
var filePath = Path.Combine(AppContext.BaseDirectory, "Error");
|
||||
return Directory.Exists(filePath)
|
||||
? Directory.GetFiles(filePath)
|
||||
.Where(f => Path.GetExtension(f).Equals(".log", StringComparison.OrdinalIgnoreCase))
|
||||
.Select(f => Path.GetFileNameWithoutExtension(f)).OrderByDescending(s => s)
|
||||
: Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中指定文件查看其内容方法
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPut]
|
||||
[ButtonAuthorize(Url = "~/Admin/Exceptions", Auth = "log")]
|
||||
public JsonResult Put([FromBody]ExceptionFileQuery exceptionFile)
|
||||
{
|
||||
var filePath = Path.Combine(AppContext.BaseDirectory, "Error");
|
||||
var logName = $"{Path.Combine(filePath, exceptionFile.FileName)}.log";
|
||||
if (!System.IO.File.Exists(logName)) return new JsonResult("无此日志文件");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
using (StreamReader reader = new StreamReader(logName))
|
||||
{
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
var line = reader.ReadLine().Replace("<", "<").Replace(">", ">");
|
||||
if (line == "General Information ") sb.AppendFormat("<h4><b>{0}</b></h4>", line);
|
||||
else if (line.StartsWith("TimeStamp:")) sb.AppendFormat("<div class='logTs'>{0}</div>", line);
|
||||
else if (line.EndsWith("Exception Information")) sb.AppendFormat("<div class='logExcep'>{0}</div>", line);
|
||||
else if (line.StartsWith("Message:")) sb.AppendFormat("<div class='logMsg'>{0}</div>", line);
|
||||
else if (line.StartsWith("ErrorSql:")) sb.AppendFormat("<div class='logSql'>{0}</div>", line);
|
||||
else if (line.StartsWith("Exception Type: Longbow.Data.DBAccessException")) sb.AppendFormat("<div class='logDbExcep'>{0}</div>", line);
|
||||
else if (line.StartsWith("StackTrace Information")) sb.AppendFormat("<b>{0}</b><br>", line);
|
||||
else sb.AppendFormat("{0}<br>", line);
|
||||
}
|
||||
}
|
||||
return new JsonResult(sb.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ExceptionFileQuery
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string FileName { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]/[action]")]
|
||||
[ApiController]
|
||||
[AllowAnonymous]
|
||||
public class GiteeController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="httpClientFactory"></param>
|
||||
/// <param name="userName"></param>
|
||||
/// <param name="repoName"></param>
|
||||
/// <param name="label"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> Issues([FromServices]IHttpClientFactory httpClientFactory, [FromQuery]string userName = "LongbowEnterprise", [FromQuery]string repoName = "BootstrapAdmin", [FromQuery]string label = "custom badge", [FromQuery]string color = "orange")
|
||||
{
|
||||
var client = httpClientFactory.CreateClient();
|
||||
var content = await GetJsonAsync(() => client.GetStringAsync($"https://gitee.com/{userName}/{repoName}/issues"));
|
||||
var regex = Regex.Matches(content, "<div class='ui mini circular label'>([\\d]+)</div>", RegexOptions.IgnoreCase);
|
||||
var labels = new string[] { "open", "closed", "rejected" };
|
||||
var result = string.IsNullOrEmpty(content) ? new string[] { "unknown" } : regex.Select((m, i) => $"{labels[i]} {m.Groups[1].Value}");
|
||||
return new JsonResult(new { schemaVersion = 1, label, message = string.Join(" ", result), color });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="httpClientFactory"></param>
|
||||
/// <param name="userName"></param>
|
||||
/// <param name="repoName"></param>
|
||||
/// <param name="label"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> Pulls([FromServices]IHttpClientFactory httpClientFactory, [FromQuery]string userName = "LongbowEnterprise", [FromQuery]string repoName = "BootstrapAdmin", [FromQuery]string label = "custom badge", [FromQuery]string color = "orange")
|
||||
{
|
||||
var client = httpClientFactory.CreateClient();
|
||||
var content = await GetJsonAsync(() => client.GetStringAsync($"https://gitee.com/{userName}/{repoName}/pulls"));
|
||||
var regex = Regex.Matches(content, "<div class='ui mini circular label'>([\\d]+)</div>", RegexOptions.IgnoreCase);
|
||||
var labels = new string[] { "open", "merged", "closed" };
|
||||
var result = string.IsNullOrEmpty(content) ? new string[] { "unknown" } : regex.Select((m, i) => $"{labels[i]} {m.Groups[1].Value}");
|
||||
return new JsonResult(new { schemaVersion = 1, label, message = string.Join(" ", result), color });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="httpClientFactory"></param>
|
||||
/// <param name="userName"></param>
|
||||
/// <param name="repoName"></param>
|
||||
/// <param name="label"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> Releases([FromServices]IHttpClientFactory httpClientFactory, [FromQuery]string userName = "LongbowEnterprise", [FromQuery]string repoName = "BootstrapAdmin", [FromQuery]string label = "custom badge", [FromQuery]string color = "orange")
|
||||
{
|
||||
var client = httpClientFactory.CreateClient();
|
||||
var content = await GetJsonAsync(() => client.GetStringAsync($"https://gitee.com/{userName}/{repoName}/releases"));
|
||||
var regex = Regex.Match(content, $"<a href=\"/{userName}/{repoName}/releases/([^\\s]+)\" target=\"_blank\">", RegexOptions.IgnoreCase);
|
||||
var result = string.IsNullOrEmpty(content) ? "unknown" : regex.Groups[1].Value;
|
||||
return new JsonResult(new { schemaVersion = 1, label, message = result, color });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="httpClientFactory"></param>
|
||||
/// <param name="userName"></param>
|
||||
/// <param name="projName"></param>
|
||||
/// <param name="branchName"></param>
|
||||
/// <param name="label"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> Builds([FromServices]IHttpClientFactory httpClientFactory, [FromQuery]string userName = "ArgoZhang", [FromQuery]string projName = "bootstrapadmin", [FromQuery]string branchName = "master", [FromQuery]string label = "custom badge", [FromQuery]string color = "orange")
|
||||
{
|
||||
var client = httpClientFactory.CreateClient();
|
||||
var content = await GetJsonAsync(() => client.GetAsJsonAsync<AppveyorBuildResult>($"https://ci.appveyor.com/api/projects/{userName}/{projName}/branch/{branchName}"));
|
||||
return new JsonResult(new { schemaVersion = 1, label, message = content == null ? "unknown" : content.Build.Version, color });
|
||||
}
|
||||
|
||||
private async static Task<T> GetJsonAsync<T>(Func<Task<T>> callback)
|
||||
{
|
||||
var ret = default(T);
|
||||
try
|
||||
{
|
||||
ret = await callback();
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Log();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private class AppveyorBuildResult
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Build Build { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private class Build
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Version { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +1,21 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.Admin.Query;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// 部门维护控制器
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class GroupsController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 部门数据查询方法
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
|
@ -32,7 +26,18 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存部门方法
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{id}")]
|
||||
public Group Get(string id)
|
||||
{
|
||||
return GroupHelper.Retrieves().FirstOrDefault(t => t.Id == id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
[HttpPost]
|
||||
|
@ -43,7 +48,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除部门方法
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
[HttpDelete]
|
||||
|
@ -56,7 +61,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
/// <summary>
|
||||
/// 获取部门授权
|
||||
/// </summary>
|
||||
/// <param name="id">用户ID或者角色ID</param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{id}")]
|
|
@ -1,10 +1,5 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.Security;
|
||||
using Bootstrap.Security.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
|
@ -12,7 +7,7 @@ using System.Collections.Generic;
|
|||
namespace Bootstrap.Admin.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// 接口控制器
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]/[action]")]
|
||||
[AllowAnonymous]
|
||||
|
@ -20,7 +15,7 @@ namespace Bootstrap.Admin.Controllers
|
|||
public class InterfaceController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取所有字典表数据
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
|
@ -28,43 +23,41 @@ namespace Bootstrap.Admin.Controllers
|
|||
{
|
||||
return DictHelper.RetrieveDicts();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过请求地址获取相对应角色集合
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public IEnumerable<string> RetrieveRolesByUrl([FromBody]string url)
|
||||
{
|
||||
return RoleHelper.RetrievesByUrl(url, BootstrapAppContext.AppId);
|
||||
return RoleHelper.RetrieveRolesByUrl(url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过用户名获得分配所有角色
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public IEnumerable<string> RetrieveRolesByUserName([FromBody]string userName)
|
||||
{
|
||||
return RoleHelper.RetrievesByUserName(userName);
|
||||
return RoleHelper.RetrieveRolesByUserName(userName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过用户名获得 User 实例
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public BootstrapUser? RetrieveUserByUserName([FromBody]string userName)
|
||||
public BootstrapUser RetrieveUserByUserName([FromBody]string userName)
|
||||
{
|
||||
return UserHelper.RetrieveUserByUserName(userName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过指定条件获得应用程序菜单
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public IEnumerable<BootstrapMenu> RetrieveAppMenus([FromBody]AppMenuOption args) => MenuHelper.RetrieveAppMenus(args.AppId, args.UserName, args.Url);
|
||||
public IEnumerable<BootstrapMenu> RetrieveAppMenus([FromBody]AppMenuOption args)
|
||||
{
|
||||
return MenuHelper.RetrieveAppMenus(args.AppId, args.UserName, args.Url);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
using Bootstrap.Admin.Query;
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.Security;
|
||||
using Longbow.Web;
|
||||
using Longbow.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class LoginController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得登录历史记录
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public QueryData<LoginUser> Get([FromQuery]QueryLoginOption value) => value.RetrieveData();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="onlineUserSvr"></param>
|
||||
/// <param name="ipLocator"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpPost]
|
||||
public string Post([FromServices]IOnlineUsers onlineUserSvr, [FromServices]IIPLocatorProvider ipLocator, [FromBody]JObject value)
|
||||
{
|
||||
string token = null;
|
||||
dynamic user = value;
|
||||
string userName = user.userName;
|
||||
string password = user.password;
|
||||
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password) && UserHelper.Authenticate(userName, password, loginUser => AccountController.CreateLoginUser(onlineUserSvr, ipLocator, HttpContext, loginUser)))
|
||||
{
|
||||
token = BootstrapAdminJwtTokenHandler.CreateToken(userName);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpOptions]
|
||||
public string Options()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,54 +1,48 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.Admin.Query;
|
||||
using Bootstrap.Admin.Query;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web;
|
||||
using Longbow.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// 操作日志控制器
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class LogsController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 前台获取操作日志数据调用
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public QueryData<Log> Get([FromQuery] QueryLogOption value)
|
||||
public QueryData<Log> Get([FromQuery]QueryLogOption value)
|
||||
{
|
||||
return value.RetrieveData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 操作日志记录方法
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="onlineUserSvr"></param>
|
||||
/// <param name="ipLocator"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<bool> Post([FromServices] IIPLocatorProvider ipLocator, [FromBody] Log value)
|
||||
public bool Post([FromServices]IOnlineUsers onlineUserSvr, [FromServices]IIPLocatorProvider ipLocator, [FromBody]Log value)
|
||||
{
|
||||
value.UserAgent = Request.Headers["User-Agent"];
|
||||
var agent = new UserAgent(value.UserAgent);
|
||||
value.Ip = HttpContext.Connection.RemoteIpAddress?.ToIPv4String() ?? "";
|
||||
value.Ip = (HttpContext.Connection.RemoteIpAddress ?? IPAddress.IPv6Loopback).ToString();
|
||||
value.Browser = $"{agent.Browser?.Name} {agent.Browser?.Version}";
|
||||
value.OS = $"{agent.OS?.Name} {agent.OS?.Version}";
|
||||
value.City = await ipLocator.Locate(value.Ip);
|
||||
value.UserName = User.Identity?.Name ?? string.Empty;
|
||||
value.City = ipLocator.Locate(value.Ip);
|
||||
value.UserName = User.Identity.Name;
|
||||
return LogHelper.Save(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,8 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.Admin.Query;
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.Security;
|
||||
using Longbow.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
|
@ -17,7 +11,6 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class MenusController : ControllerBase
|
||||
{
|
||||
|
@ -29,7 +22,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
[HttpGet]
|
||||
public QueryData<object> Get([FromQuery]QueryMenuOption value)
|
||||
{
|
||||
return value.RetrieveData(User.Identity!.Name);
|
||||
return value.RetrieveData(User.Identity.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -70,7 +63,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
ret = MenuHelper.RetrieveMenusByRoleId(id);
|
||||
break;
|
||||
case "user":
|
||||
ret = MenuHelper.RetrieveMenus(User.Identity!.Name);
|
||||
ret = MenuHelper.RetrieveMenus(User.Identity.Name);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
|
@ -89,4 +82,4 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
return RoleHelper.SavaByMenuId(id, roleIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,5 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.Admin.Models;
|
||||
using Bootstrap.Admin.Models;
|
||||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -16,7 +11,6 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class MessagesController : ControllerBase
|
||||
{
|
||||
|
@ -32,16 +26,16 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
switch (id)
|
||||
{
|
||||
case "inbox":
|
||||
ret = MessageHelper.Inbox(User.Identity!.Name).ToList();
|
||||
ret = MessageHelper.Inbox(User.Identity.Name).ToList();
|
||||
break;
|
||||
case "sendmail":
|
||||
ret = MessageHelper.SendMail(User.Identity!.Name).ToList();
|
||||
ret = MessageHelper.SendMail(User.Identity.Name).ToList();
|
||||
break;
|
||||
case "mark":
|
||||
ret = MessageHelper.Mark(User.Identity!.Name).ToList();
|
||||
ret = MessageHelper.Mark(User.Identity.Name).ToList();
|
||||
break;
|
||||
case "trash":
|
||||
ret = MessageHelper.Trash(User.Identity!.Name).ToList();
|
||||
ret = MessageHelper.Trash(User.Identity.Name).ToList();
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
|
@ -56,12 +50,12 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
{
|
||||
var mcm = new MessageCountModel
|
||||
{
|
||||
InboxCount = MessageHelper.Inbox(User.Identity!.Name).Count(),
|
||||
SendmailCount = MessageHelper.SendMail(User.Identity!.Name).Count(),
|
||||
MarkCount = MessageHelper.Mark(User.Identity!.Name).Count(),
|
||||
TrashCount = MessageHelper.Trash(User.Identity!.Name).Count()
|
||||
InboxCount = MessageHelper.Inbox(User.Identity.Name).Count(),
|
||||
SendmailCount = MessageHelper.SendMail(User.Identity.Name).Count(),
|
||||
MarkCount = MessageHelper.Mark(User.Identity.Name).Count(),
|
||||
TrashCount = MessageHelper.Trash(User.Identity.Name).Count()
|
||||
};
|
||||
return mcm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,4 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -11,10 +6,9 @@ using System.Linq;
|
|||
namespace Bootstrap.Admin.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// 新用户注册控制器
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class NewController : ControllerBase
|
||||
{
|
||||
|
@ -42,19 +36,15 @@ namespace Bootstrap.Admin.Controllers
|
|||
public bool Put([FromBody]User value)
|
||||
{
|
||||
var ret = false;
|
||||
var userName = User.Identity!.Name;
|
||||
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(value.Id))
|
||||
if (value.UserStatus == UserStates.ApproveUser)
|
||||
{
|
||||
if (value.UserStatus == UserStates.ApproveUser)
|
||||
{
|
||||
ret = UserHelper.Approve(value.Id, userName);
|
||||
}
|
||||
else if (value.UserStatus == UserStates.RejectUser)
|
||||
{
|
||||
ret = UserHelper.Reject(value.Id, userName);
|
||||
}
|
||||
ret = UserHelper.Approve(value.Id, User.Identity.Name);
|
||||
}
|
||||
else if (value.UserStatus == UserStates.RejectUser)
|
||||
{
|
||||
ret = UserHelper.Reject(value.Id, User.Identity.Name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,26 +1,19 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Longbow.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统通知控制器
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class NotificationsController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 后台 Header 状态条调用
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
|
@ -43,15 +36,15 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
});
|
||||
|
||||
// Tasks
|
||||
var task = TaskServicesManager.ToList().Where(s => s.NextRuntime != null).Select(s => new { s.Name, s.LastRuntime, s.LastRunResult });
|
||||
var task = TaskHelper.Retrieves();
|
||||
var tasksCount = task.Count();
|
||||
|
||||
//Message
|
||||
var message = MessageHelper.Retrieves(User.Identity!.Name);
|
||||
var message = MessageHelper.Retrieves(User.Identity.Name);
|
||||
var messagesCount = message.Count();
|
||||
|
||||
message = message.Take(6);
|
||||
message.AsParallel().ForAll(m => m.FromIcon = Url.Content(m.FromIcon) ?? string.Empty);
|
||||
message.AsParallel().ForAll(m => m.FromIcon = Url.Content(m.FromIcon));
|
||||
|
||||
//Apps
|
||||
var apps = ExceptionsHelper.Retrieves().Where(n => n.Category != "DB");
|
||||
|
@ -60,7 +53,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
apps = apps.Take(6);
|
||||
apps.AsParallel().ForAll(n =>
|
||||
{
|
||||
n.ExceptionType = n.ExceptionType?.Split('.').Last();
|
||||
n.ExceptionType = n.ExceptionType.Split('.').Last();
|
||||
var ts = DateTime.Now - n.LogTime;
|
||||
if (ts.TotalMinutes < 5) n.Period = "刚刚";
|
||||
else if (ts.Days > 0) n.Period = string.Format("{0}天", ts.Days);
|
||||
|
@ -97,4 +90,4 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Longbow.Web;
|
||||
using Longbow.Web;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
|
@ -18,7 +14,6 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
/// 在线用户接口
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class OnlineUsersController : ControllerBase
|
||||
{
|
||||
|
@ -27,7 +22,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet()]
|
||||
public IEnumerable<OnlineUser> Get([FromServices] IOnlineUsers onlineUSers)
|
||||
public IEnumerable<OnlineUser> Get([FromServices]IOnlineUsers onlineUSers)
|
||||
{
|
||||
return onlineUSers.OnlineUsers.OrderByDescending(u => u.LastAccessTime);
|
||||
}
|
||||
|
@ -39,7 +34,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
/// <param name="onlineUSers"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{id}")]
|
||||
public IEnumerable<KeyValuePair<DateTime, string>> Get(string id, [FromServices] IOnlineUsers onlineUSers)
|
||||
public IEnumerable<KeyValuePair<DateTime, string>> Get(string id, [FromServices]IOnlineUsers onlineUSers)
|
||||
{
|
||||
var user = onlineUSers.OnlineUsers.FirstOrDefault(u => u.ConnectionId == id);
|
||||
return user?.RequestUrls ?? new KeyValuePair<DateTime, string>[0];
|
||||
|
@ -53,7 +48,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
[AllowAnonymous]
|
||||
public bool Put()
|
||||
{
|
||||
var ip = Request.HttpContext.Connection.RemoteIpAddress?.ToIPv4String() ?? "";
|
||||
var ip = (Request.HttpContext.Connection.RemoteIpAddress ?? IPAddress.IPv6Loopback).ToString();
|
||||
if (_loginUsers.TryGetValue(ip, out var user))
|
||||
{
|
||||
user.Reset();
|
||||
|
@ -76,7 +71,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string? Ip { get; set; }
|
||||
public string Ip { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -112,7 +107,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
dispatcher.Change(TimeSpan.FromSeconds(30), Timeout.InfiniteTimeSpan);
|
||||
if (dispatcher != null) dispatcher.Change(TimeSpan.FromSeconds(30), Timeout.InfiniteTimeSpan);
|
||||
}
|
||||
|
||||
#region Impletement IDispose
|
||||
|
@ -127,6 +122,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
if (dispatcher != null)
|
||||
{
|
||||
dispatcher.Dispose();
|
||||
dispatcher = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,7 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -15,10 +9,9 @@ using System.Threading.Tasks;
|
|||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// 个人中心控制器
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class ProfilesController : ControllerBase
|
||||
{
|
||||
|
@ -31,10 +24,13 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
/// <returns></returns>
|
||||
[HttpPost("{id}")]
|
||||
[ButtonAuthorize(Url = "~/Admin/Profiles", Auth = "saveIcon")]
|
||||
public JsonResult Post(string id, [FromServices] IWebHostEnvironment env, [FromForm] DeleteFileCollection files)
|
||||
public JsonResult Post(string id, [FromServices]IHostingEnvironment env, [FromForm]DeleteFileCollection files)
|
||||
{
|
||||
if (!id.Equals("Delete", StringComparison.OrdinalIgnoreCase)) return new JsonResult(new object());
|
||||
var userName = User.Identity!.Name;
|
||||
|
||||
var previewUrl = string.Empty;
|
||||
long fileSize = 0;
|
||||
var userName = User.Identity.Name;
|
||||
var fileName = files.Key;
|
||||
|
||||
fileName = Path.Combine(env.WebRootPath, $"images{Path.DirectorySeparatorChar}uploader{Path.DirectorySeparatorChar}{fileName}");
|
||||
|
@ -42,10 +38,10 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
fileName = "default.jpg";
|
||||
var webSiteUrl = DictHelper.RetrieveIconFolderPath();
|
||||
var filePath = Path.Combine(env.WebRootPath, webSiteUrl.Replace("~", string.Empty).Replace('/', Path.DirectorySeparatorChar).TrimStart(Path.DirectorySeparatorChar) + fileName);
|
||||
var fileSize = new FileInfo(filePath).Length;
|
||||
fileSize = new FileInfo(filePath).Length;
|
||||
var iconName = $"{fileName}?v={DateTime.Now.Ticks}";
|
||||
var previewUrl = Url.Content($"{webSiteUrl}{iconName}") ?? string.Empty;
|
||||
if (!string.IsNullOrEmpty(userName)) UserHelper.SaveUserIconByName(userName, iconName);
|
||||
previewUrl = Url.Content($"{webSiteUrl}{iconName}");
|
||||
UserHelper.SaveUserIconByName(userName, iconName);
|
||||
|
||||
return new JsonResult(new
|
||||
{
|
||||
|
@ -58,14 +54,14 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 待删除文件集合类
|
||||
///
|
||||
/// </summary>
|
||||
public class DeleteFileCollection
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 文件名称
|
||||
///
|
||||
/// </summary>
|
||||
public string Key { get; set; } = "";
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -76,11 +72,11 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ButtonAuthorize(Url = "~/Admin/Profiles", Auth = "saveIcon")]
|
||||
public async Task<JsonResult> Post([FromServices] IWebHostEnvironment env, IFormCollection files)
|
||||
public async Task<JsonResult> Post([FromServices]IHostingEnvironment env, IFormCollection files)
|
||||
{
|
||||
string? previewUrl = null;
|
||||
var previewUrl = string.Empty;
|
||||
long fileSize = 0;
|
||||
var userName = User.Identity!.Name;
|
||||
var userName = User.Identity.Name;
|
||||
var fileName = string.Empty;
|
||||
if (files.Files.Count > 0)
|
||||
{
|
||||
|
@ -88,18 +84,20 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
var webSiteUrl = DictHelper.RetrieveIconFolderPath();
|
||||
fileName = $"{userName}{Path.GetExtension(uploadFile.FileName)}";
|
||||
var filePath = Path.Combine(env.WebRootPath, webSiteUrl.Replace("~", string.Empty).Replace('/', Path.DirectorySeparatorChar).TrimStart(Path.DirectorySeparatorChar) + fileName);
|
||||
var fileFolder = Path.GetDirectoryName(filePath);
|
||||
fileSize = uploadFile.Length;
|
||||
if (!Directory.Exists(fileFolder)) Directory.CreateDirectory(fileFolder);
|
||||
using (var fs = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
await uploadFile.CopyToAsync(fs);
|
||||
}
|
||||
var iconName = $"{fileName}?v={DateTime.Now.Ticks}";
|
||||
previewUrl = Url.Content($"{webSiteUrl}{iconName}");
|
||||
if (!string.IsNullOrEmpty(userName)) UserHelper.SaveUserIconByName(userName, iconName);
|
||||
UserHelper.SaveUserIconByName(userName, iconName);
|
||||
}
|
||||
return new JsonResult(new
|
||||
{
|
||||
initialPreview = new string[] { previewUrl ?? string.Empty },
|
||||
initialPreview = new string[] { previewUrl },
|
||||
initialPreviewConfig = new object[] {
|
||||
new { caption = "新头像", size = fileSize, showZoom = true, key = fileName }
|
||||
},
|
||||
|
@ -108,26 +106,26 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 个人中心操作方法 更改样式 更改显示名称 更改默认应用
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPut]
|
||||
[ButtonAuthorize(Url = "~/Admin/Profiles", Auth = "saveDisplayName,savePassword,saveApp,saveTheme")]
|
||||
public bool Put([FromBody] User value)
|
||||
public bool Put([FromBody]User value)
|
||||
{
|
||||
var ret = false;
|
||||
if (value.UserName.Equals(User.Identity!.Name, StringComparison.OrdinalIgnoreCase))
|
||||
if (value.UserName.Equals(User.Identity.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
ret = value.UserStatus switch
|
||||
{
|
||||
UserStates.ChangeTheme => UserHelper.SaveUserCssByName(value.UserName, value.Css),
|
||||
UserStates.ChangeDisplayName => UserHelper.SaveDisplayName(value.UserName, value.DisplayName),
|
||||
UserStates.ChangePassword => UserHelper.ChangePassword(value.UserName, value.Password, value.NewPassword),
|
||||
UserStates.SaveApp => UserHelper.SaveApp(value.UserName, value.App),
|
||||
_ => false
|
||||
};
|
||||
if (value.UserStatus == UserStates.ChangeTheme)
|
||||
ret = UserHelper.SaveUserCssByName(value.UserName, value.Css);
|
||||
else if (value.UserStatus == UserStates.ChangeDisplayName)
|
||||
ret = UserHelper.SaveDisplayName(value.UserName, value.DisplayName);
|
||||
else if (value.UserStatus == UserStates.ChangePassword)
|
||||
ret = UserHelper.ChangePassword(value.UserName, value.Password, value.NewPassword);
|
||||
else if (value.UserStatus == UserStates.SaveApp)
|
||||
ret = UserHelper.SaveApp(value.UserName, value.App);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,3 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.SignalR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
@ -15,8 +11,8 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
/// <summary>
|
||||
/// 注册用户操作类
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[AllowAnonymous]
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class RegisterController : ControllerBase
|
||||
{
|
||||
|
@ -41,7 +37,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
public async Task<bool> Post([FromServices]IHubContext<SignalRHub> hub, [FromBody]User user)
|
||||
{
|
||||
var ret = UserHelper.Save(user);
|
||||
if (ret) await hub.SendMessageBody(new MessageBody() { Category = "Users", Message = string.Format("{0}-{1}", user.UserName, user.Description) }, HttpContext.RequestAborted);
|
||||
if (ret) await SignalRManager.Send(hub.Clients.All, new MessageBody() { Category = "Users", Message = string.Format("{0}-{1}", user.UserName, user.Description) });
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1,13 +1,7 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.Admin.Query;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -15,15 +9,14 @@ using System.Linq;
|
|||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色维护控制器
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class RolesController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取所有角色数据
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
|
@ -41,17 +34,23 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
[HttpPost("{id}")]
|
||||
public IEnumerable<object> Post(string id, [FromQuery]string type)
|
||||
{
|
||||
var ret = type switch
|
||||
IEnumerable<Role> ret = new List<Role>();
|
||||
switch (type)
|
||||
{
|
||||
"user" => RoleHelper.RetrievesByUserId(id),
|
||||
"group" => RoleHelper.RetrievesByGroupId(id),
|
||||
"menu" => RoleHelper.RetrievesByMenuId(id),
|
||||
_ => new Role[0]
|
||||
};
|
||||
case "user":
|
||||
ret = RoleHelper.RetrievesByUserId(id);
|
||||
break;
|
||||
case "group":
|
||||
ret = RoleHelper.RetrievesByGroupId(id);
|
||||
break;
|
||||
case "menu":
|
||||
ret = RoleHelper.RetrievesByMenuId(id);
|
||||
break;
|
||||
}
|
||||
return ret.Select(m => new { m.Id, m.Checked, m.RoleName, m.Description });
|
||||
}
|
||||
/// <summary>
|
||||
/// 保存角色授权方法
|
||||
/// 保存角色
|
||||
/// </summary>
|
||||
/// <param name="id">角色ID</param>
|
||||
/// <param name="values">选中的ID集合</param>
|
||||
|
@ -59,16 +58,28 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
/// <returns></returns>
|
||||
[HttpPut("{id}")]
|
||||
[ButtonAuthorize(Url = "~/Admin/Roles", Auth = "assignUser,assignGroup,assignMenu,assignApp")]
|
||||
public bool Put(string id, [FromBody]IEnumerable<string> values, [FromQuery]string type) => type switch
|
||||
public bool Put(string id, [FromBody]IEnumerable<string> values, [FromQuery]string type)
|
||||
{
|
||||
"user" => UserHelper.SaveByRoleId(id, values),
|
||||
"group" => GroupHelper.SaveByRoleId(id, values),
|
||||
"menu" => MenuHelper.SaveMenusByRoleId(id, values),
|
||||
"app" => AppHelper.SaveByRoleId(id, values),
|
||||
_ => false
|
||||
};
|
||||
var ret = false;
|
||||
switch (type)
|
||||
{
|
||||
case "user":
|
||||
ret = UserHelper.SaveByRoleId(id, values);
|
||||
break;
|
||||
case "group":
|
||||
ret = GroupHelper.SaveByRoleId(id, values);
|
||||
break;
|
||||
case "menu":
|
||||
ret = MenuHelper.SaveMenusByRoleId(id, values);
|
||||
break;
|
||||
case "app":
|
||||
ret = AppHelper.SaveByRoleId(id, values);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/// <summary>
|
||||
/// 保存角色方法
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
[HttpPost]
|
||||
|
@ -78,7 +89,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
return RoleHelper.Save(value);
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除角色方法
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
[HttpDelete]
|
|
@ -0,0 +1,31 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.Security;
|
||||
using Longbow.Cache;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class SettingsController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ButtonAuthorize(Url = "~/Admin/Settings", Auth = "saveTitle,saveFooter,saveTheme")]
|
||||
public bool Post([FromBody]BootstrapDict value) => DictHelper.SaveSettings(value);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public IEnumerable<ICacheCorsItem> Get() => CacheManager.CorsSites;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class TasksController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public IEnumerable<Task> Get()
|
||||
{
|
||||
return TaskHelper.Retrieves();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using Bootstrap.Admin.Query;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class TracesController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public QueryData<Trace> Get([FromQuery]QueryTraceOptions value)
|
||||
{
|
||||
return value.RetrieveData();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,8 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.Admin.Query;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -15,15 +10,14 @@ using System.Linq;
|
|||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户控制器
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class UsersController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 调用获取所有用户信息 用户管理查询按钮
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
|
@ -34,25 +28,35 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户相关授权操作
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="id">主键</param>
|
||||
/// <param name="type">类型 如角色、部门</param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{id}")]
|
||||
public IEnumerable<object> Post(string id, [FromQuery]string type) => type switch
|
||||
public IEnumerable<object> Post(string id, [FromQuery]string type)
|
||||
{
|
||||
"role" => UserHelper.RetrievesByRoleId(id).Select(p => new
|
||||
IEnumerable<object> ret = null;
|
||||
switch (type)
|
||||
{
|
||||
p.Id,
|
||||
p.DisplayName,
|
||||
p.UserName,
|
||||
p.Checked
|
||||
}).OrderBy(u => u.DisplayName),
|
||||
"group" => UserHelper.RetrievesByGroupId(id),
|
||||
"reset" => UserHelper.RetrieveResetReasonsByUserName(id).Select(u => new { u.Key, u.Value }),
|
||||
_ => new string[0]
|
||||
};
|
||||
case "role":
|
||||
ret = UserHelper.RetrievesByRoleId(id).Select(p => new
|
||||
{
|
||||
p.Id,
|
||||
p.DisplayName,
|
||||
p.UserName,
|
||||
p.Checked
|
||||
});
|
||||
break;
|
||||
case "group":
|
||||
ret = UserHelper.RetrievesByGroupId(id);
|
||||
break;
|
||||
case "reset":
|
||||
ret = UserHelper.RetrieveResetReasonsByUserName(id).Select(u => new { u.Key, u.Value });
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 前台User View调用,新建/更新用户
|
||||
|
@ -62,10 +66,10 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
[ButtonAuthorize(Url = "~/Admin/Users", Auth = "add,edit")]
|
||||
public bool Post([FromBody]User value)
|
||||
{
|
||||
bool ret;
|
||||
var ret = false;
|
||||
if (string.IsNullOrEmpty(value.Id))
|
||||
{
|
||||
value.Description = string.Format("管理员{0}创建用户", User.Identity!.Name);
|
||||
value.Description = string.Format("管理员{0}创建用户", User.Identity.Name);
|
||||
value.ApprovedBy = User.Identity.Name;
|
||||
value.ApprovedTime = DateTime.Now;
|
||||
ret = UserHelper.Save(value);
|
||||
|
@ -78,7 +82,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存授权操作
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="values"></param>
|
||||
|
@ -86,15 +90,23 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
/// <returns></returns>
|
||||
[HttpPut("{id}")]
|
||||
[ButtonAuthorize(Url = "~/Admin/Users", Auth = "assignRole,assignGroup")]
|
||||
public bool Put(string id, [FromBody]IEnumerable<string> values, [FromQuery]string type) => type switch
|
||||
public bool Put(string id, [FromBody]IEnumerable<string> values, [FromQuery]string type)
|
||||
{
|
||||
"role" => RoleHelper.SaveByUserId(id, values),
|
||||
"group" => GroupHelper.SaveByUserId(id, values),
|
||||
_ => false
|
||||
};
|
||||
var ret = false;
|
||||
switch (type)
|
||||
{
|
||||
case "role":
|
||||
ret = RoleHelper.SaveByUserId(id, values);
|
||||
break;
|
||||
case "group":
|
||||
ret = GroupHelper.SaveByUserId(id, values);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除用户操作
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
[HttpDelete]
|
||||
|
@ -105,14 +117,14 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// api 握手协议
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpOptions]
|
||||
public string? Options()
|
||||
public string Options()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.Admin.Models;
|
||||
using Bootstrap.Admin.Models;
|
||||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
@ -11,32 +7,30 @@ using Microsoft.AspNetCore.Mvc;
|
|||
namespace Bootstrap.Admin.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Home Controller
|
||||
///
|
||||
/// </summary>
|
||||
[Authorize]
|
||||
public class HomeController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// Index View
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IActionResult Index()
|
||||
{
|
||||
var model = new HeaderBarModel(User.Identity!.Name);
|
||||
var homeUrl = DictHelper.RetrieveHomeUrl(User.Identity.Name, model.AppId);
|
||||
var useBlazor = DictHelper.RetrieveEnableBlazor();
|
||||
return homeUrl.Equals("~/Home/Index", System.StringComparison.OrdinalIgnoreCase) ? (useBlazor ? Redirect("~/Pages") : (IActionResult)View(model)) : Redirect(homeUrl);
|
||||
var model = new HeaderBarModel(User.Identity);
|
||||
var url = DictHelper.RetrieveHomeUrl(model.AppCode);
|
||||
return url.Equals("~/Home/Index", System.StringComparison.OrdinalIgnoreCase) ? (IActionResult)View(model) : Redirect(url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Error View
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
public IActionResult Error(int? id = 0)
|
||||
public IActionResult Error(int id)
|
||||
{
|
||||
var model = ErrorModel.CreateById(id ?? 0);
|
||||
var model = ErrorModel.CreateById(id);
|
||||
if (id != 403)
|
||||
{
|
||||
var returnUrl = Request.Query[CookieAuthenticationDefaults.ReturnUrlParameter].ToString();
|
||||
|
@ -45,4 +39,4 @@ namespace Bootstrap.Admin.Controllers
|
|||
return View(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[AllowAnonymous]
|
||||
public class ToolsController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IActionResult Index()
|
||||
{
|
||||
var returnUrl = Request.Query[CookieAuthenticationDefaults.ReturnUrlParameter].ToString();
|
||||
return Redirect(returnUrl);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed.
|
||||
#For more information, please see https://aka.ms/containercompat
|
||||
|
||||
FROM microsoft/dotnet:2.2-aspnetcore-runtime-nanoserver-1803 AS base
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
|
||||
FROM microsoft/dotnet:2.2-sdk-nanoserver-1803 AS build
|
||||
WORKDIR /src
|
||||
COPY ["Bootstrap.Admin/Bootstrap.Admin.csproj", "Bootstrap.Admin/"]
|
||||
COPY ["Bootstrap.DataAccess/Bootstrap.DataAccess.csproj", "Bootstrap.DataAccess/"]
|
||||
RUN dotnet restore "Bootstrap.Admin/Bootstrap.Admin.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/Bootstrap.Admin"
|
||||
RUN dotnet build "Bootstrap.Admin.csproj" -c Release -o /app
|
||||
|
||||
FROM build AS publish
|
||||
RUN dotnet publish "Bootstrap.Admin.csproj" -c Release -o /app
|
||||
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app .
|
||||
COPY --from=build ["/src/Bootstrap.Admin/BootstrapAdmin.db", "./BootstrapAdmin.db"]
|
||||
COPY --from=build ["/src/Scripts/Longbow.lic", "./Longbow.lic"]
|
||||
ENTRYPOINT ["dotnet", "Bootstrap.Admin.dll"]
|
|
@ -0,0 +1,35 @@
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Swashbuckle.AspNetCore.Swagger;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
using System.Collections.Generic;
|
||||
using Operation = Swashbuckle.AspNetCore.Swagger.Operation;
|
||||
|
||||
namespace Bootstrap.Admin
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class HttpHeaderOperation : IOperationFilter
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="operation"></param>
|
||||
/// <param name="context"></param>
|
||||
public void Apply(Operation operation, OperationFilterContext context)
|
||||
{
|
||||
if (operation.Parameters == null) operation.Parameters = new List<IParameter>();
|
||||
|
||||
if (context.MethodInfo.GetCustomAttributes(typeof(AllowAnonymousAttribute), true).Length == 0)
|
||||
{
|
||||
operation.Parameters.Add(new NonBodyParameter()
|
||||
{
|
||||
Name = "Authorization", //添加Authorization头部参数
|
||||
In = "header",
|
||||
Type = "string",
|
||||
Required = false
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
|
||||
FROM microsoft/dotnet:2.2-sdk AS build
|
||||
WORKDIR /src
|
||||
COPY ["Bootstrap.Admin/Bootstrap.Admin.csproj", "Bootstrap.Admin/"]
|
||||
COPY ["Bootstrap.DataAccess/Bootstrap.DataAccess.csproj", "Bootstrap.DataAccess/"]
|
||||
RUN dotnet restore "Bootstrap.Admin/Bootstrap.Admin.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/Bootstrap.Admin"
|
||||
RUN dotnet build "Bootstrap.Admin.csproj" -c Release -o /app
|
||||
|
||||
FROM build AS publish
|
||||
RUN dotnet publish "Bootstrap.Admin.csproj" -c Release -o /app
|
||||
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app .
|
||||
COPY --from=publish ["/src/Bootstrap.Admin/BootstrapAdmin.db", "./BootstrapAdmin.db"]
|
||||
COPY --from=publish ["/src/Scripts/Longbow.lic", "./Longbow.lic"]
|
||||
ENTRYPOINT ["dotnet", "Bootstrap.Admin.dll"]
|
|
@ -1,13 +1,9 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
namespace Bootstrap.Admin.Models
|
||||
namespace Bootstrap.Admin.Models
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ErrorModel : ModelBase
|
||||
public class ErrorModel
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -17,28 +13,28 @@ namespace Bootstrap.Admin.Models
|
|||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Title { get; set; } = "";
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Content { get; set; } = "";
|
||||
public string Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Image { get; set; } = "";
|
||||
public string Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
||||
public string Detail { get; set; } = "";
|
||||
public string Detail { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string ReturnUrl { get; set; } = "";
|
||||
public string ReturnUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -53,7 +49,7 @@ namespace Bootstrap.Admin.Models
|
|||
Title = "服务器内部错误",
|
||||
Content = "服务器内部错误",
|
||||
Detail = "相关错误信息已经记录到日志中,请登录服务器或后台管理中查看",
|
||||
Image = "~/images/error_icon.png",
|
||||
Image = "~/Images/error_icon.png",
|
||||
ReturnUrl = "~/Admin/Index"
|
||||
};
|
||||
|
||||
|
@ -65,7 +61,7 @@ namespace Bootstrap.Admin.Models
|
|||
case 404:
|
||||
model.Title = "资源未找到";
|
||||
model.Content = "请求资源未找到";
|
||||
model.Image = "~/images/404_icon.png";
|
||||
model.Image = "~/Images/404_icon.png";
|
||||
break;
|
||||
case 403:
|
||||
model.Title = "未授权请求";
|
|
@ -0,0 +1,56 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using System.Security.Principal;
|
||||
|
||||
namespace Bootstrap.Admin.Models
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class HeaderBarModel : ModelBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="identity"></param>
|
||||
public HeaderBarModel(IIdentity identity)
|
||||
{
|
||||
var user = UserHelper.RetrieveUserByUserName(identity.Name);
|
||||
Icon = string.Format("{0}{1}", DictHelper.RetrieveIconFolderPath(), user.Icon);
|
||||
DisplayName = user.DisplayName;
|
||||
UserName = user.UserName;
|
||||
AppCode = user.App;
|
||||
Css = user.Css;
|
||||
ActiveCss = string.IsNullOrEmpty(Css) ? Theme : Css;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string UserName { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DisplayName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 用户头像地址
|
||||
/// </summary>
|
||||
public string Icon { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取/设置 个人网站样式
|
||||
/// </summary>
|
||||
public string Css { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得 当前设置的默认应用
|
||||
/// </summary>
|
||||
public string AppCode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得 当前样式
|
||||
/// </summary>
|
||||
public string ActiveCss { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using Bootstrap.DataAccess;
|
||||
|
||||
namespace Bootstrap.Admin.Models
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class LoginModel : ModelBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public LoginModel()
|
||||
{
|
||||
ImageLibUrl = DictHelper.RetrieveImagesLibUrl();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证码图床地址
|
||||
/// </summary>
|
||||
public string ImageLibUrl { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否登录认证失败
|
||||
/// </summary>
|
||||
public bool AuthFailed { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
namespace Bootstrap.Admin.Models
|
||||
namespace Bootstrap.Admin.Models
|
||||
{
|
||||
/// <summary>
|
||||
///
|
|
@ -0,0 +1,41 @@
|
|||
using Bootstrap.DataAccess;
|
||||
|
||||
namespace Bootstrap.Admin.Models
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ModelBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public ModelBase()
|
||||
{
|
||||
Title = DictHelper.RetrieveWebTitle();
|
||||
Footer = DictHelper.RetrieveWebFooter();
|
||||
Theme = DictHelper.RetrieveActiveTheme();
|
||||
IsDemo = DictHelper.RetrieveSystemModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Title { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Footer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 网站样式全局设置
|
||||
/// </summary>
|
||||
public string Theme { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否为演示系统
|
||||
/// </summary>
|
||||
public bool IsDemo { get; protected set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.Security;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bootstrap.Admin.Models
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NavigatorBarModel : HeaderBarModel
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="controller"></param>
|
||||
public NavigatorBarModel(ControllerBase controller) : base(controller.User.Identity)
|
||||
{
|
||||
Navigations = MenuHelper.RetrieveSystemMenus(UserName, $"~{controller.HttpContext.Request.Path}");
|
||||
var authApps = AppHelper.RetrievesByUserName(controller.User.Identity.Name);
|
||||
Applications = DictHelper.RetrieveApps().Where(app => app.Key == "0" || authApps.Any(key => key.Equals(app.Key, StringComparison.OrdinalIgnoreCase)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IEnumerable<BootstrapMenu> Navigations { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IEnumerable<KeyValuePair<string, string>> Applications { get; private set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bootstrap.Admin.Models
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ProfilesModel : ThemeModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得 头像文件大小
|
||||
/// </summary>
|
||||
public long Size { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得 头像文件名称
|
||||
/// </summary>
|
||||
public string FileName { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="host"></param>
|
||||
/// <param name="controller"></param>
|
||||
public ProfilesModel(ControllerBase controller, IHostingEnvironment host) : base(controller)
|
||||
{
|
||||
if (host != null)
|
||||
{
|
||||
var fileName = Path.Combine(host.WebRootPath, Icon.TrimStart('~', '/').Replace('/', Path.DirectorySeparatorChar));
|
||||
|
||||
// 数据库存储的个人图片有后缀 default.jpg?v=1234567
|
||||
fileName = fileName.Split('?').FirstOrDefault();
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
Size = new FileInfo(fileName).Length;
|
||||
FileName = Path.GetFileName(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.Security;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bootstrap.Admin.Models
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ThemeModel : NavigatorBarModel
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="controller"></param>
|
||||
public ThemeModel(ControllerBase controller) : base(controller)
|
||||
{
|
||||
Themes = DictHelper.RetrieveThemes();
|
||||
}
|
||||
/// <summary>
|
||||
/// 获得 系统配置的所有样式表
|
||||
/// </summary>
|
||||
public IEnumerable<BootstrapDict> Themes { get; }
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace Bootstrap.Client
|
||||
namespace Bootstrap.Admin
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -14,15 +14,14 @@ namespace Bootstrap.Client
|
|||
/// <param name="args"></param>
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
CreateWebHostBuilder(args).Build().Run();
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(builder => builder.UseStartup<Startup>());
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args).UseSentry().UseStartup<Startup>();
|
||||
}
|
||||
}
|
|
@ -16,11 +16,6 @@
|
|||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Docker": {
|
||||
"commandName": "Docker",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}"
|
||||
},
|
||||
"Bootstrap.Admin": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
|
@ -28,6 +23,11 @@
|
|||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "http://localhost:50852/"
|
||||
},
|
||||
"Docker": {
|
||||
"commandName": "Docker",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,61 +1,46 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.Security;
|
||||
using Longbow.Web.Mvc;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bootstrap.Admin.Query
|
||||
{
|
||||
/// <summary>
|
||||
/// 字典表查询类
|
||||
///
|
||||
/// </summary>
|
||||
public class QueryDictOption : PaginationOption
|
||||
{
|
||||
/// <summary>
|
||||
/// 字典分项
|
||||
/// </summary>
|
||||
public string? Category { get; set; }
|
||||
|
||||
public string Category { get; set; }
|
||||
/// <summary>
|
||||
/// 字典名称
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// 字典种类
|
||||
/// </summary>
|
||||
public string? Define { get; set; }
|
||||
|
||||
public string Define { get; set; }
|
||||
/// <summary>
|
||||
/// 字典表查询
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public QueryData<BootstrapDict> RetrieveData()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Order)) Order = "asc";
|
||||
if (string.IsNullOrEmpty(Sort)) Sort = "Category";
|
||||
|
||||
var data = DictHelper.RetrieveDicts();
|
||||
if (!string.IsNullOrEmpty(Category))
|
||||
{
|
||||
data = data.Where(t => t.Category.Contains(Category, StringComparison.OrdinalIgnoreCase));
|
||||
data = data.Where(t => t.Category.Contains(Category));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
data = data.Where(t => t.Name.Contains(Name, StringComparison.OrdinalIgnoreCase));
|
||||
data = data.Where(t => t.Name.Contains(Name));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Define))
|
||||
{
|
||||
data = data.Where(t => t.Define.ToString() == Define);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Search))
|
||||
{
|
||||
data = data.Where(t => t.Category.Contains(Search, StringComparison.OrdinalIgnoreCase) || t.Name.Contains(Search, StringComparison.OrdinalIgnoreCase) || t.Code.Contains(Search, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
var ret = new QueryData<BootstrapDict>();
|
||||
ret.total = data.Count();
|
||||
// 通过option.Sort属性判断对那列进行排序
|
||||
|
@ -78,4 +63,4 @@ namespace Bootstrap.Admin.Query
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.Mvc;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
@ -10,22 +6,20 @@ using System.Linq;
|
|||
namespace Bootstrap.Admin.Query
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序异常查询条件类
|
||||
///
|
||||
/// </summary>
|
||||
public class QueryExceptionOption : PaginationOption
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 开始时间
|
||||
///
|
||||
/// </summary>
|
||||
public DateTime? StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 结束时间
|
||||
///
|
||||
/// </summary>
|
||||
public DateTime? EndTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 查询方法
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public QueryData<object> Retrieves()
|
|
@ -1,31 +1,24 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.Mvc;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bootstrap.Admin.Query
|
||||
{
|
||||
/// <summary>
|
||||
/// 部门查询条件类
|
||||
///
|
||||
/// </summary>
|
||||
public class QueryGroupOption : PaginationOption
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 部门名称
|
||||
///
|
||||
/// </summary>
|
||||
public string? GroupName { get; set; }
|
||||
|
||||
public string GroupName { get; set; }
|
||||
/// <summary>
|
||||
/// 获得/设置 部门描述
|
||||
///
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
/// <summary>
|
||||
/// 部门查询数据方法
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public QueryData<object> RetrieveData()
|
||||
|
@ -34,21 +27,17 @@ namespace Bootstrap.Admin.Query
|
|||
var data = GroupHelper.Retrieves();
|
||||
if (!string.IsNullOrEmpty(GroupName))
|
||||
{
|
||||
data = data.Where(t => t.GroupName.Contains(GroupName, StringComparison.OrdinalIgnoreCase));
|
||||
data = data.Where(t => t.GroupName.Contains(GroupName));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Description))
|
||||
{
|
||||
data = data.Where(t => t.Description?.Contains(Description, StringComparison.OrdinalIgnoreCase) ?? false);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Search))
|
||||
{
|
||||
data = data.Where(t => t.GroupName.Contains(Search, StringComparison.OrdinalIgnoreCase) || (t.Description?.Contains(Search, StringComparison.OrdinalIgnoreCase) ?? false));
|
||||
data = data.Where(t => t.Description.Contains(Description));
|
||||
}
|
||||
var ret = new QueryData<object>();
|
||||
ret.total = data.Count();
|
||||
data = Order == "asc" ? data.OrderBy(t => t.GroupName) : data.OrderByDescending(t => t.GroupName);
|
||||
ret.rows = data.Skip(Offset).Take(Limit).Select(g => new { g.Id, g.GroupCode, g.GroupName, g.Description });
|
||||
ret.rows = data.Skip(Offset).Take(Limit).Select(g => new { g.Id, g.GroupName, g.Description });
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +1,31 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.Mvc;
|
||||
using System;
|
||||
|
||||
namespace Bootstrap.Admin.Query
|
||||
{
|
||||
/// <summary>
|
||||
/// 操作日志查询条件类
|
||||
///
|
||||
/// </summary>
|
||||
public class QueryLogOption : PaginationOption
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 操作类型
|
||||
///
|
||||
/// </summary>
|
||||
public string? OperateType { get; set; }
|
||||
public string OperateType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 开始时间
|
||||
///
|
||||
/// </summary>
|
||||
public DateTime? OperateTimeStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 结束时间
|
||||
///
|
||||
/// </summary>
|
||||
public DateTime? OperateTimeEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 获取查询分页数据
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public QueryData<Log> RetrieveData()
|
||||
|
@ -41,4 +37,4 @@ namespace Bootstrap.Admin.Query
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.Mvc;
|
||||
using System;
|
||||
|
||||
|
@ -26,7 +22,7 @@ namespace Bootstrap.Admin.Query
|
|||
/// <summary>
|
||||
/// 登录IP地址
|
||||
/// </summary>
|
||||
public string? LoginIP { get; set; }
|
||||
public string LoginIP { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -34,6 +30,7 @@ namespace Bootstrap.Admin.Query
|
|||
/// <returns></returns>
|
||||
public QueryData<LoginUser> RetrieveData()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Order)) Order = "LoginTime desc";
|
||||
var data = LoginHelper.RetrievePages(this, StartTime, EndTime, LoginIP);
|
||||
return new QueryData<LoginUser>
|
||||
{
|
|
@ -1,7 +1,3 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.Mvc;
|
||||
using System;
|
||||
|
@ -10,66 +6,62 @@ using System.Linq;
|
|||
namespace Bootstrap.Admin.Query
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
public class QueryMenuOption : PaginationOption
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
public string? ParentName { get; set; }
|
||||
public string ParentName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
public string? Category { get; set; }
|
||||
public string Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
public string? IsResource { get; set; }
|
||||
public string IsResource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
public string? AppId { get; set; }
|
||||
public string AppCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userName"></param>
|
||||
/// <returns></returns>
|
||||
public QueryData<object> RetrieveData(string? userName)
|
||||
public QueryData<object> RetrieveData(string userName)
|
||||
{
|
||||
var data = MenuHelper.RetrieveMenusByUserName(userName);
|
||||
if (!string.IsNullOrEmpty(ParentName))
|
||||
{
|
||||
data = data.Where(t => t.Name.Contains(ParentName, StringComparison.OrdinalIgnoreCase) || (t.ParentName != null && t.ParentName.Contains(ParentName, StringComparison.OrdinalIgnoreCase)));
|
||||
data = data.Where(t => t.ParentName != null && t.ParentName.Contains(ParentName));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
data = data.Where(t => t.Name.Contains(Name, StringComparison.OrdinalIgnoreCase));
|
||||
data = data.Where(t => t.Name.Contains(Name));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Category))
|
||||
{
|
||||
data = data.Where(t => t.Category.Contains(Category, StringComparison.OrdinalIgnoreCase));
|
||||
data = data.Where(t => t.Category.Contains(Category));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(IsResource))
|
||||
{
|
||||
data = data.Where(t => t.IsResource.ToString() == IsResource);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(AppId))
|
||||
if (!string.IsNullOrEmpty(AppCode))
|
||||
{
|
||||
data = data.Where(t => t.Application.Equals(AppId, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Search))
|
||||
{
|
||||
data = data.Where(t => t.Name.Contains(Search, StringComparison.OrdinalIgnoreCase) || t.ParentName.Contains(Search, StringComparison.OrdinalIgnoreCase));
|
||||
data = data.Where(t => t.Application.Equals(AppCode, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
var ret = new QueryData<object>();
|
||||
ret.total = data.Count();
|
||||
|
@ -115,4 +107,4 @@ namespace Bootstrap.Admin.Query
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +1,24 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.Mvc;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bootstrap.Admin.Query
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色查询条件类
|
||||
///
|
||||
/// </summary>
|
||||
public class QueryRoleOption : PaginationOption
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色名称
|
||||
///
|
||||
/// </summary>
|
||||
public string? RoleName { get; set; }
|
||||
|
||||
public string RoleName { get; set; }
|
||||
/// <summary>
|
||||
/// 角色描述
|
||||
///
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
/// <summary>
|
||||
/// 角色数据
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public QueryData<object> RetrieveData()
|
||||
|
@ -34,15 +27,11 @@ namespace Bootstrap.Admin.Query
|
|||
var data = RoleHelper.Retrieves();
|
||||
if (!string.IsNullOrEmpty(RoleName))
|
||||
{
|
||||
data = data.Where(t => t.RoleName.Contains(RoleName, StringComparison.OrdinalIgnoreCase));
|
||||
data = data.Where(t => t.RoleName.Contains(RoleName));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Description))
|
||||
{
|
||||
data = data.Where(t => t.Description.Contains(Description, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Search))
|
||||
{
|
||||
data = data.Where(t => t.RoleName.Contains(Search, StringComparison.OrdinalIgnoreCase) || t.Description.Contains(Search, StringComparison.OrdinalIgnoreCase));
|
||||
data = data.Where(t => t.Description.Contains(Description));
|
||||
}
|
||||
var ret = new QueryData<object>();
|
||||
ret.total = data.Count();
|
||||
|
@ -51,4 +40,4 @@ namespace Bootstrap.Admin.Query
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.Mvc;
|
||||
using System;
|
||||
|
||||
|
@ -26,7 +22,7 @@ namespace Bootstrap.Admin.Query
|
|||
/// <summary>
|
||||
/// 请求IP地址
|
||||
/// </summary>
|
||||
public string? AccessIP { get; set; }
|
||||
public string AccessIP { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
|
@ -1,31 +1,24 @@
|
|||
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
|
||||
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
|
||||
// Website: https://admin.blazor.zone
|
||||
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.Mvc;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bootstrap.Admin.Query
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户维护查询条件类
|
||||
///
|
||||
/// </summary>
|
||||
public class QueryUserOption : PaginationOption
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 用户登录名称
|
||||
///
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// 获得/设置 用户显示名称
|
||||
///
|
||||
/// </summary>
|
||||
public string? DisplayName { get; set; }
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
/// <summary>
|
||||
/// 获取用户分页数据
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public QueryData<object> RetrieveData()
|
||||
|
@ -34,15 +27,11 @@ namespace Bootstrap.Admin.Query
|
|||
var data = UserHelper.Retrieves();
|
||||
if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
data = data.Where(t => t.UserName.Contains(Name, StringComparison.OrdinalIgnoreCase));
|
||||
data = data.Where(t => t.UserName.Contains(Name));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(DisplayName))
|
||||
{
|
||||
data = data.Where(t => t.DisplayName.Contains(DisplayName, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Search))
|
||||
{
|
||||
data = data.Where(t => t.DisplayName.Contains(Search, StringComparison.OrdinalIgnoreCase) || t.Description.Contains(Search, StringComparison.OrdinalIgnoreCase) || t.UserName.Contains(Search, StringComparison.OrdinalIgnoreCase));
|
||||
data = data.Where(t => t.DisplayName.Contains(DisplayName));
|
||||
}
|
||||
var ret = new QueryData<object>();
|
||||
ret.total = data.Count();
|
||||
|
@ -78,4 +67,4 @@ namespace Bootstrap.Admin.Query
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Forgot password?" xml:space="preserve">
|
||||
<value>忘记密码</value>
|
||||
</data>
|
||||
<data name="Invalid email or password." xml:space="preserve">
|
||||
<value>用户名或密码错误!</value>
|
||||
</data>
|
||||
<data name="Login" xml:space="preserve">
|
||||
<value>登 陆</value>
|
||||
</data>
|
||||
<data name="Password" xml:space="preserve">
|
||||
<value>密码</value>
|
||||
</data>
|
||||
<data name="Please input the password" xml:space="preserve">
|
||||
<value>请输入密码</value>
|
||||
</data>
|
||||
<data name="Please input the user name" xml:space="preserve">
|
||||
<value>请输入用户名</value>
|
||||
</data>
|
||||
<data name="Remember me" xml:space="preserve">
|
||||
<value>记住密码自动登录</value>
|
||||
</data>
|
||||
<data name="Sign up" xml:space="preserve">
|
||||
<value>申请账号</value>
|
||||
</data>
|
||||
<data name="UserName" xml:space="preserve">
|
||||
<value>用户名</value>
|
||||
</data>
|
||||
</root>
|
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Home" xml:space="preserve">
|
||||
<value>首页</value>
|
||||
</data>
|
||||
</root>
|
|
@ -0,0 +1,34 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using System;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace Bootstrap.Admin
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class SignalRManager
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public static async System.Threading.Tasks.Task Send(IClientProxy client, MessageBody args) => await client.SendAsync("rev", args);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="ex"></param>
|
||||
/// <returns></returns>
|
||||
public static async System.Threading.Tasks.Task Send<T>(IHubContext<T> context, Exception ex) where T : Hub
|
||||
{
|
||||
var category = "App";
|
||||
if (ex.GetType().IsSubclassOf(typeof(DbException))) category = "DB";
|
||||
var message = new MessageBody() { Category = category, Message = ex.Message };
|
||||
await Send(context.Clients.All, message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.Security.Filter;
|
||||
using Longbow.Web;
|
||||
using Longbow.Web.SignalR;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.AspNetCore.Mvc.Versioning;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Swashbuckle.AspNetCore.Swagger;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Unicode;
|
||||
|
||||
namespace Bootstrap.Admin
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Startup
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="configuration"></param>
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton(HtmlEncoder.Create(UnicodeRanges.All));
|
||||
services.AddLocalization(op => op.ResourcesPath = "Resources");
|
||||
services.Configure<CookiePolicyOptions>(options =>
|
||||
{
|
||||
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
|
||||
options.CheckConsentNeeded = context => true;
|
||||
options.MinimumSameSitePolicy = SameSiteMode.None;
|
||||
});
|
||||
services.AddCors();
|
||||
services.AddLogging(builder => builder.AddFileLogger().AddDBLogger(ExceptionsHelper.Log));
|
||||
services.AddConfigurationManager(Configuration);
|
||||
services.AddCacheManager(Configuration);
|
||||
services.AddDbAdapter();
|
||||
services.AddIPLocator(DictHelper.ConfigIPLocator);
|
||||
services.AddOnlineUsers();
|
||||
var dataProtectionBuilder = services.AddDataProtection(op => op.ApplicationDiscriminator = Configuration["ApplicationDiscriminator"])
|
||||
.SetApplicationName(Configuration["ApplicationName"])
|
||||
.PersistKeysToFileSystem(new DirectoryInfo(Configuration["KeyPath"]));
|
||||
if (Configuration["DisableAutomaticKeyGeneration"] == "True") dataProtectionBuilder.DisableAutomaticKeyGeneration();
|
||||
services.AddSignalR().AddJsonProtocalDefault();
|
||||
services.AddSignalRExceptionFilterHandler<SignalRHub>(async (client, ex) => await SignalRManager.Send(client, ex));
|
||||
services.AddResponseCompression();
|
||||
services.AddMvc(options =>
|
||||
{
|
||||
options.Filters.Add<BootstrapAdminAuthorizeFilter>();
|
||||
options.Filters.Add<ExceptionFilter>();
|
||||
options.Filters.Add<SignalRExceptionFilter<SignalRHub>>();
|
||||
}).AddJsonOptions(options =>
|
||||
{
|
||||
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
|
||||
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
|
||||
JsonConvert.DefaultSettings = () => options.SerializerSettings;
|
||||
}).AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
|
||||
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
|
||||
{
|
||||
options.Cookie.Path = "/";
|
||||
if (!string.IsNullOrEmpty(Configuration["Domain"])) options.Cookie.Domain = Configuration["Domain"];
|
||||
});
|
||||
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.AddSwaggerGen(options =>
|
||||
{
|
||||
options.SwaggerDoc("v1", new Info
|
||||
{
|
||||
Version = "v1",
|
||||
Title = "BootstrapAdmin API"
|
||||
});
|
||||
|
||||
//Set the comments path for the swagger json and ui.
|
||||
var xmlPath = Path.Combine(AppContext.BaseDirectory, "Bootstrap.Admin.xml");
|
||||
options.IncludeXmlComments(xmlPath);
|
||||
options.OperationFilter<HttpHeaderOperation>(); // 添加httpHeader参数
|
||||
});
|
||||
services.AddButtonAuthorization(MenuHelper.AuthorizateButtons);
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="env"></param>
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
{
|
||||
app.UseForwardedHeaders(new ForwardedHeadersOptions() { ForwardedHeaders = ForwardedHeaders.All });
|
||||
app.UseRequestLocalization(options => options.AddSupportedCultures("en-us", "zh-CN").AddSupportedUICultures("en-us", "zh-CN"));
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
app.UseHsts();
|
||||
}
|
||||
app.UseStatusCodePagesWithReExecute("/Home/Error/{0}");
|
||||
app.UseCors(builder => builder.WithOrigins(Configuration["AllowOrigins"].Split(',', StringSplitOptions.RemoveEmptyEntries)).AllowAnyHeader().AllowAnyMethod().AllowCredentials());
|
||||
app.UseHttpsRedirection();
|
||||
app.UseResponseCompression();
|
||||
app.UseStaticFiles();
|
||||
app.UseAuthentication();
|
||||
app.UseBootstrapAdminAuthorization(RoleHelper.RetrieveRolesByUserName, RoleHelper.RetrieveRolesByUrl, AppHelper.RetrievesByUserName);
|
||||
app.UseOnlineUsers(callback: TraceHelper.Save);
|
||||
app.UseCacheManagerCorsHandler();
|
||||
app.UseSignalR(routes => { routes.MapHub<SignalRHub>("/NotiHub"); });
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
});
|
||||
app.UseWhen(context => context.Request.Path.StartsWithSegments("/swagger"), builder =>
|
||||
{
|
||||
builder.Use(async (context, next) =>
|
||||
{
|
||||
if (!context.User.Identity.IsAuthenticated) await context.ChallengeAsync();
|
||||
else await next();
|
||||
});
|
||||
});
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(c =>
|
||||
{
|
||||
c.SwaggerEndpoint($"{Configuration["SwaggerPathBase"]}/swagger/v1/swagger.json", "BootstrapAdmin API V1");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
@model LoginModel
|
||||
@model LoginModel
|
||||
@inject IViewLocalizer Localizer
|
||||
@{
|
||||
ViewBag.Title = Model.Title;
|
||||
Layout = "_Layout";
|
||||
|
@ -7,31 +8,34 @@
|
|||
<environment include="Development">
|
||||
<link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
|
||||
<link href="~/lib/font-awesome/css/font-awesome.css" rel="stylesheet" />
|
||||
<link href="~/lib/sweetalert/sweetalert2.css" rel="stylesheet" />
|
||||
<link href="~/lib/bootstrap-sweetalert/sweetalert.css" rel="stylesheet" />
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<link href="~/lib/twitter-bootstrap/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="~/lib/font-awesome/css/font-awesome.min.css" rel="stylesheet" />
|
||||
<link href="~/lib/sweetalert/sweetalert2.min.css" rel="stylesheet" />
|
||||
<link href="~/lib/bootstrap-sweetalert/sweetalert.min.css" rel="stylesheet" />
|
||||
</environment>
|
||||
<link href="~/lib/captcha/slidercaptcha.css" rel="stylesheet" />
|
||||
<link href="~/css/theme.css" rel="stylesheet" asp-append-version="true" />
|
||||
<link href="~/css/login-footer.css" rel="stylesheet" asp-append-version="true" />
|
||||
<link href="~/css/login.css" rel="stylesheet" asp-append-version="true" />
|
||||
<link href="~/css/login-responsive.css" rel="stylesheet" asp-append-version="true" />
|
||||
@if (!string.IsNullOrEmpty(Model.Theme))
|
||||
{
|
||||
<link href="~/css/@Model.Theme" rel="stylesheet" asp-append-version="true" />
|
||||
}
|
||||
}
|
||||
@section javascript {
|
||||
<environment include="Development">
|
||||
<script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.js"></script>
|
||||
<script src="~/lib/validate/jquery.validate.js"></script>
|
||||
<script src="~/lib/validate/localization/messages_zh.js"></script>
|
||||
<script src="~/lib/sweetalert/sweetalert2.js" rel="stylesheet"></script>
|
||||
<script src="~/lib/bootstrap-sweetalert/sweetalert.js"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="~/lib/validate/jquery.validate.min.js"></script>
|
||||
<script src="~/lib/validate/localization/messages_zh.min.js"></script>
|
||||
<script src="~/lib/sweetalert/sweetalert2.min.js" rel="stylesheet"></script>
|
||||
<script src="~/lib/bootstrap-sweetalert/sweetalert.min.js"></script>
|
||||
</environment>
|
||||
<script src="~/lib/captcha/longbow.slidercaptcha.js"></script>
|
||||
<script src="~/lib/longbow/longbow.common.js"></script>
|
||||
|
@ -40,105 +44,41 @@
|
|||
}
|
||||
<div class="container">
|
||||
<input id="imgUrl" type="hidden" value="@Model.ImageLibUrl" />
|
||||
<form id="login" method="post" class="form-signin" data-demo="@Model.IsDemo">
|
||||
<form id="login" method="post" class="form-signin">
|
||||
<h2 class="form-signin-heading">@Model.Title</h2>
|
||||
<div class="login-wrap" data-auth="@Model.AuthFailed" data-toggle="LgbValidate" data-valid-button="button[type='submit']">
|
||||
<div class="alert alert-danger d-none" asp-condition="@Model.AuthFailed">用户名或密码错误!</div>
|
||||
<div id="loginUser" class="form-group">
|
||||
<div class="alert alert-danger" asp-condition="@Model.AuthFailed">@Localizer["Invalid email or password."] </div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
<span class="fa fa-user"></span>
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" name="userName" class="form-control" data-toggle="tooltip" placeholder="用户名" maxlength="16" data-required-msg="请输入用户名" value="" autofocus data-valid="true" />
|
||||
<input type="text" name="userName" class="form-control" placeholder="@Localizer["UserName"]" maxlength="16" data-required-msg="@Localizer["Please input the user name"]" value="@ViewBag.UserName" autofocus data-valid="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="loginPwd" class="form-group">
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
<span class="fa fa-lock"></span>
|
||||
</div>
|
||||
</div>
|
||||
<input type="password" name="password" class="form-control" value="" data-toggle="tooltip" placeholder="密码" maxlength="16" autocomplete="off" data-required-msg="请输入密码" data-valid="true" />
|
||||
<input type="password" name="password" class="form-control" value="@ViewBag.Password" placeholder="@Localizer["Password"]" maxlength="16" data-required-msg="@Localizer["Please input the password"]" data-valid="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div asp-condition="@Model.AllowMobile">
|
||||
<div id="loginMobile" class="form-group d-none">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
<span class="fa fa-user"></span>
|
||||
</div>
|
||||
</div>
|
||||
<input type="tel" id="phone" name="phone" class="form-control digits" data-toggle="tooltip" placeholder="手机号码" minlength="11" maxlength="11" data-required-msg="请输入手机号码" value="" data-valid="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="loginSMS" class="form-group d-none">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
<span class="fa fa-lock"></span>
|
||||
</div>
|
||||
</div>
|
||||
<input type="number" id="code" name="code" class="form-control digits" data-toggle="tooltip" disabled value="" placeholder="验证码" maxlength="4" data-required-msg="请输入验证码" data-valid="true" />
|
||||
<div class="input-group-append">
|
||||
<button type="button" id="btnSendCode" class="btn btn-sms" data-toggle="tooltip" title="点击发送验证码">发送验证码</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group rememberPwd" onselectstart="return false">
|
||||
<i class="fa fa-square-o"></i>
|
||||
<span>@Localizer["Remember me"]</span>
|
||||
<input id="remember" name="remember" type="hidden" value="false" />
|
||||
</div>
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="form-group rememberPwd" onselectstart="return false">
|
||||
<i class="fa fa-square-o"></i>
|
||||
<span>记住密码自动登录</span>
|
||||
<input id="remember" name="remember" type="hidden" value="false" />
|
||||
</div>
|
||||
<div asp-condition="@Model.AllowMobile">
|
||||
<a id="loginType" data-value="username" href="#" class="">短信验证登陆</a>
|
||||
</div>
|
||||
<button class="btn btn-lg btn-login btn-block" type="submit">@Localizer["Login"]</button>
|
||||
<div class="login-footer">
|
||||
<a href="#" data-method="register">@Localizer["Sign up"]</a>
|
||||
<a href="#" data-method="forgot">@Localizer["Forgot password?"]</a>
|
||||
</div>
|
||||
<button class="btn btn-lg btn-login btn-block" data-oauth="@Model.AllowOAuth" data-toggle="tooltip" title="不填写密码默认使用 Gitee 认证" type="submit">登 录</button>
|
||||
<div class="d-flex justify-content-between">
|
||||
<a href="#" data-method="register">申请账号</a>
|
||||
<a href="#" data-method="forgot">忘记密码</a>
|
||||
</div>
|
||||
<div asp-condition="@Model.AllowOAuth">
|
||||
<div class="login-other">
|
||||
<span class="text-muted">
|
||||
其他方式登录
|
||||
</span>
|
||||
</div>
|
||||
<div class="login-list">
|
||||
<div class="item">
|
||||
<a href="~/Account/Gitee" data-toggle="tooltip" title="使用 Gitee 帐号登录">
|
||||
<img class="item" src="~/images/gitee.svg" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a href="~/Account/GitHub" data-toggle="tooltip" title="使用 GitHub 帐号登录">
|
||||
<img class="item" src="~/images/git.svg" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a href="#" data-toggle="tooltip" title="微信-暂未实现">
|
||||
<img class="item" src="~/images/weixin-2.svg" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a href="~/Account/Tencent" data-toggle="tooltip" title="使用 QQ 账号登录">
|
||||
<img class="item" src="~/images/qq.svg" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a href="~/Account/Alipay" data-toggle="tooltip" title="使用支付宝账号登录">
|
||||
<img class="item" src="~/images/zhifubao.svg" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slidercaptcha @(Model.ShowOAuth ? "card oauth" : "card")">
|
||||
<div class="slidercaptcha card">
|
||||
<div class="card-header">
|
||||
<span>请完成安全验证</span>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
|
@ -148,7 +88,6 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@await Html.PartialAsync("LoginFooter", Model)
|
||||
<div class="modal fade" id="dialogNew" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
|
||||
<div class="modal-content" data-toggle="LgbValidate" data-valid-button="#btnSubmit" data-valid-modal="#dialogNew">
|
||||
|
@ -158,14 +97,14 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="userName">登录名称:</label>
|
||||
<label for="userName">登陆名称:</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
<span class="fa fa-user-plus"></span>
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" id="userName" autocomplete="off" class="form-control" placeholder="登录账号不可为空" userName="true" minlength="4" maxlength="16" remote="api/Register" data-remote-msg="此用户已存在" data-valid="true" />
|
||||
<input type="text" id="userName" autocomplete="off" class="form-control" placeholder="登陆账号不可为空" userName="true" minlength="4" maxlength="16" remote="api/Register" data-remote-msg="此用户已存在" data-valid="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -187,7 +126,7 @@
|
|||
<span class="fa fa-lock"></span>
|
||||
</div>
|
||||
</div>
|
||||
<input type="password" id="password" class="form-control" value="" placeholder="密码不可为空" maxlength="16" data-valid="true" autocomplete="off" />
|
||||
<input type="password" id="password" class="form-control" value="" placeholder="密码不可为空" maxlength="16" data-valid="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -198,7 +137,7 @@
|
|||
<span class="fa fa-lock"></span>
|
||||
</div>
|
||||
</div>
|
||||
<input type="password" id="assurePassword" class="form-control" value="" placeholder="确认密码" maxlength="16" equalTo="#password" data-valid="true" autocomplete="off" />
|
||||
<input type="password" id="assurePassword" class="form-control" value="" placeholder="确认密码" maxlength="16" equalTo="#password" data-valid="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -235,14 +174,14 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="f_userName">登录账号:</label>
|
||||
<label for="f_userName">登陆账号:</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
<span class="fa fa-user-plus"></span>
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" id="f_userName" autocomplete="off" class="form-control" placeholder="登录账号不可为空" minlength="4" maxlength="16" data-valid="true" />
|
||||
<input type="text" id="f_userName" autocomplete="off" class="form-control" placeholder="登陆账号不可为空" minlength="4" maxlength="16" data-valid="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
|
@ -12,6 +12,7 @@
|
|||
<link href="~/lib/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" />
|
||||
</environment>
|
||||
<style>
|
||||
|
||||
.card .card-body {
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
@ -19,19 +20,6 @@
|
|||
.spark {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.loading {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 178px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.loading span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
}
|
||||
@section javascript {
|
||||
|
@ -96,9 +84,7 @@
|
|||
</div>
|
||||
<div class="card-body">
|
||||
<div id="trace" class="spark"></div>
|
||||
<div id="traceLoading" class="loading"><i class="fa fa-spinner fa-pulse"></i><span>正在加载...请稍等</span></div>
|
||||
<div id="traceChart" style="height: 178px">
|
||||
</div>
|
||||
<div id="traceChart" style="height: 178px"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
|
@ -107,9 +93,7 @@
|
|||
</div>
|
||||
<div class="card-body">
|
||||
<div id="login" class="spark"></div>
|
||||
<div id="loginLoading" class="loading"><i class="fa fa-spinner fa-pulse"></i><span>正在加载...请稍等</span></div>
|
||||
<div id="loginChart" style="height: 178px">
|
||||
</div>
|
||||
<div id="loginChart" style="height: 178px"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
|
@ -118,8 +102,6 @@
|
|||
</div>
|
||||
<div class="card-body">
|
||||
<div id="log" class="spark"></div>
|
||||
<div id="logLoading" class="loading"><i class="fa fa-spinner fa-pulse"></i><span>正在加载...请稍等</span></div>
|
||||
<div id="logChart" style="height: 178px">
|
||||
</div>
|
||||
<div id="logChart" style="height: 178px"></div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,83 @@
|
|||
@model NavigatorBarModel
|
||||
@{
|
||||
ViewBag.Title = "字典表维护";
|
||||
Layout = "_Default";
|
||||
}
|
||||
@section javascript {
|
||||
<environment include="Development">
|
||||
<script src="~/lib/bootstrap-3-typeahead/bootstrap3-typeahead.js"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="~/lib/bootstrap-3-typeahead/bootstrap3-typeahead.min.js"></script>
|
||||
</environment>
|
||||
<script src="~/js/dicts.js" asp-append-version="true"></script>
|
||||
}
|
||||
@section query {
|
||||
<form class="form-inline">
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-6 col-md-auto">
|
||||
<label class="control-label" for="txt_dict_cate">字典标签</label>
|
||||
<input type="text" class="form-control" id="txt_dict_cate" data-provide="typeahead" />
|
||||
</div>
|
||||
<div class="form-group col-sm-6 col-md-auto">
|
||||
<label class="control-label" for="txt_dict_name">字典名称</label>
|
||||
<input type="text" class="form-control" id="txt_dict_name" />
|
||||
</div>
|
||||
<div class="form-group form-group-dropdown col-sm-6 col-md-auto">
|
||||
<label class="control-label" for="txt_dict_define">字典类别</label>
|
||||
<div class="dropdown">
|
||||
<button id="txt_dict_define" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown">全部</button>
|
||||
<div class="dropdown-menu">
|
||||
<a href="#" data-val="">全部</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a href="#" data-val="0">系统使用</a>
|
||||
<a href="#" data-val="1">自定义</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-6 col-md-auto flex-md-fill justify-content-md-end">
|
||||
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
@section body {
|
||||
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
|
||||
<span>演示系统禁止修改系统使用字典配置项</span>
|
||||
</div>
|
||||
}
|
||||
@section modal {
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myModalLabel">字典编辑窗口</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-inline">
|
||||
<div class="row">
|
||||
<input type="hidden" id="dictID" />
|
||||
<div class="form-group col-12">
|
||||
<label class="control-label" for="dictCate">字典标签</label>
|
||||
<input type="text" class="form-control flex-sm-fill" id="dictCate" placeholder="不可为空,50字以内" maxlength="50" data-valid="true" />
|
||||
</div>
|
||||
<div class="form-group col-12">
|
||||
<label class="control-label" for="dictName">字典名称</label>
|
||||
<input type="text" class="form-control flex-sm-fill" id="dictName" placeholder="不可为空,50字以内" maxlength="50" data-valid="true" />
|
||||
</div>
|
||||
<div class="form-group col-12">
|
||||
<label class="control-label" for="dictCode">字典代码</label>
|
||||
<input type="text" class="form-control flex-sm-fill" id="dictCode" placeholder="不可为空,2000字以内" maxlength="2000" data-valid="true" />
|
||||
</div>
|
||||
<div class="form-group form-group-dropdown col-12">
|
||||
<label class="control-label" for="dictDefine">字典类型</label>
|
||||
<div class="dropdown">
|
||||
<button id="dictDefine" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown" data-default-val="1">全部</button>
|
||||
<div class="dropdown-menu">
|
||||
<a href="#" data-val="0">系统使用</a>
|
||||
<a href="#" data-val="1">自定义</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
@model NavigatorBarModel
|
||||
@{
|
||||
ViewBag.Title = "程序异常";
|
||||
}
|
||||
@section css {
|
||||
<environment include="Development">
|
||||
<link href="~/lib/bootstrap-table/bootstrap-table.css" rel="stylesheet" />
|
||||
<link href="~/lib/datetimepicker/css/bootstrap-datetimepicker.css" rel="stylesheet" />
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<link href="~/lib/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" />
|
||||
<link href="~/lib/datetimepicker/css/bootstrap-datetimepicker.min.css" rel="stylesheet" />
|
||||
</environment>
|
||||
<link href="~/css/fa.css" rel="stylesheet" asp-append-version="true" />
|
||||
}
|
||||
@section javascript {
|
||||
<environment include="Development">
|
||||
<script src="~/lib/bootstrap-table/bootstrap-table.js"></script>
|
||||
<script src="~/lib/bootstrap-table/extensions/export/bootstrap-table-export.js"></script>
|
||||
<script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script>
|
||||
<script src="~/lib/tablexport/tableExport.js"></script>
|
||||
<script src="~/lib/datetimepicker/js/bootstrap-datetimepicker.js"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="~/lib/bootstrap-table/bootstrap-table.min.js"></script>
|
||||
<script src="~/lib/bootstrap-table/extensions/export/bootstrap-table-export.min.js"></script>
|
||||
<script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.min.js"></script>
|
||||
<script src="~/lib/tablexport/tableExport.min.js"></script>
|
||||
<script src="~/lib/datetimepicker/js/bootstrap-datetimepicker.min.js"></script>
|
||||
</environment>
|
||||
<script src="~/lib/datetimepicker/js/locales/bootstrap-datetimepicker.zh-CN.js"></script>
|
||||
<script src="~/js/exceptions.js" asp-append-version="true"></script>
|
||||
}
|
||||
<div class="card">
|
||||
<div class="card-header">查询条件</div>
|
||||
<div class="card-body">
|
||||
<form class="form-inline">
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-auto">
|
||||
<label class="control-label" for="txt_operate_start">起始时间</label>
|
||||
<div class="input-group date">
|
||||
<input id="txt_operate_start" class="form-control" size="16" type="text" value="" readonly>
|
||||
<div class="input-group-append input-group-addon">
|
||||
<div class="input-group-text"><span class="fa fa-times"></span></div>
|
||||
</div>
|
||||
<div class="input-group-append input-group-addon">
|
||||
<div class="input-group-text"><span class="fa fa-calendar"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-auto">
|
||||
<label class="control-label" for="txt_operate_end">终止时间</label>
|
||||
<div class="input-group date">
|
||||
<input id="txt_operate_end" class="form-control" size="16" type="text" value="" readonly>
|
||||
<div class="input-group-append input-group-addon">
|
||||
<div class="input-group-text"><span class="fa fa-times"></span></div>
|
||||
</div>
|
||||
<div class="input-group-append input-group-addon">
|
||||
<div class="input-group-text"><span class="fa fa-calendar"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-auto flex-sm-fill justify-content-sm-end">
|
||||
<label class="sr-only"></label>
|
||||
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="toolbar" class="d-none">
|
||||
<div class="toolbar btn-group">
|
||||
<button id="btn_view" type="button" class="btn btn-danger" asp-auth="log">
|
||||
<i class="fa fa-file-text-o" aria-hidden="true"></i><span>服务器日志</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="gear btn-group dropdown">
|
||||
<button class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" type="button"><i class="fa fa-gear"></i></button>
|
||||
<div class="dropdown-menu">
|
||||
<a id="tb_view" href="#" title="查看明细" asp-auth="log"><i class="fa fa-file-text-o"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
查询结果
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table></table>
|
||||
</div>
|
||||
</div>
|
||||
@section modal {
|
||||
<div class="modal fade" id="dialogNew" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div id="errorList" class="modal-dialog modal-dialog-centered modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myModalLabel">程序异常日志窗口</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-inline" id="dataForm" name="dataForm"><div class="form-row"></div></form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fa fa-times"></i>
|
||||
<span>关闭</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="errorDetail" class="modal-content icon-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myDetailModalLabel">程序异常日志窗口</h5>
|
||||
<button type="button" class="close" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="iconview">
|
||||
<i id="fa-top" class="fa-target"></i>
|
||||
<div class="affix">
|
||||
<div><a href="#fa-top" class="fa fa-arrow-circle-up"></a></div>
|
||||
<div><a href="#fa-bottom" class="fa fa-arrow-circle-down"></a></div>
|
||||
</div>
|
||||
<div id="dataFormDetail" class="ex-content"><div class="text-center"><i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i></div></div>
|
||||
<i id="fa-bottom" class="fa-target"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary">
|
||||
<i class="fa fa-times"></i>
|
||||
<span>关闭</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
|
@ -9,13 +9,16 @@
|
|||
@section query {
|
||||
<form class="form-inline">
|
||||
<div class="row">
|
||||
<div class="form-group col-12">
|
||||
<div class="form-group col-sm-5 col-md-auto">
|
||||
<label class="control-label" for="txt_search_name">部门名称</label>
|
||||
<input type="text" class="form-control" id="txt_search_name" data-default-val="" />
|
||||
<input type="text" class="form-control" id="txt_search_name" />
|
||||
</div>
|
||||
<div class="form-group col-12">
|
||||
<div class="form-group col-sm-5 col-md-auto">
|
||||
<label class="control-label" for="txt_group_desc">部门描述</label>
|
||||
<input type="text" class="form-control" id="txt_group_desc" data-default-val="" />
|
||||
<input type="text" class="form-control" id="txt_group_desc" />
|
||||
</div>
|
||||
<div class="form-group col-sm-2 col-md-auto flex-md-fill justify-content-md-end">
|
||||
<button type="button" id="btn_query" class="btn btn-primary btn-fill align-self-sm-end align-self-md-auto"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -44,23 +47,16 @@
|
|||
<label class="control-label" for="groupName">部门名称</label>
|
||||
<input type="text" class="form-control" id="groupName" placeholder="不可为空,50字以内" maxlength="50" data-valid="true" />
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="control-label" for="groupCode">部门编码</label>
|
||||
<input type="text" class="form-control" id="groupCode" placeholder="不可为空,50字以内" maxlength="50" data-valid="true" />
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<input type="hidden" id="groupID" />
|
||||
<label class="control-label" for="groupDesc">部门描述</label>
|
||||
<input type="text" class="form-control" id="groupDesc" placeholder="描述信息(可为空),500字以内" maxlength="500" />
|
||||
<input type="text" class="form-control" id="groupDesc" placeholder="描述信息(可为空),50字以内" maxlength="50" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
@section cardbody {
|
||||
<div class="alert alert-info" role="alert" asp-condition="@Model.IsDemo">
|
||||
<span>部门与组织结构中的带有层次关系的部门不同,用于资源权限的分配与管理 <a href="https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/%E6%95%B0%E6%8D%AE%E6%9D%83%E9%99%90?sort_id=1680495" target="_blank">参考文档</a></span>
|
||||
</div>
|
||||
}
|
||||
@await Html.PartialAsync("RoleConfig")
|
||||
@await Html.PartialAsync("UserConfig")
|
||||
@section customModal {
|
||||
@await Html.PartialAsync("RoleConfig")
|
||||
@await Html.PartialAsync("UserConfig")
|
||||
}
|
|
@ -12,10 +12,6 @@
|
|||
color: #fff;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.main-content .main-header {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
}
|
||||
@section javascript {
|
|
@ -31,10 +31,10 @@
|
|||
<div class="card-body">
|
||||
<form class="form-inline">
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-6 col-lg-auto">
|
||||
<div class="form-group col-sm-auto">
|
||||
<label class="control-label" for="txt_operate_start">起始时间</label>
|
||||
<div class="input-group date">
|
||||
<input id="txt_operate_start" class="form-control" size="16" type="text" value="@DateTime.Today.ToString("yyyy-MM-dd")" readonly>
|
||||
<input id="txt_operate_start" class="form-control" size="16" type="text" value="" readonly>
|
||||
<div class="input-group-append input-group-addon">
|
||||
<div class="input-group-text"><span class="fa fa-times"></span></div>
|
||||
</div>
|
||||
|
@ -43,7 +43,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-6 col-lg-auto">
|
||||
<div class="form-group col-sm-auto">
|
||||
<label class="control-label" for="txt_operate_end">终止时间</label>
|
||||
<div class="input-group date">
|
||||
<input id="txt_operate_end" class="form-control" size="16" type="text" value="" readonly>
|
||||
|
@ -55,11 +55,11 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-6 col-lg-auto">
|
||||
<div class="form-group col-sm-auto">
|
||||
<label class="control-label" for="txt_ip">请求IP</label>
|
||||
<input type="text" class="form-control" id="txt_ip" />
|
||||
</div>
|
||||
<div class="form-group col-sm-6 col-lg-auto flex-sm-fill justify-content-sm-end align-self-sm-end">
|
||||
<div class="form-group col-sm-auto flex-md-fill justify-content-md-end">
|
||||
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
|
||||
</div>
|
||||
</div>
|
|
@ -35,10 +35,10 @@
|
|||
<div class="card-body">
|
||||
<form class="form-inline">
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-6 col-lg-auto">
|
||||
<div class="form-group col-sm-auto">
|
||||
<label class="control-label" for="txt_operate_start">起始时间</label>
|
||||
<div class="input-group date">
|
||||
<input id="txt_operate_start" class="form-control" size="16" type="text" value="@DateTime.Today.ToString("yyyy-MM-dd")" readonly>
|
||||
<input id="txt_operate_start" class="form-control" size="16" type="text" value="" readonly>
|
||||
<div class="input-group-append input-group-addon">
|
||||
<div class="input-group-text"><span class="fa fa-times"></span></div>
|
||||
</div>
|
||||
|
@ -47,7 +47,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-6 col-lg-auto">
|
||||
<div class="form-group col-sm-auto">
|
||||
<label class="control-label" for="txt_operate_end">终止时间</label>
|
||||
<div class="input-group date">
|
||||
<input id="txt_operate_end" class="form-control" size="16" type="text" value="" readonly>
|
||||
|
@ -59,11 +59,11 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-6 col-lg-auto">
|
||||
<div class="form-group col-sm-auto">
|
||||
<label class="control-label" for="txt_operate_type">操作类型</label>
|
||||
<input type="text" class="form-control" id="txt_operate_type" />
|
||||
</div>
|
||||
<div class="form-group col-sm-6 col-lg-auto flex-sm-fill justify-content-sm-end align-self-sm-end">
|
||||
<div class="form-group col-sm-auto flex-sm-fill justify-content-sm-end">
|
||||
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -78,28 +78,30 @@
|
|||
<table></table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="dialogRequestData" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myModalLabel">请求数据明细窗口</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-inline">
|
||||
<div class="form-row">
|
||||
<div class="form-group col-12">
|
||||
<pre id="requestData"></pre>
|
||||
@section modal {
|
||||
<div class="modal fade" id="dialogRequestData" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myModalLabel">请求数据明细窗口</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-inline">
|
||||
<div class="form-row">
|
||||
<div class="form-group col-12">
|
||||
<pre id="requestData"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fa fa-times"></i>
|
||||
<span>关闭</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fa fa-times"></i>
|
||||
<span>关闭</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
|
@ -11,7 +11,6 @@
|
|||
<link href="~/lib/nestable2/jquery.nestable.min.css" rel="stylesheet" />
|
||||
</environment>
|
||||
<link href="~/lib/treegrid/css/jquery.treegrid.css" rel="stylesheet" />
|
||||
<link href="~/lib/longbow-select/longbow-select.css" rel="stylesheet" />
|
||||
<link href="~/css/fa.css" rel="stylesheet" asp-append-version="true" />
|
||||
}
|
||||
@section javascript {
|
||||
|
@ -27,49 +26,58 @@
|
|||
<script src="~/lib/treegrid/js/jquery.treegrid.min.js"></script>
|
||||
<script src="~/lib/bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.min.js"></script>
|
||||
</environment>
|
||||
<script src="~/lib/longbow-select/longbow-select.js"></script>
|
||||
<script src="~/js/menus.js" asp-append-version="true"></script>
|
||||
}
|
||||
@section query {
|
||||
<form class="form-inline">
|
||||
<div class="row">
|
||||
<div class="form-group col-12">
|
||||
<div class="form-group col-sm-6 col-lg-auto">
|
||||
<label class="control-label" for="txt_menus_name">菜单名称</label>
|
||||
<input type="text" class="form-control" id="txt_menus_name" data-default-val="" />
|
||||
<input type="text" class="form-control" id="txt_menus_name" />
|
||||
</div>
|
||||
<div class="form-group col-12">
|
||||
<div class="form-group col-sm-6 col-lg-auto">
|
||||
<label class="control-label" for="txt_parent_menus_name">父级菜单</label>
|
||||
<input type="text" class="form-control" id="txt_parent_menus_name" data-default-val="" />
|
||||
<input type="text" class="form-control" id="txt_parent_menus_name" />
|
||||
</div>
|
||||
<div class="form-group col-12">
|
||||
<div class="form-group form-group-dropdown col-sm-6 col-lg-auto">
|
||||
<label class="control-label" for="sel_menus_category">菜单类别</label>
|
||||
<input class="form-control" data-toggle="lgbSelect" data-default-val="" />
|
||||
<select data-toggle="lgbSelect" class="d-none" id="sel_menus_category">
|
||||
<option value="">全部</option>
|
||||
<option value="0">系统菜单</option>
|
||||
<option value="1">外部菜单</option>
|
||||
</select>
|
||||
<div class="dropdown">
|
||||
<button id="sel_menus_category" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown">全部</button>
|
||||
<div class="dropdown-menu">
|
||||
<a href="#" data-val="">全部</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a href="#" data-val="0">系统菜单</a>
|
||||
<a href="#" data-val="1">外部菜单</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-12">
|
||||
<div class="form-group form-group-dropdown col-sm-6 col-lg-auto">
|
||||
<label class="control-label" for="sel_menus_res">菜单类型</label>
|
||||
<input class="form-control" data-toggle="lgbSelect" data-default-val="" />
|
||||
<select data-toggle="lgbSelect" class="d-none" id="sel_menus_res">
|
||||
<option value="">全部</option>
|
||||
<option value="0">菜单</option>
|
||||
<option value="1">资源</option>
|
||||
<option value="2">按钮</option>
|
||||
</select>
|
||||
<div class="dropdown">
|
||||
<button id="sel_menus_res" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown">全部</button>
|
||||
<div class="dropdown-menu">
|
||||
<a href="#" data-val="">全部</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a href="#" data-val="0">菜单</a>
|
||||
<a href="#" data-val="1">资源</a>
|
||||
<a href="#" data-val="2">按钮</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-12">
|
||||
<div class="form-group form-group-dropdown col-sm-6 col-lg-auto">
|
||||
<label class="control-label" for="sel_app">所属应用</label>
|
||||
<input class="form-control" data-toggle="lgbSelect" data-default-val="" />
|
||||
<select data-toggle="lgbSelect" class="d-none" id="sel_app">
|
||||
<option value="">全部</option>
|
||||
@foreach (var kv in Model.Applications)
|
||||
{
|
||||
<option value="@kv.Key">@kv.Value</option>
|
||||
}
|
||||
</select>
|
||||
<div class="dropdown">
|
||||
<button id="sel_app" class="btn btn-info dropdown-select dropdown-toggle" data-toggle="dropdown" data-default-val="0">未设置</button>
|
||||
<div class="dropdown-menu">
|
||||
@foreach (var kv in Model.Applications)
|
||||
{
|
||||
<a href="#" data-val="@kv.Key">@kv.Value</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-lg-auto flex-lg-fill justify-content-lg-end">
|
||||
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -82,7 +90,7 @@
|
|||
@section gear {
|
||||
<a id="tb_assignRole" href="#" title="分配角色" asp-auth="assignRole"><i class="fa fa-sitemap"></i></a>
|
||||
}
|
||||
@section cardbody {
|
||||
@section body {
|
||||
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
|
||||
<span>演示系统禁止修改系统菜单,可修改外部菜单</span>
|
||||
</div>
|
||||
|
@ -100,7 +108,7 @@
|
|||
<div class="form-group col-sm-6">
|
||||
<input type="hidden" id="menuID" />
|
||||
<label class="control-label" for="name">菜单名称</label>
|
||||
<div class="input-group flex-sm-fill">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="name" name="name" placeholder="不可为空,50字以内" maxlength="50" data-valid="true" />
|
||||
<div class="input-group-append">
|
||||
<button data-method="clear" class="btn" type="button"><i class="fa fa-remove"></i></button>
|
||||
|
@ -109,9 +117,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<input type="hidden" class="form-control" id="parentId" data-default-val="0" />
|
||||
<input type="text" class="form-control d-none" id="parentId" data-default-val="0" />
|
||||
<label class="control-label" for="parentName">父级菜单</label>
|
||||
<div class="input-group flex-sm-fill">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" readonly id="parentName" name="parentName" placeholder="请选择...(可为空),50字以内" maxlength="50" />
|
||||
<div class="input-group-append">
|
||||
<button data-method="clear" class="btn" type="button"><i class="fa fa-remove"></i></button>
|
||||
|
@ -121,7 +129,7 @@
|
|||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="control-label" for="order">菜单序号</label>
|
||||
<div class="input-group flex-sm-fill">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control digits" id="order" name="order" data-default-val="10" placeholder="默认为10" maxlength="8" data-valid="true" />
|
||||
<div class="input-group-append">
|
||||
<button data-method="clear" class="btn" type="button"><i class="fa fa-remove"></i></button>
|
||||
|
@ -131,7 +139,7 @@
|
|||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="control-label" for="icon">菜单图标</label>
|
||||
<div class="input-group flex-sm-fill">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" readonly id="icon" data-default-val="fa fa-fa" placeholder="请选择...(可为空),50字以内" maxlength="50" />
|
||||
<div class="input-group-append">
|
||||
<button data-method="clear" class="btn" type="button"><i class="fa fa-remove"></i></button>
|
||||
|
@ -143,62 +151,76 @@
|
|||
<label class="control-label" for="url">路径</label>
|
||||
<input type="text" class="form-control flex-sm-fill" id="url" placeholder="不可为空,4000字以内" maxlength="4000" data-valid="true" />
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="control-label" for="isRes">菜单类型</label>
|
||||
<select data-toggle="lgbSelect" class="d-none menuChild" data-default-val="0" id="isRes" data-valid="true">
|
||||
<option value="0">菜单</option>
|
||||
<option value="1">资源</option>
|
||||
<option value="2">按钮</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="control-label" for="target">目标</label>
|
||||
<select data-toggle="lgbSelect" class="d-none" data-default-val="_self" id="target">
|
||||
<option value="_self">本窗口</option>
|
||||
<option value="_blank">新窗口</option>
|
||||
<option value="_parent">父级窗口</option>
|
||||
<option value="_top">顶级窗口</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="control-label" for="app">所属应用</label>
|
||||
<select data-toggle="lgbSelect" class="d-none" data-default-val="@BootstrapAppContext.AppId" id="app">
|
||||
@foreach (var kv in Model.Applications)
|
||||
{
|
||||
<option value="@kv.Key">@kv.Value</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<div class="form-group form-group-dropdown col-sm-6">
|
||||
<label class="control-label" for="category">菜单类别</label>
|
||||
<select data-toggle="lgbSelect" class="d-none" disabled data-default-val="1" id="category">
|
||||
<option value="0">系统菜单</option>
|
||||
<option value="1">外部菜单</option>
|
||||
</select>
|
||||
<div class="dropup">
|
||||
<button id="category" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown" data-default-val="1">外部菜单</button>
|
||||
<div class="dropdown-menu">
|
||||
<a href="#" data-val="0">系统菜单</a>
|
||||
<a href="#" data-val="1">外部菜单</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-group-dropdown col-sm-6">
|
||||
<label class="control-label" for="target">目标</label>
|
||||
<div class="dropup">
|
||||
<button id="target" class="btn btn-info dropdown-select dropdown-toggle" data-toggle="dropdown" data-default-val="_self">本窗口</button>
|
||||
<div class="dropdown-menu">
|
||||
<a href="#" data-val="_self">本窗口</a>
|
||||
<a href="#" data-val="_blank">新窗口</a>
|
||||
<a href="#" data-val="_parent">父级窗口</a>
|
||||
<a href="#" data-val="_top">顶级窗口</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-group-dropdown col-sm-6">
|
||||
<label class="control-label" for="isRes">菜单类型</label>
|
||||
<div class="dropup">
|
||||
<button id="isRes" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown" data-default-val="0">菜单</button>
|
||||
<div class="dropdown-menu">
|
||||
<a href="#" data-val="0">菜单</a>
|
||||
<a href="#" data-val="1">资源</a>
|
||||
<a href="#" data-val="2">按钮</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-group-dropdown col-sm-6">
|
||||
<label class="control-label" for="app">所属应用</label>
|
||||
<div class="dropup">
|
||||
<button id="app" class="btn btn-info dropdown-select dropdown-toggle" data-toggle="dropdown" data-default-val="0">未设置</button>
|
||||
<div class="dropdown-menu">
|
||||
@foreach (var kv in Model.Applications)
|
||||
{
|
||||
<a href="#" data-val="@kv.Key">@kv.Value</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
<div id="dialogIcon" class="modal-content icon-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myIconModalLabel">请选择图标</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
@section customModal {
|
||||
@await Html.PartialAsync("RoleConfig")
|
||||
<div id="dialogIcon" class="modal-content icon-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myIconModalLabel">请选择图标</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="loadIconView"><i class="fa fa-spinner fa-pulse"></i><span>正在加载图标...请稍等</span></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<span>被选择的图标</span><i class="fa fa-fa" id="pickIcon"></i>
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fa fa-times"></i>
|
||||
<span>关闭</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" id="btnSubmitIcon">
|
||||
<i class="fa fa-save"></i>
|
||||
<span>确定</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="loadIconView"><i class="fa fa-spinner fa-pulse"></i><span>正在加载图标...请稍等</span></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<span>被选择的图标</span><i class="fa fa-fa" id="pickIcon"></i>
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fa fa-times"></i>
|
||||
<span>关闭</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" id="btnSubmitIcon">
|
||||
<i class="fa fa-save"></i>
|
||||
<span>确定</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@await Html.PartialAsync("RoleConfig")
|
||||
@await Html.PartialAsync("NavigatorConfig")
|
||||
@await Html.PartialAsync("NavigatorConfig")
|
||||
}
|
|
@ -22,8 +22,8 @@
|
|||
<script src="~/js/noti.js" asp-append-version="true"></script>
|
||||
}
|
||||
<div class="card" asp-condition="@User.IsInRole("Administrators")">
|
||||
<div class="card-header">用户注册<span class="pull-right"><a id="refreshUsers" href="#" class="fa fa-refresh" title="点击刷新" data-toggle="tooltip" data-placement="left"></a></span></div>
|
||||
<div class="card-body">
|
||||
<div class="card-header">用户注册<span class="pull-right"><a id="refreshUsers" href="javascript:;" class="fa fa-refresh" title="点击刷新" data-toggle="tooltip" data-placement="left"></a></span></div>
|
||||
<div class="card-body" style="padding-top: 25px;">
|
||||
<table></table>
|
||||
</div>
|
||||
</div>
|
|
@ -23,7 +23,7 @@
|
|||
}
|
||||
<div class="card">
|
||||
<div class="card-header">在线用户<span class="pull-right"><a id="refreshUsers" href="javascript:;" class="fa fa-refresh" title="点击刷新" data-toggle="tooltip" data-placement="left"></a></span></div>
|
||||
<div class="card-body">
|
||||
<div class="card-body" style="padding-top: 25px;">
|
||||
<table></table>
|
||||
</div>
|
||||
</div>
|
|
@ -30,8 +30,7 @@
|
|||
<script src="~/lib/longbow/longbow.validate.js" asp-append-version="true"></script>
|
||||
<script src="~/js/profiles.js" asp-append-version="true"></script>
|
||||
}
|
||||
<input type="hidden" value="@Model.UserName" id="userName"/>
|
||||
<div class="card" asp-auth="saveDisplayName">
|
||||
<div class="card">
|
||||
<div class="card-header">基本资料</div>
|
||||
<div class="card-body" data-toggle="LgbValidate" data-valid-button="#btnSaveDisplayName">
|
||||
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
|
||||
|
@ -40,21 +39,21 @@
|
|||
<form class="form-inline">
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-6 col-md-auto">
|
||||
<label class="control-label" for="userName1">登录名称</label>
|
||||
<input type="text" class="form-control ignore" id="userName1" value="@Model.UserName" readonly />
|
||||
<label class="control-label" for="userName">登陆名称</label>
|
||||
<input type="text" class="form-control ignore" id="userName" name="userName" value="@Model.UserName" readonly />
|
||||
</div>
|
||||
<div class="form-group col-sm-6 col-md-auto">
|
||||
<label class="control-label" for="DisplayName">显示名称</label>
|
||||
<input type="text" class="form-control" id="displayName" value="@Model.DisplayName" placeholder="不可为空,20字以内" maxlength="20" data-valid="true" />
|
||||
<input type="text" class="form-control" id="displayName" name="displayName" value="@Model.DisplayName" placeholder="不可为空,20字以内" maxlength="20" data-valid="true" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="modal-footer" asp-condition="!@Model.IsDemo">
|
||||
<div class="modal-footer" asp-auth="saveDisplayName" asp-condition="!@Model.IsDemo">
|
||||
<button id="btnSaveDisplayName" data-method="user" class="btn btn-secondary" type="button"><i class="fa fa-save"></i><span>保存</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" asp-auth="savePassword" asp-condition="!@Model.External">
|
||||
<div class="card">
|
||||
<div class="card-header">修改密码</div>
|
||||
<div class="card-body" data-toggle="LgbValidate" data-valid-button="#btnSavePassword">
|
||||
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
|
||||
|
@ -78,17 +77,17 @@
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="modal-footer" asp-condition="!@Model.IsDemo">
|
||||
<div class="modal-footer" asp-auth="savePassword" asp-condition="!@Model.IsDemo">
|
||||
<button id="btnSavePassword" data-method="password" class="btn btn-secondary" type="button"><i class="fa fa-save"></i><span>保存</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" asp-auth="saveApp">
|
||||
<div class="card">
|
||||
<div class="card-header">默认应用</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<div class="btn-group" role="group">
|
||||
<button id="app" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown" value="@Model.AppId">@Model.AppName</button>
|
||||
<button id="app" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown" data-default-val="" value="@Model.AppCode">未设置</button>
|
||||
<div class="dropdown-menu">
|
||||
@foreach (var app in Model.Applications)
|
||||
{
|
||||
|
@ -97,12 +96,12 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="modal-footer" asp-auth="saveApp">
|
||||
<button id="btnSaveApp" data-method="app" class="btn btn-secondary" type="button"><i class="fa fa-save"></i><span>保存</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" asp-auth="saveTheme">
|
||||
<div class="card">
|
||||
<div class="card-header">网站样式</div>
|
||||
<div class="card-body">
|
||||
<div class="alert alert-info" role="alert">
|
||||
|
@ -120,15 +119,15 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="modal-footer" asp-auth="saveTheme">
|
||||
<button id="btnSaveCss" data-method="profileCss" class="btn btn-secondary" type="button"><i class="fa fa-save"></i><span>保存</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" asp-auth="saveIcon">
|
||||
<div class="card">
|
||||
<div class="card-header">修改头像</div>
|
||||
<div class="card-body">
|
||||
<form enctype="multipart/form-data">
|
||||
<form enctype="multipart/form-data" asp-auth="saveIcon">
|
||||
<div class="form-group">
|
||||
<input id="fileIcon" type="file" data-init="@Model.Size" data-file="@Model.FileName">
|
||||
</div>
|
|
@ -24,13 +24,16 @@
|
|||
@section query {
|
||||
<form class="form-inline">
|
||||
<div class="row">
|
||||
<div class="form-group col-12">
|
||||
<div class="form-group col-sm-5 col-md-auto">
|
||||
<label class="control-label" for="txt_search_name">角色名称</label>
|
||||
<input type="text" class="form-control" id="txt_search_name" data-default-val="" />
|
||||
<input type="text" class="form-control" id="txt_search_name" />
|
||||
</div>
|
||||
<div class="form-group col-12">
|
||||
<div class="form-group col-sm-5 col-md-auto">
|
||||
<label class="control-label" for="txt_role_desc">角色描述</label>
|
||||
<input type="text" class="form-control" id="txt_role_desc" data-default-val="" />
|
||||
<input type="text" class="form-control" id="txt_role_desc" />
|
||||
</div>
|
||||
<div class="form-group col-sm-2 col-md-auto flex-md-fill justify-content-md-end">
|
||||
<button type="button" id="btn_query" class="btn btn-primary btn-fill align-self-sm-end align-self-md-auto"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -55,7 +58,7 @@
|
|||
<a id="tb_assignMenu" href="#" title="分配菜单" asp-auth="assignMenu"><i class="fa fa-dashboard"></i></a>
|
||||
<a id="tb_assignApp" href="#" title="分配应用" asp-auth="assignApp"><i class="fa fa-cubes"></i></a>
|
||||
}
|
||||
@section cardbody {
|
||||
@section body {
|
||||
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
|
||||
<span>演示系统禁止修改内置角色(Administrators、Default)</span>
|
||||
</div>
|
||||
|
@ -75,13 +78,15 @@
|
|||
<div class="form-group col-sm-6">
|
||||
<input type="hidden" id="roleID" />
|
||||
<label class="control-label" for="roleDesc">角色描述</label>
|
||||
<input type="text" class="form-control" id="roleDesc" placeholder="描述信息(可为空),500字以内" maxlength="500" />
|
||||
<input type="text" class="form-control" id="roleDesc" placeholder="描述信息(可为空),50字以内" maxlength="50" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
@await Html.PartialAsync("UserConfig")
|
||||
@await Html.PartialAsync("GroupConfig")
|
||||
@await Html.PartialAsync("NavigatorConfig")
|
||||
@await Html.PartialAsync("AppConfig")
|
||||
@section customModal{
|
||||
@await Html.PartialAsync("UserConfig")
|
||||
@await Html.PartialAsync("GroupConfig")
|
||||
@await Html.PartialAsync("NavigatorConfig")
|
||||
@await Html.PartialAsync("AppConfig")
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
@model ThemeModel
|
||||
@{
|
||||
ViewBag.Title = "网站设置";
|
||||
}
|
||||
@section javascript {
|
||||
<environment include="Development">
|
||||
<script src="~/lib/validate/jquery.validate.js"></script>
|
||||
<script src="~/lib/validate/localization/messages_zh.js"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="~/lib/validate/jquery.validate.min.js"></script>
|
||||
<script src="~/lib/validate/localization/messages_zh.min.js"></script>
|
||||
</environment>
|
||||
<script src="~/lib/longbow/longbow.dataentity.js"></script>
|
||||
<script src="~/lib/longbow/longbow.validate.js"></script>
|
||||
<script src="~/js/settings.js" asp-append-version="true"></script>
|
||||
}
|
||||
<div class="card">
|
||||
<div class="card-header">系统名称设置</div>
|
||||
<div class="card-body" data-toggle="LgbValidate" data-valid-button="#sysSave">
|
||||
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
|
||||
<span>演示系统禁止更改系统名称</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="sysName" placeholder="请输入网站标题,50字以内" value="@Model.Title" maxlength="50" data-valid="true" />
|
||||
<div class="input-group-append" asp-condition="!@Model.IsDemo">
|
||||
<button class="btn btn-secondary" type="button" data-method="title" asp-auth="saveTitle">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">页脚设置</div>
|
||||
<div class="card-body" data-toggle="LgbValidate" data-valid-button="#footSave">
|
||||
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
|
||||
<span>演示系统禁止更改页脚</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="sysFoot" placeholder="请输入网站页脚,50字以内" value="@Model.Footer" maxlength="50" data-valid="true" />
|
||||
<div class="input-group-append" asp-condition="!@Model.IsDemo">
|
||||
<button class="btn btn-secondary" type="button" data-method="footer" asp-auth="saveFooter">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">网站样式</div>
|
||||
<div class="card-body">
|
||||
<div class="alert alert-info" role="alert">
|
||||
<span>注意:<b><a class="badge-pill" href="./Profiles">个人中心</a></b>中设置的网站样式覆盖本设置</span>
|
||||
</div>
|
||||
<div class="form-group text-right">
|
||||
<div class="btn-group" role="group">
|
||||
<div class="btn-group" role="group">
|
||||
<button id="dictCssDefine" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown" data-default-val="" value="@Model.Theme">默认样式</button>
|
||||
<div class="dropdown-menu">
|
||||
<a href="#" data-val="">默认样式</a>
|
||||
@foreach (var css in Model.Themes)
|
||||
{
|
||||
<a href="#" data-val="@css.Code">@css.Name</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-secondary" type="button" data-method="css" asp-auth="saveTheme">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="flex-fill">网站缓存</span>
|
||||
<a data-method="clear" href="#" class="fa fa-times-circle-o" title="全部清除" data-toggle="tooltip" data-placement="left" asp-auth="clearAllCache"></a>
|
||||
<a data-method="refresh" href="#" class="fa fa-refresh ml-3" title="点击刷新" data-toggle="tooltip"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body" id="sortable">
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,18 @@
|
|||
@model NavigatorBarModel
|
||||
@{
|
||||
ViewBag.Title = "任务管理";
|
||||
}
|
||||
@section css {
|
||||
<link href="~/css/tasks.css" rel="stylesheet" asp-append-version="true" />
|
||||
}
|
||||
@section javascript {
|
||||
<script src="~/js/tasks.js" asp-append-version="true"></script>
|
||||
}
|
||||
<div class="card">
|
||||
<div class="card-header">任务消息<span class="pull-right"><a id="refreshTask" href="javascript:;" class="fa fa-refresh"></a></span></div>
|
||||
<div class="card-body">
|
||||
<div class="tasks-widget">
|
||||
<ul id="list-task" class="task-list ui-sortable"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -35,10 +35,10 @@
|
|||
<div class="card-body">
|
||||
<form class="form-inline">
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-6 col-lg-auto">
|
||||
<div class="form-group col-sm-auto">
|
||||
<label class="control-label" for="txt_operate_start">起始时间</label>
|
||||
<div class="input-group date">
|
||||
<input id="txt_operate_start" class="form-control" size="16" type="text" value="@DateTime.Today.ToString("yyyy-MM-dd")" readonly>
|
||||
<input id="txt_operate_start" class="form-control" size="16" type="text" value="" readonly>
|
||||
<div class="input-group-append input-group-addon">
|
||||
<div class="input-group-text"><span class="fa fa-times"></span></div>
|
||||
</div>
|
||||
|
@ -47,7 +47,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-6 col-lg-auto">
|
||||
<div class="form-group col-sm-auto">
|
||||
<label class="control-label" for="txt_operate_end">终止时间</label>
|
||||
<div class="input-group date">
|
||||
<input id="txt_operate_end" class="form-control" size="16" type="text" value="" readonly>
|
||||
|
@ -59,11 +59,11 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-6 col-lg-auto">
|
||||
<div class="form-group col-sm-auto">
|
||||
<label class="control-label" for="txt_ip">请求IP</label>
|
||||
<input type="text" class="form-control" id="txt_ip" />
|
||||
</div>
|
||||
<div class="form-group col-sm-6 col-lg-auto flex-sm-fill justify-content-sm-end align-self-sm-end">
|
||||
<div class="form-group col-sm-auto flex-sm-fill justify-content-sm-end">
|
||||
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -78,28 +78,30 @@
|
|||
<table></table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="dialogRequestData" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myModalLabel">请求数据明细窗口</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-inline">
|
||||
<div class="form-row">
|
||||
<div class="form-group col-12">
|
||||
<pre id="requestData"></pre>
|
||||
@section modal {
|
||||
<div class="modal fade" id="dialogRequestData" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myModalLabel">请求数据明细窗口</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-inline">
|
||||
<div class="form-row">
|
||||
<div class="form-group col-12">
|
||||
<pre id="requestData"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fa fa-times"></i>
|
||||
<span>关闭</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fa fa-times"></i>
|
||||
<span>关闭</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
@model NavigatorBarModel
|
||||
@{
|
||||
ViewBag.Title = "用户管理";
|
||||
Layout = "_Default";
|
||||
}
|
||||
@section javascript {
|
||||
<script src="~/js/users.js" asp-append-version="true"></script>
|
||||
}
|
||||
@section query {
|
||||
<form class="form-inline">
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-5 col-md-auto">
|
||||
<label class="control-label" for="txt_search_name">登陆名称</label>
|
||||
<input type="text" class="form-control" id="txt_search_name" maxlength="16" />
|
||||
</div>
|
||||
<div class="form-group col-sm-5 col-md-auto">
|
||||
<label class="control-label" for="txt_display_name">显示名称</label>
|
||||
<input type="text" class="form-control" id="txt_display_name" maxlength="20" />
|
||||
</div>
|
||||
<div class="form-group col-sm-2 col-md-auto flex-md-fill justify-content-md-end">
|
||||
<button type="button" id="btn_query" class="btn btn-primary btn-fill align-self-sm-end align-self-md-auto"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
@section toolbar {
|
||||
<button id="btn_assignGroup" type="button" class="btn btn-info" asp-auth="assignGroup">
|
||||
<i class="fa fa-bank" aria-hidden="true"></i><span>分配部门</span>
|
||||
</button>
|
||||
<button id="btn_assignRole" type="button" class="btn btn-warning" asp-auth="assignRole">
|
||||
<i class="fa fa-sitemap" aria-hidden="true"></i><span>分配角色</span>
|
||||
</button>
|
||||
}
|
||||
@section gear {
|
||||
<a id="tb_assignRole" href="#" title="分配角色"><i class="fa fa-sitemap" asp-auth="assignGroup"></i></a>
|
||||
<a id="tb_assignGroup" href="#" title="分配部门"><i class="fa fa-bank" asp-auth="assignRole"></i></a>
|
||||
}
|
||||
@section tableButtons {
|
||||
<button class="reset btn btn-warning" asp-auth="resetPassword"><i class="fa fa-remove"></i><span>重置</span></button>
|
||||
}
|
||||
@section body {
|
||||
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
|
||||
<span>演示系统禁止修改Admin账户</span>
|
||||
</div>
|
||||
}
|
||||
@section modal {
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myModalLabel">用户编辑窗口</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-inline">
|
||||
<input type="hidden" id="userID" />
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="control-label" for="userName">登陆名称</label>
|
||||
<input type="text" class="form-control" id="userName" placeholder="不可为空,16字以内" minlength="4" maxlength="16" userName="true" remote="api/Register" data-remote-msg="此用户已存在" data-valid="true" />
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="control-label" for="displayName">显示名称</label>
|
||||
<input type="text" class="form-control" id="displayName" placeholder="不可为空,20字以内" maxlength="20" data-valid="true" />
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="control-label" for="password">登录密码</label>
|
||||
<input type="password" class="form-control" id="password" placeholder="不可为空,16字以内" maxlength="16" data-valid="true" />
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="control-label" for="confirm">确认密码</label>
|
||||
<input type="password" class="form-control" id="confirm" placeholder="与登陆密码一致" maxlength="16" equalTo="#password" data-valid="true" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
@section customModal {
|
||||
@await Html.PartialAsync("RoleConfig")
|
||||
@await Html.PartialAsync("GroupConfig")
|
||||
<div class="modal fade" id="dialogReset" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myResetModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
|
||||
<div class="modal-content" data-toggle="LgbValidate" data-valid-button="#btnReset" data-valid-modal="#dialogReset">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myResetModalLabel">重置密码窗口</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-inline">
|
||||
<div class="form-row" id="resetForm">
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="control-label" for="password">登录密码</label>
|
||||
<input type="password" class="form-control" id="resetPassword" placeholder="不可为空,16字以内" maxlength="16" data-valid="true" />
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="control-label" for="confirm">确认密码</label>
|
||||
<input type="password" class="form-control" id="resetConfirm" placeholder="与登陆密码一致" maxlength="16" equalTo="#resetPassword" data-valid="true" />
|
||||
</div>
|
||||
<div class="form-group col-sm-12">
|
||||
<label class="control-label" for="resetReason">重置原因</label>
|
||||
<textarea class="form-control flex-sm-fill" id="resetReason" rows="3" readonly="readonly" maxlength="200"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fa fa-times"></i>
|
||||
<span>关闭</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" id="btnReset">
|
||||
<i class="fa fa-save"></i>
|
||||
<span>保存</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
@inject IViewLocalizer Localizer
|
||||
@{
|
||||
ViewBag.Title = @Localizer["Home"];
|
||||
Layout = "_Bootstrap";
|
||||
}
|
||||
@section css {
|
||||
<style type="text/css">
|
||||
|
||||
.content-body {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 40px;
|
||||
right: 0;
|
||||
top: 96px;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
}
|
||||
<div class="content-body welcome-bg">
|
||||
</div>
|
|
@ -13,7 +13,7 @@
|
|||
<img src="@Url.Content(Model.Image)" />
|
||||
<h1>@Model.Content</h1>
|
||||
<h3>@Model.Detail</h3>
|
||||
<p><a href="~/Account/Logout">登录</a> <span>或者</span> <a href="@Url.Content(Model.ReturnUrl)">返回首页</a> <span>或者</span> <a href="~/healths-ui">系统自检</a></p>
|
||||
<p><a href="~/Account/Logout">登录</a> <span>或者</span> <a href="@Url.Content(Model.ReturnUrl)">返回首页</a></p>
|
||||
@if (Model.Id == 403)
|
||||
{
|
||||
<div>
|
|
@ -84,17 +84,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<!-- db dropdown end -->
|
||||
<div class="dropdown">
|
||||
<a class="shadow-success" href="~/Account/Lock" data-toggle="tooltip" title="系统锁屏">
|
||||
<i class="fa fa-tv"></i>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
<div class="@(Model.EnableBlazor ? "dropdown" : "dropdown d-none")">
|
||||
<a class="shadow-success dropdown-blazor" data-method="blazor" href="#" data-toggle="tooltip" title="Blazor 多 Tabs 模式">
|
||||
<img src="~/images/blazor.svg" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown userinfo">
|
||||
<a data-toggle="dropdown" class="dropdown-toggle shadow-default" href="#">
|
||||
|
@ -102,15 +92,6 @@
|
|||
<span id="userDisplayName" data-userName="@Model.UserName" class="username text-truncate d-inline-block">@Model.DisplayName</span>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
<div class="dropdown-item">
|
||||
<div class="d-flex flex-fill align-items-center">
|
||||
<img src="@Url.Content(Model.Icon)">
|
||||
<div class="flex-fill">
|
||||
<div class="username text-truncate">@Model.DisplayName</div>
|
||||
<div>登录名:@Model.UserName</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-item">
|
||||
<a href="~/Admin/Profiles"><i class=" fa fa-suitcase"></i>个人中心</a>
|
||||
<a href="~/Admin/Index"><i class="fa fa-cog"></i>设置</a>
|
||||
|
@ -124,7 +105,7 @@
|
|||
</div>
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="~/Admin/Index"><i class="fa fa-home"></i>首页</a></li>
|
||||
<li class="breadcrumb-item"><a href="@Url.Content("~/Admin/Index")"><i class="fa fa-home"></i>首页</a></li>
|
||||
<li class="breadcrumb-item d-none" id="breadNav"></li>
|
||||
</ol>
|
||||
</nav>
|
|
@ -0,0 +1,11 @@
|
|||
@model NavigatorBarModel
|
||||
<aside>
|
||||
<!-- sidebar menu start-->
|
||||
<ul class="sidebar nav nav-pills flex-column flex-nowrap">
|
||||
@foreach (var menu in Model.Navigations)
|
||||
{
|
||||
@await Html.PartialAsync("SubNavItem", menu)
|
||||
}
|
||||
</ul>
|
||||
<!-- sidebar menu end-->
|
||||
</aside>
|
|
@ -0,0 +1,25 @@
|
|||
<div class="modal fade" id="dialogMenu" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myMenuModalLabel" aria-hidden="true">
|
||||
<div id="dialogSubMenu" class="modal-dialog modal-dialog-centered modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myMenuModalLabel">请选择菜单</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="dd" id="nestable_menu">
|
||||
<ol class="dd-list"></ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fa fa-times"></i>
|
||||
<span>关闭</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" data-dismiss="modal" id="btnSubmitMenu">
|
||||
<i class="fa fa-save"></i>
|
||||
<span>确认</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,8 @@
|
|||
@model Bootstrap.Security.BootstrapMenu
|
||||
<li class="nav-item @Model.Active">
|
||||
<a href="@Url.Content(Model.Url)" class="nav-link @Model.Active" target="@Model.Target"><i class="@Model.Icon"></i>@Model.Name</a>
|
||||
@if (Model.Menus.Any())
|
||||
{
|
||||
@await Html.PartialAsync("SubNavigation", Model.Menus)
|
||||
}
|
||||
</li>
|
|
@ -1,5 +1,5 @@
|
|||
@model IEnumerable<Bootstrap.Security.BootstrapMenu>
|
||||
<ul class="sub nav flex-column">
|
||||
<ul class="sub nav nav-pills flex-column flex-nowrap" style="display: none;">
|
||||
@foreach (var menu in Model)
|
||||
{
|
||||
@await Html.PartialAsync("SubNavItem", menu)
|
|
@ -7,19 +7,6 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-inline">
|
||||
<div class="row" id="useFilter">
|
||||
<div class="form-group col-12">
|
||||
<div class="input-group flex-fill">
|
||||
<div class="input-group-prepend d-none d-sm-flex">
|
||||
<span class="input-group-text">过滤条件</span>
|
||||
</div>
|
||||
<input class="form-control" type="text" />
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-primary" type="button">查询</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="userForm"></div>
|
||||
</form>
|
||||
</div>
|
|
@ -1,4 +1,3 @@
|
|||
@model AdminModel
|
||||
@{
|
||||
Layout = "_Bootstrap";
|
||||
}
|
||||
|
@ -6,43 +5,44 @@
|
|||
<environment include="Development">
|
||||
<link href="~/lib/toastr.js/toastr.css" rel="stylesheet" />
|
||||
<link href="~/lib/nprogress/nprogress.css" rel="stylesheet" />
|
||||
<link href="~/lib/sweetalert/sweetalert2.css" rel="stylesheet" />
|
||||
<link href="~/lib/overlayscrollbars/OverlayScrollbars.css" rel="stylesheet" />
|
||||
<link href="~/lib/bootstrap-sweetalert/sweetalert.css" rel="stylesheet" />
|
||||
<link href="~/lib/scrollbar/jquery.mCustomScrollbar.css" rel="stylesheet" />
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<link href="~/lib/toastr.js/toastr.min.css" rel="stylesheet" />
|
||||
<link href="~/lib/nprogress/nprogress.min.css" rel="stylesheet" />
|
||||
<link href="~/lib/sweetalert/sweetalert2.min.css" rel="stylesheet" />
|
||||
<link href="~/lib/overlayscrollbars/OverlayScrollbars.min.css" rel="stylesheet" />
|
||||
<link href="~/lib/bootstrap-sweetalert/sweetalert.min.css" rel="stylesheet" />
|
||||
<link href="~/lib/scrollbar/jquery.mCustomScrollbar.min.css" rel="stylesheet" />
|
||||
</environment>
|
||||
@RenderSection("css", false)
|
||||
}
|
||||
@section javascript {
|
||||
<environment include="Development">
|
||||
<script src="~/lib/overlayscrollbars/jquery.overlayScrollbars.js"></script>
|
||||
<script src="~/lib/scrollbar/jquery.mousewheel.js"></script>
|
||||
<script src="~/lib/scrollbar/jquery.mCustomScrollbar.js"></script>
|
||||
<script src="~/lib/signalr/dist/browser/signalr.js"></script>
|
||||
<script src="~/lib/sweetalert/sweetalert2.js"></script>
|
||||
<script src="~/lib/dcjqaccordion/js/jquery.dcjqaccordion.2.7.js"></script>
|
||||
<script src="~/lib/bootstrap-sweetalert/sweetalert.js"></script>
|
||||
<script src="~/lib/nprogress/nprogress.js"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="~/lib/overlayscrollbars/jquery.overlayScrollbars.min.js"></script>
|
||||
<script src="~/lib/scrollbar/jquery.mousewheel.min.js"></script>
|
||||
<script src="~/lib/scrollbar/jquery.mCustomScrollbar.concat.min.js"></script>
|
||||
<script src="~/lib/signalr/dist/browser/signalr.min.js"></script>
|
||||
<script src="~/lib/sweetalert/sweetalert2.min.js"></script>
|
||||
<script src="~/lib/dcjqaccordion/js/jquery.dcjqaccordion.2.7.min.js"></script>
|
||||
<script src="~/lib/bootstrap-sweetalert/sweetalert.min.js"></script>
|
||||
<script src="~/lib/nprogress/nprogress.min.js"></script>
|
||||
</environment>
|
||||
<script src="~/lib/toastr.js/toastr.min.js"></script>
|
||||
<script src="~/lib/dcjqaccordion/js/jquery.cookie.js"></script>
|
||||
<script src="~/js/common-scripts.js" asp-append-version="true"></script>
|
||||
@RenderSection("javascript", false)
|
||||
<script src="~/js/log.js" asp-append-version="true"></script>
|
||||
}
|
||||
@await Html.PartialAsync("Navigator")
|
||||
<section id="main-content" class="main-content @(Model.ShowCardTitle ? "" : "no-card-header")">
|
||||
<input id="lockScreenPeriod" type="hidden" asp-condition="@Model.EnableAutoLockScreen" value="@Model.LockScreenPeriod" />
|
||||
<div class="main-header">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="~/Admin/Index"><i class="fa fa-home"></i>首页</a></li>
|
||||
<li class="breadcrumb-item d-none"></li>
|
||||
</ol>
|
||||
</div>
|
||||
<section id="main-content" class="main-content">
|
||||
@RenderBody()
|
||||
</section>
|
||||
@section modal {
|
||||
@RenderSection("modal", false)
|
||||
}
|
|
@ -34,3 +34,4 @@
|
|||
@await Html.PartialAsync("Header")
|
||||
@RenderBody()
|
||||
@await Html.PartialAsync("Footer")
|
||||
@RenderSection("modal", false)
|
|
@ -9,7 +9,6 @@
|
|||
<environment exclude="Development">
|
||||
<link href="~/lib/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" />
|
||||
</environment>
|
||||
<link href="~/lib/longbow-checkbox/longbow-checkbox.css" rel="stylesheet" />
|
||||
@RenderSection("css", false)
|
||||
}
|
||||
@section javascript {
|
||||
|
@ -29,11 +28,36 @@
|
|||
<script src="~/lib/validate/jquery.validate.min.js"></script>
|
||||
<script src="~/lib/validate/localization/messages_zh.min.js"></script>
|
||||
</environment>
|
||||
<script src="~/lib/longbow-checkbox/longbow-checkbox.js"></script>
|
||||
<script src="~/lib/longbow/longbow.dataentity.js" asp-append-version="true"></script>
|
||||
<script src="~/lib/longbow/longbow.validate.js" asp-append-version="true"></script>
|
||||
@RenderSection("javascript", false)
|
||||
}
|
||||
@section modal {
|
||||
<div class="modal fade" id="dialogNew" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
|
||||
<div class="modal-content" data-toggle="LgbValidate" data-valid-button="#btnSubmit" data-valid-modal="#dialogNew">
|
||||
@RenderSection("modal", false)
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fa fa-times"></i>
|
||||
<span>关闭</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" id="btnSubmit">
|
||||
<i class="fa fa-save"></i>
|
||||
<span>保存</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@RenderSection("customModal", false)
|
||||
}
|
||||
<div class="card">
|
||||
<div class="card-header">查询条件</div>
|
||||
<div class="card-body">
|
||||
@RenderSection("query", false)
|
||||
</div>
|
||||
</div>
|
||||
<div id="toolbar" class="d-none">
|
||||
<div class="gear btn-group">
|
||||
<button class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" type="button"><i class="fa fa-gear"></i></button>
|
||||
|
@ -56,8 +80,8 @@
|
|||
查询结果
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@await RenderSectionAsync("cardbody", false)
|
||||
<table data-Header="@(Model.FixedTableHeader ? "fixed" : "scroll")"></table>
|
||||
@await RenderSectionAsync("body", false)
|
||||
<table></table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tableButtons" class="d-none">
|
||||
|
@ -66,39 +90,4 @@
|
|||
<button class='del btn btn-sm btn-danger' asp-auth="del"><i class='fa fa-remove'></i><span>删除</span></button>
|
||||
@RenderSection("tableButtons", false)
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="dialogNew" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
|
||||
<div class="modal-content" data-toggle="LgbValidate" data-valid-button="#btnSubmit" data-valid-modal="#dialogNew">
|
||||
@RenderSection("modal", false)
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fa fa-times"></i>
|
||||
<span>关闭</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" id="btnSubmit">
|
||||
<i class="fa fa-save"></i>
|
||||
<span>保存</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="dialogAdvancedSearch" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="mySearchModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="mySearchModalLabel">查询条件</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body modal-query">
|
||||
@RenderSection("query", false)
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" id="btn_reset" class="btn btn-info btn-fill"><i class="fa fa-trash-o" aria-hidden="true"></i><span>重置</span></button>
|
||||
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@RenderBody()
|
||||
</div>
|
|
@ -1,31 +1,19 @@
|
|||
@model ModelBase
|
||||
<!DOCTYPE html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<link rel="icon" href="@Url.Content(Model.WebSiteIcon)" type="image/x-icon" />
|
||||
<link rel="shortcut icon" href="@Url.Content(Model.WebSiteIcon)" type="image/x-icon" />
|
||||
<link rel="apple-touch-icon" href="~/favicon.png" />
|
||||
<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"/>
|
||||
<title>@ViewBag.Title</title>
|
||||
@RenderSection("css", false)
|
||||
<!--[if lt IE 10 ]>
|
||||
<link href="../css/IE8.css" rel="stylesheet" />
|
||||
<![endif]-->
|
||||
<environment include="Staging,Production">
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function () {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?ce3c9cfb729226f39dd330899489086d";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
</environment>
|
||||
</head>
|
||||
<body class="trans-mute">
|
||||
<body>
|
||||
<!--[if lt IE 10 ]>
|
||||
<div id="ieAlert" class="alert alert-danger alert-dismissible">
|
||||
<div>当前浏览器版本太低,不支持本系统,请升级到至少IE10 <a href="../browser/IE10.exe" target="_blank">本地下载</a> <a href="https://support.microsoft.com/zh-cn/help/17621/internet-explorer-downloads" target="_blank">微软下载</a>,或者使用Chrome浏览器 <a href="../browser/ChromeSetup.exe" target="_blank">本地下载</a></div>
|
|
@ -0,0 +1,5 @@
|
|||
@using Bootstrap.Admin.Models
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@addTagHelper *, Bootstrap.Security.Mvc
|
||||
@addTagHelper *, Longbow.Web
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue