style: 更改文件格式

This commit is contained in:
Argo-MacBookPro 2019-05-01 16:46:24 +08:00
parent 1a1f7e86d6
commit d3eb38d854
76 changed files with 5512 additions and 5512 deletions

View File

@ -1,137 +1,137 @@
using Bootstrap.Admin.Models; using Bootstrap.Admin.Models;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System; using System;
namespace Bootstrap.Admin.Controllers namespace Bootstrap.Admin.Controllers
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class AdminController : Controller public class AdminController : Controller
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Index() => View(new NavigatorBarModel(this)); public ActionResult Index() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Users() => View(new NavigatorBarModel(this)); public ActionResult Users() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Groups() => View(new NavigatorBarModel(this)); public ActionResult Groups() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Dicts() => View(new NavigatorBarModel(this)); public ActionResult Dicts() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Roles() => View(new NavigatorBarModel(this)); public ActionResult Roles() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Menus() => View(new NavigatorBarModel(this)); public ActionResult Menus() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Logs() => View(new NavigatorBarModel(this)); public ActionResult Logs() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Traces() => View(new NavigatorBarModel(this)); public ActionResult Traces() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Logins() => View(new NavigatorBarModel(this)); public ActionResult Logins() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult FAIcon() => View(new NavigatorBarModel(this)); public ActionResult FAIcon() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[AllowAnonymous] [AllowAnonymous]
[ResponseCache(Duration = 600)] [ResponseCache(Duration = 600)]
public PartialViewResult IconView() => PartialView("IconView"); public PartialViewResult IconView() => PartialView("IconView");
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Settings() => View(new ThemeModel(this)); public ActionResult Settings() => View(new ThemeModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Notifications() => View(new NavigatorBarModel(this)); public ActionResult Notifications() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="host"></param> /// <param name="host"></param>
/// <returns></returns> /// <returns></returns>
public ActionResult Profiles([FromServices]IHostingEnvironment host) => View(new ProfilesModel(this, host)); public ActionResult Profiles([FromServices]IHostingEnvironment host) => View(new ProfilesModel(this, host));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Exceptions() => View(new NavigatorBarModel(this)); public ActionResult Exceptions() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Messages() => View(new NavigatorBarModel(this)); public ActionResult Messages() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Tasks() => View(new NavigatorBarModel(this)); public ActionResult Tasks() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Mobile() => View(new NavigatorBarModel(this)); public ActionResult Mobile() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// 在线用户 /// 在线用户
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Online() => View(new NavigatorBarModel(this)); public ActionResult Online() => View(new NavigatorBarModel(this));
/// <summary> /// <summary>
/// 用于测试ExceptionFilter /// 用于测试ExceptionFilter
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ActionResult Error() => throw new Exception("Customer Excetion UnitTest"); public ActionResult Error() => throw new Exception("Customer Excetion UnitTest");
} }
} }

View File

@ -1,69 +1,69 @@
using Bootstrap.DataAccess; using Bootstrap.DataAccess;
using Bootstrap.Security; using Bootstrap.Security;
using Longbow.Web; using Longbow.Web;
using Longbow.Web.Mvc; using Longbow.Web.Mvc;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace Bootstrap.Admin.Controllers.Api namespace Bootstrap.Admin.Controllers.Api
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
[Route("api/[controller]")] [Route("api/[controller]")]
[ApiController] [ApiController]
public class LoginController : ControllerBase public class LoginController : ControllerBase
{ {
/// <summary> /// <summary>
/// 获得登录历史记录 /// 获得登录历史记录
/// </summary> /// </summary>
/// <param name="po"></param> /// <param name="po"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
public QueryData<LoginUser> Get([FromQuery]PaginationOption po) public QueryData<LoginUser> Get([FromQuery]PaginationOption po)
{ {
var data = LoginHelper.Retrieves(po); var data = LoginHelper.Retrieves(po);
var ret = new QueryData<LoginUser>(); var ret = new QueryData<LoginUser>();
ret.total = data.TotalItems; ret.total = data.TotalItems;
ret.rows = data.Items; ret.rows = data.Items;
return ret; return ret;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="onlineUserSvr"></param> /// <param name="onlineUserSvr"></param>
/// <param name="ipLocator"></param> /// <param name="ipLocator"></param>
/// <param name="value"></param> /// <param name="value"></param>
/// <returns></returns> /// <returns></returns>
[AllowAnonymous] [AllowAnonymous]
[HttpPost] [HttpPost]
public string Post([FromServices]IOnlineUsers onlineUserSvr, [FromServices]IIPLocatorProvider ipLocator, [FromBody]JObject value) public string Post([FromServices]IOnlineUsers onlineUserSvr, [FromServices]IIPLocatorProvider ipLocator, [FromBody]JObject value)
{ {
string token = null; string token = null;
dynamic user = value; dynamic user = value;
string userName = user.userName; string userName = user.userName;
string password = user.password; string password = user.password;
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password) && UserHelper.Authenticate(userName, password, loginUser => AccountController.CreateLoginUser(onlineUserSvr, ipLocator, HttpContext, loginUser))) if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password) && UserHelper.Authenticate(userName, password, loginUser => AccountController.CreateLoginUser(onlineUserSvr, ipLocator, HttpContext, loginUser)))
{ {
token = BootstrapAdminJwtTokenHandler.CreateToken(userName); token = BootstrapAdminJwtTokenHandler.CreateToken(userName);
} }
return token; return token;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[AllowAnonymous] [AllowAnonymous]
[HttpOptions] [HttpOptions]
public string Options() public string Options()
{ {
return null; return null;
} }
} }
} }

View File

@ -1,6 +1,6 @@
using Bootstrap.Admin.Query; using Bootstrap.Admin.Query;
using Bootstrap.DataAccess; using Bootstrap.DataAccess;
using Longbow.Web.Mvc; using Longbow.Web.Mvc;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace Bootstrap.Admin.Controllers.Api namespace Bootstrap.Admin.Controllers.Api

View File

@ -1,42 +1,42 @@
using Bootstrap.Admin.Models; using Bootstrap.Admin.Models;
using Bootstrap.DataAccess; using Bootstrap.DataAccess;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace Bootstrap.Admin.Controllers namespace Bootstrap.Admin.Controllers
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class HomeController : Controller public class HomeController : Controller
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public IActionResult Index() public IActionResult Index()
{ {
var model = new HeaderBarModel(User.Identity); var model = new HeaderBarModel(User.Identity);
var url = DictHelper.RetrieveHomeUrl(model.AppCode); var url = DictHelper.RetrieveHomeUrl(model.AppCode);
return url.Equals("~/Home/Index", System.StringComparison.OrdinalIgnoreCase) ? (IActionResult)View(model) : Redirect(url); return url.Equals("~/Home/Index", System.StringComparison.OrdinalIgnoreCase) ? (IActionResult)View(model) : Redirect(url);
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
/// <returns></returns> /// <returns></returns>
[AllowAnonymous] [AllowAnonymous]
public IActionResult Error(int id) public IActionResult Error(int id)
{ {
var model = ErrorModel.CreateById(id); var model = ErrorModel.CreateById(id);
if (id != 403) if (id != 403)
{ {
var returnUrl = Request.Query[CookieAuthenticationDefaults.ReturnUrlParameter].ToString(); var returnUrl = Request.Query[CookieAuthenticationDefaults.ReturnUrlParameter].ToString();
if (!string.IsNullOrEmpty(returnUrl)) model.ReturnUrl = returnUrl; if (!string.IsNullOrEmpty(returnUrl)) model.ReturnUrl = returnUrl;
} }
return View(model); return View(model);
} }
} }
} }

View File

@ -69,7 +69,7 @@
model.Detail = "服务器拒绝处理您的请求!您可能没有访问此操作的权限"; model.Detail = "服务器拒绝处理您的请求!您可能没有访问此操作的权限";
break; break;
} }
return model; return model;
} }
} }
} }

View File

@ -1,56 +1,56 @@
using Bootstrap.DataAccess; using Bootstrap.DataAccess;
using System.Security.Principal; using System.Security.Principal;
namespace Bootstrap.Admin.Models namespace Bootstrap.Admin.Models
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class HeaderBarModel : ModelBase public class HeaderBarModel : ModelBase
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="identity"></param> /// <param name="identity"></param>
public HeaderBarModel(IIdentity identity) public HeaderBarModel(IIdentity identity)
{ {
var user = UserHelper.RetrieveUserByUserName(identity.Name); var user = UserHelper.RetrieveUserByUserName(identity.Name);
Icon = string.Format("{0}{1}", DictHelper.RetrieveIconFolderPath(), user.Icon); Icon = string.Format("{0}{1}", DictHelper.RetrieveIconFolderPath(), user.Icon);
DisplayName = user.DisplayName; DisplayName = user.DisplayName;
UserName = user.UserName; UserName = user.UserName;
AppCode = user.App; AppCode = user.App;
Css = user.Css; Css = user.Css;
ActiveCss = string.IsNullOrEmpty(Css) ? Theme : Css; ActiveCss = string.IsNullOrEmpty(Css) ? Theme : Css;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string UserName { get; } public string UserName { get; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string DisplayName { get; } public string DisplayName { get; }
/// <summary> /// <summary>
/// 获得/设置 用户头像地址 /// 获得/设置 用户头像地址
/// </summary> /// </summary>
public string Icon { get; } public string Icon { get; }
/// <summary> /// <summary>
/// 获取/设置 个人网站样式 /// 获取/设置 个人网站样式
/// </summary> /// </summary>
public string Css { get; } public string Css { get; }
/// <summary> /// <summary>
/// 获得 当前设置的默认应用 /// 获得 当前设置的默认应用
/// </summary> /// </summary>
public string AppCode { get; } public string AppCode { get; }
/// <summary> /// <summary>
/// 获得 当前样式 /// 获得 当前样式
/// </summary> /// </summary>
public string ActiveCss { get; } public string ActiveCss { get; }
} }
} }

View File

@ -1,28 +1,28 @@
using Bootstrap.DataAccess; using Bootstrap.DataAccess;
namespace Bootstrap.Admin.Models namespace Bootstrap.Admin.Models
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class LoginModel : ModelBase public class LoginModel : ModelBase
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public LoginModel() public LoginModel()
{ {
ImageLibUrl = DictHelper.RetrieveImagesLibUrl(); ImageLibUrl = DictHelper.RetrieveImagesLibUrl();
} }
/// <summary> /// <summary>
/// 验证码图床地址 /// 验证码图床地址
/// </summary> /// </summary>
public string ImageLibUrl { get; protected set; } public string ImageLibUrl { get; protected set; }
/// <summary> /// <summary>
/// 是否登录认证失败 /// 是否登录认证失败
/// </summary> /// </summary>
public bool AuthFailed { get; set; } public bool AuthFailed { get; set; }
} }
} }

View File

@ -1,24 +1,24 @@
namespace Bootstrap.Admin.Models namespace Bootstrap.Admin.Models
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class MessageCountModel public class MessageCountModel
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public int InboxCount { get; set; } public int InboxCount { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public int SendmailCount { get; set; } public int SendmailCount { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public int MarkCount { get; set; } public int MarkCount { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public int TrashCount { get; set; } public int TrashCount { get; set; }
} }

View File

@ -1,41 +1,41 @@
using Bootstrap.DataAccess; using Bootstrap.DataAccess;
namespace Bootstrap.Admin.Models namespace Bootstrap.Admin.Models
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class ModelBase public class ModelBase
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public ModelBase() public ModelBase()
{ {
Title = DictHelper.RetrieveWebTitle(); Title = DictHelper.RetrieveWebTitle();
Footer = DictHelper.RetrieveWebFooter(); Footer = DictHelper.RetrieveWebFooter();
Theme = DictHelper.RetrieveActiveTheme(); Theme = DictHelper.RetrieveActiveTheme();
IsDemo = DictHelper.RetrieveSystemModel(); IsDemo = DictHelper.RetrieveSystemModel();
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string Title { get; private set; } public string Title { get; private set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string Footer { get; private set; } public string Footer { get; private set; }
/// <summary> /// <summary>
/// 网站样式全局设置 /// 网站样式全局设置
/// </summary> /// </summary>
public string Theme { get; protected set; } public string Theme { get; protected set; }
/// <summary> /// <summary>
/// 是否为演示系统 /// 是否为演示系统
/// </summary> /// </summary>
public bool IsDemo { get; protected set; } public bool IsDemo { get; protected set; }
} }
} }

View File

@ -1,44 +1,44 @@
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
namespace Bootstrap.Admin.Models namespace Bootstrap.Admin.Models
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class ProfilesModel : ThemeModel public class ProfilesModel : ThemeModel
{ {
/// <summary> /// <summary>
/// 获得 头像文件大小 /// 获得 头像文件大小
/// </summary> /// </summary>
public long Size { get; } public long Size { get; }
/// <summary> /// <summary>
/// 获得 头像文件名称 /// 获得 头像文件名称
/// </summary> /// </summary>
public string FileName { get; } public string FileName { get; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="host"></param> /// <param name="host"></param>
/// <param name="controller"></param> /// <param name="controller"></param>
public ProfilesModel(ControllerBase controller, IHostingEnvironment host) : base(controller) public ProfilesModel(ControllerBase controller, IHostingEnvironment host) : base(controller)
{ {
if (host != null) if (host != null)
{ {
var fileName = Path.Combine(host.WebRootPath, Icon.TrimStart('~', '/').Replace('/', Path.DirectorySeparatorChar)); var fileName = Path.Combine(host.WebRootPath, Icon.TrimStart('~', '/').Replace('/', Path.DirectorySeparatorChar));
// 数据库存储的个人图片有后缀 default.jpg?v=1234567 // 数据库存储的个人图片有后缀 default.jpg?v=1234567
fileName = fileName.Split('?').FirstOrDefault(); fileName = fileName.Split('?').FirstOrDefault();
if (File.Exists(fileName)) if (File.Exists(fileName))
{ {
Size = new FileInfo(fileName).Length; Size = new FileInfo(fileName).Length;
FileName = Path.GetFileName(fileName); FileName = Path.GetFileName(fileName);
} }
} }
} }
} }
} }

View File

@ -1,221 +1,221 @@
@model LoginModel @model LoginModel
@{ @{
ViewBag.Title = Model.Title; ViewBag.Title = Model.Title;
Layout = "_Layout"; Layout = "_Layout";
} }
@section css { @section css {
<environment include="Development"> <environment include="Development">
<link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" /> <link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
<link href="~/lib/font-awesome/css/font-awesome.css" rel="stylesheet" /> <link href="~/lib/font-awesome/css/font-awesome.css" rel="stylesheet" />
<link href="~/lib/bootstrap-sweetalert/sweetalert.css" rel="stylesheet" /> <link href="~/lib/bootstrap-sweetalert/sweetalert.css" rel="stylesheet" />
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<link href="~/lib/twitter-bootstrap/css/bootstrap.min.css" rel="stylesheet" /> <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/font-awesome/css/font-awesome.min.css" rel="stylesheet" />
<link href="~/lib/bootstrap-sweetalert/sweetalert.min.css" rel="stylesheet" /> <link href="~/lib/bootstrap-sweetalert/sweetalert.min.css" rel="stylesheet" />
</environment> </environment>
<link href="~/lib/captcha/slidercaptcha.css" rel="stylesheet" /> <link href="~/lib/captcha/slidercaptcha.css" rel="stylesheet" />
<link href="~/css/theme.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/theme.css" rel="stylesheet" asp-append-version="true" />
<link href="~/css/login.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" /> <link href="~/css/login-responsive.css" rel="stylesheet" asp-append-version="true" />
@if (!string.IsNullOrEmpty(Model.Theme)) @if (!string.IsNullOrEmpty(Model.Theme))
{ {
<link href="~/css/@Model.Theme" rel="stylesheet" asp-append-version="true" /> <link href="~/css/@Model.Theme" rel="stylesheet" asp-append-version="true" />
} }
} }
@section javascript { @section javascript {
<environment include="Development"> <environment include="Development">
<script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.js"></script> <script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.js"></script>
<script src="~/lib/validate/jquery.validate.js"></script> <script src="~/lib/validate/jquery.validate.js"></script>
<script src="~/lib/validate/localization/messages_zh.js"></script> <script src="~/lib/validate/localization/messages_zh.js"></script>
<script src="~/lib/bootstrap-sweetalert/sweetalert.js"></script> <script src="~/lib/bootstrap-sweetalert/sweetalert.js"></script>
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.min.js"></script> <script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="~/lib/validate/jquery.validate.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/validate/localization/messages_zh.min.js"></script>
<script src="~/lib/bootstrap-sweetalert/sweetalert.min.js"></script> <script src="~/lib/bootstrap-sweetalert/sweetalert.min.js"></script>
</environment> </environment>
<script src="~/lib/captcha/longbow.slidercaptcha.js"></script> <script src="~/lib/captcha/longbow.slidercaptcha.js"></script>
<script src="~/lib/longbow/longbow.common.js"></script> <script src="~/lib/longbow/longbow.common.js"></script>
<script src="~/lib/longbow/longbow.validate.js"></script> <script src="~/lib/longbow/longbow.validate.js"></script>
<script src="~/js/login.js" asp-append-version="true"></script> <script src="~/js/login.js" asp-append-version="true"></script>
} }
<div class="container"> <div class="container">
<input id="imgUrl" type="hidden" value="@Model.ImageLibUrl" /> <input id="imgUrl" type="hidden" value="@Model.ImageLibUrl" />
<form id="login" method="post" class="form-signin"> <form id="login" method="post" class="form-signin">
<h2 class="form-signin-heading">@Model.Title</h2> <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="login-wrap" data-auth="@Model.AuthFailed" data-toggle="LgbValidate" data-valid-button="button[type='submit']">
<div class="alert alert-danger" asp-condition="@Model.AuthFailed">用户名或密码错误!</div> <div class="alert alert-danger" asp-condition="@Model.AuthFailed">用户名或密码错误!</div>
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="input-group-text"> <div class="input-group-text">
<span class="fa fa-user"></span> <span class="fa fa-user"></span>
</div> </div>
</div> </div>
<input type="text" name="userName" class="form-control" placeholder="用户名" maxlength="16" data-required-msg="请输入用户名" value="@ViewBag.UserName" autofocus data-valid="true" /> <input type="text" name="userName" class="form-control" placeholder="用户名" maxlength="16" data-required-msg="请输入用户名" value="@ViewBag.UserName" autofocus data-valid="true" />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="input-group-text"> <div class="input-group-text">
<span class="fa fa-lock"></span> <span class="fa fa-lock"></span>
</div> </div>
</div> </div>
<input type="password" name="password" class="form-control" value="@ViewBag.Password" placeholder="密码" maxlength="16" data-required-msg="请输入密码" data-valid="true" /> <input type="password" name="password" class="form-control" value="@ViewBag.Password" placeholder="密码" maxlength="16" data-required-msg="请输入密码" data-valid="true" />
</div> </div>
</div> </div>
<div class="form-group rememberPwd" onselectstart="return false"> <div class="form-group rememberPwd" onselectstart="return false">
<i class="fa fa-square-o"></i> <i class="fa fa-square-o"></i>
<span>记住密码自动登录</span> <span>记住密码自动登录</span>
<input id="remember" name="remember" type="hidden" value="false" /> <input id="remember" name="remember" type="hidden" value="false" />
</div> </div>
<button class="btn btn-lg btn-login btn-block" type="submit">登 陆</button> <button class="btn btn-lg btn-login btn-block" type="submit">登 陆</button>
<div class="login-footer"> <div class="login-footer">
<a href="#" data-method="register">申请账号</a> <a href="#" data-method="register">申请账号</a>
<a href="#" data-method="forgot">忘记密码</a> <a href="#" data-method="forgot">忘记密码</a>
</div> </div>
<div class="slidercaptcha card"> <div class="slidercaptcha card">
<div class="card-header"> <div class="card-header">
<span>请完成安全验证</span> <span>请完成安全验证</span>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div> </div>
<div class="card-body"><div id="captcha"></div></div> <div class="card-body"><div id="captcha"></div></div>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
<div class="modal fade" id="dialogNew" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true"> <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-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content" data-toggle="LgbValidate" data-valid-button="#btnSubmit" data-valid-modal="#dialogNew"> <div class="modal-content" data-toggle="LgbValidate" data-valid-button="#btnSubmit" data-valid-modal="#dialogNew">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="myModalLabel">新用户注册</h5> <h5 class="modal-title" id="myModalLabel">新用户注册</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="form-group">
<label for="userName">登陆名称:</label> <label for="userName">登陆名称:</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="input-group-text"> <div class="input-group-text">
<span class="fa fa-user-plus"></span> <span class="fa fa-user-plus"></span>
</div> </div>
</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> </div>
<div class="form-group"> <div class="form-group">
<label for="displayName">显示名称:</label> <label for="displayName">显示名称:</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="input-group-text"> <div class="input-group-text">
<span class="fa fa-user-circle-o"></span> <span class="fa fa-user-circle-o"></span>
</div> </div>
</div> </div>
<input type="text" id="displayName" class="form-control" value="" placeholder="显示名称不可为空" maxlength="20" data-valid="true" /> <input type="text" id="displayName" class="form-control" value="" placeholder="显示名称不可为空" maxlength="20" data-valid="true" />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="password">密码:</label> <label for="password">密码:</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="input-group-text"> <div class="input-group-text">
<span class="fa fa-lock"></span> <span class="fa fa-lock"></span>
</div> </div>
</div> </div>
<input type="password" id="password" class="form-control" value="" placeholder="密码不可为空" maxlength="16" data-valid="true" /> <input type="password" id="password" class="form-control" value="" placeholder="密码不可为空" maxlength="16" data-valid="true" />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="assurePassword">确认密码:</label> <label for="assurePassword">确认密码:</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="input-group-text"> <div class="input-group-text">
<span class="fa fa-lock"></span> <span class="fa fa-lock"></span>
</div> </div>
</div> </div>
<input type="password" id="assurePassword" class="form-control" value="" placeholder="确认密码" maxlength="16" equalTo="#password" data-valid="true" /> <input type="password" id="assurePassword" class="form-control" value="" placeholder="确认密码" maxlength="16" equalTo="#password" data-valid="true" />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="description">申请理由:</label> <label for="description">申请理由:</label>
<textarea id="description" class="form-control" placeholder="申请理由500字以内" rows="3" maxlength="500" data-valid="true"></textarea> <textarea id="description" class="form-control" placeholder="申请理由500字以内" rows="3" maxlength="500" data-valid="true"></textarea>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"> <button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>
<span>关闭</span> <span>关闭</span>
</button> </button>
<button type="button" class="btn btn-primary" id="btnSubmit"> <button type="button" class="btn btn-primary" id="btnSubmit">
<i class="fa fa-save"></i> <i class="fa fa-save"></i>
<span>提交</span> <span>提交</span>
</button> </button>
<div class="slidercaptcha forgot reg card"> <div class="slidercaptcha forgot reg card">
<div class="card-header"> <div class="card-header">
<span>请完成安全验证</span> <span>请完成安全验证</span>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div> </div>
<div class="card-body"><div id="regcap"></div></div> <div class="card-body"><div id="regcap"></div></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="modal fade" id="dialogForgot" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal fade" id="dialogForgot" 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-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content" data-toggle="LgbValidate" data-valid-button="#btnForgot" data-valid-modal="#dialogForgot"> <div class="modal-content" data-toggle="LgbValidate" data-valid-button="#btnForgot" data-valid-modal="#dialogForgot">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="myModalLabelForgot">忘记密码</h5> <h5 class="modal-title" id="myModalLabelForgot">忘记密码</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="form-group">
<label for="f_userName">登陆账号:</label> <label for="f_userName">登陆账号:</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="input-group-text"> <div class="input-group-text">
<span class="fa fa-user-plus"></span> <span class="fa fa-user-plus"></span>
</div> </div>
</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> </div>
<div class="form-group"> <div class="form-group">
<label for="f_displayName">显示名称:</label> <label for="f_displayName">显示名称:</label>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="input-group-text"> <div class="input-group-text">
<span class="fa fa-user-circle-o"></span> <span class="fa fa-user-circle-o"></span>
</div> </div>
</div> </div>
<input type="text" id="f_displayName" class="form-control" value="" placeholder="显示名称不可为空" maxlength="20" data-valid="true" /> <input type="text" id="f_displayName" class="form-control" value="" placeholder="显示名称不可为空" maxlength="20" data-valid="true" />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="f_desc">申请理由:</label> <label for="f_desc">申请理由:</label>
<textarea id="f_desc" class="form-control" placeholder="申请理由500字以内" rows="3" maxlength="500" data-valid="true">我是用户XXX我的手机号是XXXXXX由于密码忘记请将密码重置为123登录后我自行更改谢谢管理员</textarea> <textarea id="f_desc" class="form-control" placeholder="申请理由500字以内" rows="3" maxlength="500" data-valid="true">我是用户XXX我的手机号是XXXXXX由于密码忘记请将密码重置为123登录后我自行更改谢谢管理员</textarea>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"> <button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>
<span>关闭</span> <span>关闭</span>
</button> </button>
<button type="button" class="btn btn-danger" id="btnForgot"> <button type="button" class="btn btn-danger" id="btnForgot">
<i class="fa fa-send-o"></i> <i class="fa fa-send-o"></i>
<span>提交</span> <span>提交</span>
</button> </button>
<div class="slidercaptcha forgot card"> <div class="slidercaptcha forgot card">
<div class="card-header"> <div class="card-header">
<span>请完成安全验证</span> <span>请完成安全验证</span>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div> </div>
<div class="card-body"><div id="forgotcap"></div></div> <div class="card-body"><div id="forgotcap"></div></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,11 +1,11 @@
@model NavigatorBarModel @model NavigatorBarModel
@{ @{
ViewBag.Title = "图标集"; ViewBag.Title = "图标集";
} }
@section css { @section css {
<link href="~/css/fa.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/fa.css" rel="stylesheet" asp-append-version="true" />
} }
@section javascript { @section javascript {
<script src="~/js/icon.js" asp-append-version="true"></script> <script src="~/js/icon.js" asp-append-version="true"></script>
} }
<div class="text-center"><i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i></div> <div class="text-center"><i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i></div>

View File

@ -1,24 +1,24 @@
@model ModelBase @model ModelBase
@{ @{
ViewBag.Title = "后台管理"; ViewBag.Title = "后台管理";
} }
@section css { @section css {
<style> <style>
.main-content { .main-content {
position: fixed; position: fixed;
} }
.main-content h4 { .main-content h4 {
color: #fff; color: #fff;
margin-top: 0; margin-top: 0;
} }
</style> </style>
} }
@section javascript { @section javascript {
<script> <script>
$(function () { $(function () {
$('#main-content').addClass('welcome-bg'); $('#main-content').addClass('welcome-bg');
}); });
</script> </script>
} }
<h4>欢迎使用后台管理</h4> <h4>欢迎使用后台管理</h4>

View File

@ -1,107 +1,107 @@
@model NavigatorBarModel @model NavigatorBarModel
@{ @{
ViewBag.Title = "操作日志"; ViewBag.Title = "操作日志";
} }
@section css { @section css {
<environment include="Development"> <environment include="Development">
<link href="~/lib/datetimepicker/css//bootstrap-datetimepicker.css" rel="stylesheet" /> <link href="~/lib/datetimepicker/css//bootstrap-datetimepicker.css" rel="stylesheet" />
<link href="~/lib/bootstrap-table/bootstrap-table.css" rel="stylesheet" /> <link href="~/lib/bootstrap-table/bootstrap-table.css" rel="stylesheet" />
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<link href="~/lib/datetimepicker/css//bootstrap-datetimepicker.min.css" rel="stylesheet" /> <link href="~/lib/datetimepicker/css//bootstrap-datetimepicker.min.css" rel="stylesheet" />
<link href="~/lib/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" /> <link href="~/lib/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" />
</environment> </environment>
} }
@section javascript { @section javascript {
<environment include="Development"> <environment include="Development">
<script src="~/lib/bootstrap-table/bootstrap-table.js"></script> <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/extensions/export/bootstrap-table-export.js"></script>
<script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script> <script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script>
<script src="~/lib/tablexport/tableExport.js"></script> <script src="~/lib/tablexport/tableExport.js"></script>
<script src="~/lib/datetimepicker/js/bootstrap-datetimepicker.js"></script> <script src="~/lib/datetimepicker/js/bootstrap-datetimepicker.js"></script>
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<script src="~/lib/bootstrap-table/bootstrap-table.min.js"></script> <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/extensions/export/bootstrap-table-export.min.js"></script>
<script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.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/tablexport/tableExport.min.js"></script>
<script src="~/lib/datetimepicker/js/bootstrap-datetimepicker.min.js"></script> <script src="~/lib/datetimepicker/js/bootstrap-datetimepicker.min.js"></script>
</environment> </environment>
<script src="~/lib/datetimepicker/js/locales/bootstrap-datetimepicker.zh-CN.js"></script> <script src="~/lib/datetimepicker/js/locales/bootstrap-datetimepicker.zh-CN.js"></script>
<script src="~/js/logs.js" asp-append-version="true"></script> <script src="~/js/logs.js" asp-append-version="true"></script>
} }
<div class="card"> <div class="card">
<div class="card-header">查询条件</div> <div class="card-header">查询条件</div>
<div class="card-body"> <div class="card-body">
<form class="form-inline"> <form class="form-inline">
<div class="row"> <div class="row">
<div class="form-group col-sm-auto"> <div class="form-group col-sm-auto">
<label class="control-label" for="txt_operate_start">起始时间</label> <label class="control-label" for="txt_operate_start">起始时间</label>
<div class="input-group date"> <div class="input-group date">
<input id="txt_operate_start" class="form-control" size="16" type="text" value="" 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-append input-group-addon">
<div class="input-group-text"><span class="fa fa-times"></span></div> <div class="input-group-text"><span class="fa fa-times"></span></div>
</div> </div>
<div class="input-group-append input-group-addon"> <div class="input-group-append input-group-addon">
<div class="input-group-text"><span class="fa fa-calendar"></span></div> <div class="input-group-text"><span class="fa fa-calendar"></span></div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group col-sm-auto"> <div class="form-group col-sm-auto">
<label class="control-label" for="txt_operate_end">终止时间</label> <label class="control-label" for="txt_operate_end">终止时间</label>
<div class="input-group date"> <div class="input-group date">
<input id="txt_operate_end" class="form-control" size="16" type="text" value="" readonly> <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-append input-group-addon">
<div class="input-group-text"><span class="fa fa-times"></span></div> <div class="input-group-text"><span class="fa fa-times"></span></div>
</div> </div>
<div class="input-group-append input-group-addon"> <div class="input-group-append input-group-addon">
<div class="input-group-text"><span class="fa fa-calendar"></span></div> <div class="input-group-text"><span class="fa fa-calendar"></span></div>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group col-sm-auto"> <div class="form-group col-sm-auto">
<label class="control-label" for="txt_operate_type">操作类型</label> <label class="control-label" for="txt_operate_type">操作类型</label>
<input type="text" class="form-control" id="txt_operate_type" /> <input type="text" class="form-control" id="txt_operate_type" />
</div> </div>
<div class="form-group col-sm-auto flex-sm-fill justify-content-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> <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>
</form> </form>
</div> </div>
</div> </div>
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
查询结果 查询结果
</div> </div>
<div class="card-body"> <div class="card-body">
<table></table> <table></table>
</div> </div>
</div> </div>
@section modal { @section modal {
<div class="modal fade" id="dialogRequestData" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true"> <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-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="myModalLabel">请求数据明细窗口</h5> <h5 class="modal-title" id="myModalLabel">请求数据明细窗口</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form class="form-inline"> <form class="form-inline">
<div class="form-row"> <div class="form-row">
<div class="form-group col-12"> <div class="form-group col-12">
<pre id="requestData"></pre> <pre id="requestData"></pre>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"> <button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>
<span>关闭</span> <span>关闭</span>
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
} }

View File

@ -1,46 +1,46 @@
@model NavigatorBarModel @model NavigatorBarModel
@{ @{
ViewBag.Title = "站内消息"; ViewBag.Title = "站内消息";
} }
@section javascript { @section javascript {
<script src="~/js/message.js" asp-append-version="true"></script> <script src="~/js/message.js" asp-append-version="true"></script>
} }
<div class="mail-box"> <div class="mail-box">
<div class="sm-side"> <div class="sm-side">
<div class="user-head"> <div class="user-head">
<a href="javascript:;" class="inbox-avatar"> <a href="javascript:;" class="inbox-avatar">
<img src="~/images/logo6.jpg" alt=""> <img src="~/images/logo6.jpg" alt="">
</a> </a>
<div class="user-name"><h5><a href="#">@Model.DisplayName</a></h5></div> <div class="user-name"><h5><a href="#">@Model.DisplayName</a></h5></div>
</div> </div>
<div class="inbox-body"> <div class="inbox-body">
<a class="btn btn-compose" data-toggle="modal" href="#myModal"> <a class="btn btn-compose" data-toggle="modal" href="#myModal">
写消息 写消息
</a> </a>
</div> </div>
<ul id="mailBox" class="inbox-nav inbox-divider"> <ul id="mailBox" class="inbox-nav inbox-divider">
<li class="active"> <li class="active">
<a href="#" data-id="inbox"><i class="fa fa-inbox"></i>收信箱<span class="label label-danger pull-right" id="s_inbox"></span></a> <a href="#" data-id="inbox"><i class="fa fa-inbox"></i>收信箱<span class="label label-danger pull-right" id="s_inbox"></span></a>
</li> </li>
<li> <li>
<a href="#" data-id="sendmail"><i class="fa fa-envelope-o"></i>发信箱<span class="label label-danger pull-right" id="s_sendmail"></span></a> <a href="#" data-id="sendmail"><i class="fa fa-envelope-o"></i>发信箱<span class="label label-danger pull-right" id="s_sendmail"></span></a>
</li> </li>
<li> <li>
<a href="#" data-id="mark"><i class="fa fa-bookmark-o"></i>标旗消息<span class="label label-danger pull-right" id="s_mark"></span></a> <a href="#" data-id="mark"><i class="fa fa-bookmark-o"></i>标旗消息<span class="label label-danger pull-right" id="s_mark"></span></a>
</li> </li>
<li> <li>
<a href="#" data-id="trash"><i class=" fa fa-trash-o"></i>垃圾箱<span class="label label-danger pull-right" id="s_trash"></span></a> <a href="#" data-id="trash"><i class=" fa fa-trash-o"></i>垃圾箱<span class="label label-danger pull-right" id="s_trash"></span></a>
</li> </li>
</ul> </ul>
</div> </div>
<div class="lg-side"> <div class="lg-side">
<div class="inbox-head"> <div class="inbox-head">
<h3>消息列表</h3> <h3>消息列表</h3>
</div> </div>
<div class="inbox-body"> <div class="inbox-body">
<table class="table table-inbox table-hover"> <table class="table table-inbox table-hover">
<tbody id="tbMsg"></tbody> <tbody id="tbMsg"></tbody>
</table> </table>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,73 +1,73 @@
@model ModelBase @model ModelBase
@{ @{
ViewBag.Title = "客户端测试"; ViewBag.Title = "客户端测试";
} }
@section javascript { @section javascript {
<script> <script>
window.onload = function () { window.onload = function () {
var browser = $.browser; var browser = $.browser;
$('#language').text(browser.language); $('#language').text(browser.language);
$('#mobile').text(browser.versions.mobile); $('#mobile').text(browser.versions.mobile);
$('#webapp').text(browser.versions.webApp); $('#webapp').text(browser.versions.webApp);
$('#webkit').text(browser.versions.webKit); $('#webkit').text(browser.versions.webKit);
$('#ios').text(browser.versions.ios); $('#ios').text(browser.versions.ios);
$('#android').text(browser.versions.android); $('#android').text(browser.versions.android);
$('#iphone').text(browser.versions.iPhone); $('#iphone').text(browser.versions.iPhone);
$('#ipad').text(browser.versions.iPad); $('#ipad').text(browser.versions.iPad);
$('#useragent').text(navigator.userAgent); $('#useragent').text(navigator.userAgent);
$('#versions').text(JSON.stringify(browser.versions)); $('#versions').text(JSON.stringify(browser.versions));
$.footer(); $.footer();
}; };
</script> </script>
} }
@section css { @section css {
<style type="text/css"> <style type="text/css">
label { label {
word-break: break-all; word-break: break-all;
} }
.control-label { .control-label {
width: 120px; width: 120px;
} }
</style> </style>
} }
<div class="form-group"> <div class="form-group">
<label class="control-label">语言版本:</label> <label class="control-label">语言版本:</label>
<label id="language" class="form-control-static"></label> <label id="language" class="form-control-static"></label>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label">是否为移动终端:</label> <label class="control-label">是否为移动终端:</label>
<label id="mobile" class="form-control-static"></label> <label id="mobile" class="form-control-static"></label>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label">webApp</label> <label class="control-label">webApp</label>
<label id="webapp" class="form-control-static"></label> <label id="webapp" class="form-control-static"></label>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label">webKit</label> <label class="control-label">webKit</label>
<label id="webkit" class="form-control-static"></label> <label id="webkit" class="form-control-static"></label>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label">ios终端</label> <label class="control-label">ios终端</label>
<label id="ios" class="form-control-static"></label> <label id="ios" class="form-control-static"></label>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label">android终端</label> <label class="control-label">android终端</label>
<label id="android" class="form-control-static"></label> <label id="android" class="form-control-static"></label>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label">是否为iPhone</label> <label class="control-label">是否为iPhone</label>
<label id="iphone" class="form-control-static"></label> <label id="iphone" class="form-control-static"></label>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label">是否iPad</label> <label class="control-label">是否iPad</label>
<label id="ipad" class="form-control-static"></label> <label id="ipad" class="form-control-static"></label>
</div><div class="form-group"> </div><div class="form-group">
<label class="control-label">userAgent</label> <label class="control-label">userAgent</label>
<label id="useragent" class="form-control-static"></label> <label id="useragent" class="form-control-static"></label>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label">versions</label> <label class="control-label">versions</label>
<label id="versions" class="form-control-static"></label> <label id="versions" class="form-control-static"></label>
</div> </div>

View File

@ -1,29 +1,29 @@
@model NavigatorBarModel @model NavigatorBarModel
@{ @{
ViewBag.Title = "通知管理"; ViewBag.Title = "通知管理";
} }
@section css { @section css {
<environment include="Development"> <environment include="Development">
<link href="~/lib/bootstrap-table/bootstrap-table.css" rel="stylesheet" /> <link href="~/lib/bootstrap-table/bootstrap-table.css" rel="stylesheet" />
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<link href="~/lib/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" /> <link href="~/lib/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" />
</environment> </environment>
} }
@section javascript { @section javascript {
<environment include="Development"> <environment include="Development">
<script src="~/lib/bootstrap-table/bootstrap-table.js"></script> <script src="~/lib/bootstrap-table/bootstrap-table.js"></script>
<script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script> <script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script>
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<script src="~/lib/bootstrap-table/bootstrap-table.min.js"></script> <script src="~/lib/bootstrap-table/bootstrap-table.min.js"></script>
<script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.min.js"></script> <script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.min.js"></script>
</environment> </environment>
<script src="~/js/noti.js" asp-append-version="true"></script> <script src="~/js/noti.js" asp-append-version="true"></script>
} }
<div class="card"> <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-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;"> <div class="card-body" style="padding-top: 25px;">
<table></table> <table></table>
</div> </div>
</div> </div>

View File

@ -1,137 +1,137 @@
@model ProfilesModel @model ProfilesModel
@{ @{
ViewBag.Title = "个人中心"; ViewBag.Title = "个人中心";
} }
@section css { @section css {
<environment include="Development"> <environment include="Development">
<link href="~/lib/bootstrap-fileinput/css/fileinput.css" rel="stylesheet" /> <link href="~/lib/bootstrap-fileinput/css/fileinput.css" rel="stylesheet" />
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<link href="~/lib/bootstrap-fileinput/css/fileinput.min.css" rel="stylesheet" /> <link href="~/lib/bootstrap-fileinput/css/fileinput.min.css" rel="stylesheet" />
</environment> </environment>
<link href="~/css/tasks.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/tasks.css" rel="stylesheet" asp-append-version="true" />
} }
@section javascript { @section javascript {
<environment include="Development"> <environment include="Development">
<script src="~/lib/bootstrap-fileinput/js/fileinput.js"></script> <script src="~/lib/bootstrap-fileinput/js/fileinput.js"></script>
<script src="~/lib/bootstrap-fileinput/js/locales/zh.js"></script> <script src="~/lib/bootstrap-fileinput/js/locales/zh.js"></script>
<script src="~/lib/bootstrap-fileinput/themes/fa/theme.js"></script> <script src="~/lib/bootstrap-fileinput/themes/fa/theme.js"></script>
<script src="~/lib/validate/jquery.validate.js"></script> <script src="~/lib/validate/jquery.validate.js"></script>
<script src="~/lib/validate/localization/messages_zh.js"></script> <script src="~/lib/validate/localization/messages_zh.js"></script>
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<script src="~/lib/bootstrap-fileinput/js/fileinput.min.js"></script> <script src="~/lib/bootstrap-fileinput/js/fileinput.min.js"></script>
<script src="~/lib/bootstrap-fileinput/js/locales/zh.min.js"></script> <script src="~/lib/bootstrap-fileinput/js/locales/zh.min.js"></script>
<script src="~/lib/bootstrap-fileinput/themes/fa/theme.min.js"></script> <script src="~/lib/bootstrap-fileinput/themes/fa/theme.min.js"></script>
<script src="~/lib/validate/jquery.validate.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/validate/localization/messages_zh.min.js"></script>
</environment> </environment>
<script src="~/lib/longbow/longbow.dataentity.js" asp-append-version="true"></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> <script src="~/lib/longbow/longbow.validate.js" asp-append-version="true"></script>
<script src="~/js/profiles.js" asp-append-version="true"></script> <script src="~/js/profiles.js" asp-append-version="true"></script>
} }
<div class="card"> <div class="card">
<div class="card-header">基本资料</div> <div class="card-header">基本资料</div>
<div class="card-body" data-toggle="LgbValidate" data-valid-button="#btnSaveDisplayName"> <div class="card-body" data-toggle="LgbValidate" data-valid-button="#btnSaveDisplayName">
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo"> <div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
<span>演示系统禁止更改管理员显示名称</span> <span>演示系统禁止更改管理员显示名称</span>
</div> </div>
<form class="form-inline"> <form class="form-inline">
<div class="row"> <div class="row">
<div class="form-group col-sm-6 col-md-auto"> <div class="form-group col-sm-6 col-md-auto">
<label class="control-label" for="userName">登陆名称</label> <label class="control-label" for="userName">登陆名称</label>
<input type="text" class="form-control ignore" id="userName" name="userName" value="@Model.UserName" readonly /> <input type="text" class="form-control ignore" id="userName" name="userName" value="@Model.UserName" readonly />
</div> </div>
<div class="form-group col-sm-6 col-md-auto"> <div class="form-group col-sm-6 col-md-auto">
<label class="control-label" for="DisplayName">显示名称</label> <label class="control-label" for="DisplayName">显示名称</label>
<input type="text" class="form-control" id="displayName" name="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>
</div> </div>
</form> </form>
<div class="modal-footer" asp-auth="saveDisplayName" 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> <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>
</div> </div>
<div class="card"> <div class="card">
<div class="card-header">修改密码</div> <div class="card-header">修改密码</div>
<div class="card-body" data-toggle="LgbValidate" data-valid-button="#btnSavePassword"> <div class="card-body" data-toggle="LgbValidate" data-valid-button="#btnSavePassword">
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo"> <div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
<span>演示系统禁止更改管理员密码</span> <span>演示系统禁止更改管理员密码</span>
</div> </div>
<form class="form-inline"> <form class="form-inline">
<div class="row"> <div class="row">
<div class="form-group col-sm-6 col-md-auto"> <div class="form-group col-sm-6 col-md-auto">
<label class="control-label" for="currentPassword">原密码: </label> <label class="control-label" for="currentPassword">原密码: </label>
<input type="password" class="form-control" id="currentPassword" placeholder="原密码" maxlength="16" data-valid="true" /> <input type="password" class="form-control" id="currentPassword" placeholder="原密码" maxlength="16" data-valid="true" />
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="form-group col-sm-6 col-md-auto"> <div class="form-group col-sm-6 col-md-auto">
<label class="control-label" for="newPassword">新密码: </label> <label class="control-label" for="newPassword">新密码: </label>
<input type="password" class="form-control" id="newPassword" placeholder="新密码" maxlength="16" data-valid="true" /> <input type="password" class="form-control" id="newPassword" placeholder="新密码" maxlength="16" data-valid="true" />
</div> </div>
<div class="form-group col-sm-6 col-md-auto"> <div class="form-group col-sm-6 col-md-auto">
<label class="control-label" for="confirmPassword">确认密码: </label> <label class="control-label" for="confirmPassword">确认密码: </label>
<input type="password" class="form-control" id="confirmPassword" placeholder="与新密码一致" maxlength="16" equalTo="#newPassword" data-valid="true" /> <input type="password" class="form-control" id="confirmPassword" placeholder="与新密码一致" maxlength="16" equalTo="#newPassword" data-valid="true" />
</div> </div>
</div> </div>
</form> </form>
<div class="modal-footer" asp-auth="savePassword" 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> <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>
</div> </div>
<div class="card"> <div class="card">
<div class="card-header">默认应用</div> <div class="card-header">默认应用</div>
<div class="card-body"> <div class="card-body">
<div class="form-group"> <div class="form-group">
<div class="btn-group" role="group"> <div class="btn-group" role="group">
<button id="app" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown" data-default-val="" value="@Model.AppCode">未设置</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"> <div class="dropdown-menu">
@foreach (var app in Model.Applications) @foreach (var app in Model.Applications)
{ {
<a href="#" data-val="@app.Key">@app.Value</a> <a href="#" data-val="@app.Key">@app.Value</a>
} }
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer" asp-auth="saveApp"> <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> <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>
</div> </div>
<div class="card"> <div class="card">
<div class="card-header">网站样式</div> <div class="card-header">网站样式</div>
<div class="card-body"> <div class="card-body">
<div class="alert alert-info" role="alert"> <div class="alert alert-info" role="alert">
<span>注意:本设置将覆盖<b><a class="badge-pill" href="./Settings">网站设置</a></b>中设置的网站样式</span> <span>注意:本设置将覆盖<b><a class="badge-pill" href="./Settings">网站设置</a></b>中设置的网站样式</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="btn-group" role="group"> <div class="btn-group" role="group">
<button id="css" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown" data-default-val="" value="@Model.Css">默认样式</button> <button id="css" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown" data-default-val="" value="@Model.Css">默认样式</button>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a href="#" data-val="">默认样式</a> <a href="#" data-val="">默认样式</a>
@foreach (var css in Model.Themes) @foreach (var css in Model.Themes)
{ {
<a href="#" data-val="@css.Code">@css.Name</a> <a href="#" data-val="@css.Code">@css.Name</a>
} }
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer" asp-auth="saveTheme"> <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> <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>
</div> </div>
<div class="card"> <div class="card">
<div class="card-header">修改头像</div> <div class="card-header">修改头像</div>
<div class="card-body"> <div class="card-body">
<form enctype="multipart/form-data" asp-auth="saveIcon"> <form enctype="multipart/form-data" asp-auth="saveIcon">
<div class="form-group"> <div class="form-group">
<input id="fileIcon" type="file" data-init="@Model.Size" data-file="@Model.FileName"> <input id="fileIcon" type="file" data-init="@Model.Size" data-file="@Model.FileName">
</div> </div>
</form> </form>
<img class="card-img d-none" src="@Url.Content(Model.Icon)" /> <img class="card-img d-none" src="@Url.Content(Model.Icon)" />
</div> </div>
</div> </div>

View File

@ -1,83 +1,83 @@
@model ThemeModel @model ThemeModel
@{ @{
ViewBag.Title = "网站设置"; ViewBag.Title = "网站设置";
} }
@section javascript { @section javascript {
<environment include="Development"> <environment include="Development">
<script src="~/lib/validate/jquery.validate.js"></script> <script src="~/lib/validate/jquery.validate.js"></script>
<script src="~/lib/validate/localization/messages_zh.js"></script> <script src="~/lib/validate/localization/messages_zh.js"></script>
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<script src="~/lib/validate/jquery.validate.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/validate/localization/messages_zh.min.js"></script>
</environment> </environment>
<script src="~/lib/longbow/longbow.dataentity.js"></script> <script src="~/lib/longbow/longbow.dataentity.js"></script>
<script src="~/lib/longbow/longbow.validate.js"></script> <script src="~/lib/longbow/longbow.validate.js"></script>
<script src="~/js/settings.js" asp-append-version="true"></script> <script src="~/js/settings.js" asp-append-version="true"></script>
} }
<div class="card"> <div class="card">
<div class="card-header">系统名称设置</div> <div class="card-header">系统名称设置</div>
<div class="card-body" data-toggle="LgbValidate" data-valid-button="#sysSave"> <div class="card-body" data-toggle="LgbValidate" data-valid-button="#sysSave">
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo"> <div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
<span>演示系统禁止更改系统名称</span> <span>演示系统禁止更改系统名称</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" id="sysName" placeholder="请输入网站标题50字以内" value="@Model.Title" maxlength="50" data-valid="true" /> <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"> <div class="input-group-append" asp-condition="!@Model.IsDemo">
<button class="btn btn-secondary" type="button" data-method="title" asp-auth="saveTitle">保存</button> <button class="btn btn-secondary" type="button" data-method="title" asp-auth="saveTitle">保存</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="card"> <div class="card">
<div class="card-header">页脚设置</div> <div class="card-header">页脚设置</div>
<div class="card-body" data-toggle="LgbValidate" data-valid-button="#footSave"> <div class="card-body" data-toggle="LgbValidate" data-valid-button="#footSave">
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo"> <div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
<span>演示系统禁止更改页脚</span> <span>演示系统禁止更改页脚</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" id="sysFoot" placeholder="请输入网站页脚50字以内" value="@Model.Footer" maxlength="50" data-valid="true" /> <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"> <div class="input-group-append" asp-condition="!@Model.IsDemo">
<button class="btn btn-secondary" type="button" data-method="footer" asp-auth="saveFooter">保存</button> <button class="btn btn-secondary" type="button" data-method="footer" asp-auth="saveFooter">保存</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="card"> <div class="card">
<div class="card-header">网站样式</div> <div class="card-header">网站样式</div>
<div class="card-body"> <div class="card-body">
<div class="alert alert-info" role="alert"> <div class="alert alert-info" role="alert">
<span>注意:<b><a class="badge-pill" href="./Profiles">个人中心</a></b>中设置的网站样式覆盖本设置</span> <span>注意:<b><a class="badge-pill" href="./Profiles">个人中心</a></b>中设置的网站样式覆盖本设置</span>
</div> </div>
<div class="form-group text-right"> <div class="form-group text-right">
<div class="btn-group" role="group"> <div class="btn-group" role="group">
<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> <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"> <div class="dropdown-menu">
<a href="#" data-val="">默认样式</a> <a href="#" data-val="">默认样式</a>
@foreach (var css in Model.Themes) @foreach (var css in Model.Themes)
{ {
<a href="#" data-val="@css.Code">@css.Name</a> <a href="#" data-val="@css.Code">@css.Name</a>
} }
</div> </div>
</div> </div>
<button class="btn btn-secondary" type="button" data-method="css" asp-auth="saveTheme">保存</button> <button class="btn btn-secondary" type="button" data-method="css" asp-auth="saveTheme">保存</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<span class="flex-fill">网站缓存</span> <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="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> <a data-method="refresh" href="#" class="fa fa-refresh ml-3" title="点击刷新" data-toggle="tooltip"></a>
</div> </div>
</div> </div>
<div class="card-body" id="sortable"> <div class="card-body" id="sortable">
</div> </div>
</div> </div>

View File

@ -1,18 +1,18 @@
@model NavigatorBarModel @model NavigatorBarModel
@{ @{
ViewBag.Title = "任务管理"; ViewBag.Title = "任务管理";
} }
@section css { @section css {
<link href="~/css/tasks.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/tasks.css" rel="stylesheet" asp-append-version="true" />
} }
@section javascript { @section javascript {
<script src="~/js/tasks.js" asp-append-version="true"></script> <script src="~/js/tasks.js" asp-append-version="true"></script>
} }
<div class="card"> <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-header">任务消息<span class="pull-right"><a id="refreshTask" href="javascript:;" class="fa fa-refresh"></a></span></div>
<div class="card-body"> <div class="card-body">
<div class="tasks-widget"> <div class="tasks-widget">
<ul id="list-task" class="task-list ui-sortable"></ul> <ul id="list-task" class="task-list ui-sortable"></ul>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,18 +1,18 @@
@{ @{
ViewBag.Title = "首页"; ViewBag.Title = "首页";
Layout = "_Bootstrap"; Layout = "_Bootstrap";
} }
@section css { @section css {
<style type="text/css"> <style type="text/css">
.content-body { .content-body {
position: fixed; position: fixed;
left: 0; left: 0;
bottom: 40px; bottom: 40px;
right: 0; right: 0;
top: 96px; top: 96px;
overflow: hidden; overflow: hidden;
} }
</style> </style>
} }
<div class="content-body welcome-bg"> <div class="content-body welcome-bg">
</div> </div>

View File

@ -1,25 +1,25 @@
@model ErrorModel @model ErrorModel
@{ @{
ViewBag.Title = Model.Title; ViewBag.Title = Model.Title;
Layout = "_Layout"; Layout = "_Layout";
} }
@section css { @section css {
<link href="~/css/error.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/error.css" rel="stylesheet" asp-append-version="true" />
} }
@section javascript { @section javascript {
<script src="~/js/error.js" asp-append-version="true"></script> <script src="~/js/error.js" asp-append-version="true"></script>
} }
<section class="error-wrapper"> <section class="error-wrapper">
<img src="@Url.Content(Model.Image)" /> <img src="@Url.Content(Model.Image)" />
<h1>@Model.Content</h1> <h1>@Model.Content</h1>
<h3>@Model.Detail</h3> <h3>@Model.Detail</h3>
<p><a href="~/Account/Logout">登录</a> <span>或者</span> <a href="@Url.Content(Model.ReturnUrl)">返回首页</a></p> <p><a href="~/Account/Logout">登录</a> <span>或者</span> <a href="@Url.Content(Model.ReturnUrl)">返回首页</a></p>
@if (Model.Id == 403) @if (Model.Id == 403)
{ {
<div> <div>
<p>也可能是以下原因导致您没有权限</p> <p>也可能是以下原因导致您没有权限</p>
<p>1. 没有登录,请登录后查看</p> <p>1. 没有登录,请登录后查看</p>
<p>2. 当前用户未获得此资源的相应权限,请联系管理员</p> <p>2. 当前用户未获得此资源的相应权限,请联系管理员</p>
</div> </div>
} }
</section> </section>

View File

@ -1,7 +1,7 @@
@model ModelBase @model ModelBase
<footer class="position-fixed"> <footer class="position-fixed">
<div><span id="websiteFooter">@Model.Footer</span><span asp-condition="@Model.IsDemo">(演示系统)</span></div> <div><span id="websiteFooter">@Model.Footer</span><span asp-condition="@Model.IsDemo">(演示系统)</span></div>
<a id="gotoTop" href="#" class="go-top" title="返回顶部" data-toggle="tooltip" data-placement="left"> <a id="gotoTop" href="#" class="go-top" title="返回顶部" data-toggle="tooltip" data-placement="left">
<i class="fa fa-angle-up"></i> <i class="fa fa-angle-up"></i>
</a> </a>
</footer> </footer>

View File

@ -1,25 +1,25 @@
<div class="modal fade" id="dialogGroup" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myGroupModalLabel" aria-hidden="true"> <div class="modal fade" id="dialogGroup" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myGroupModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg" role="document"> <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="myGroupModalLabel">部门授权窗口</h5> <h5 class="modal-title" id="myGroupModalLabel">部门授权窗口</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form class="form-inline"> <form class="form-inline">
<div class="row" id="groupForm"></div> <div class="row" id="groupForm"></div>
</form> </form>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"> <button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>
<span>关闭</span> <span>关闭</span>
</button> </button>
<button type="button" class="btn btn-primary" id="btnSubmitGroup"> <button type="button" class="btn btn-primary" id="btnSubmitGroup">
<i class="fa fa-save"></i> <i class="fa fa-save"></i>
<span>保存</span> <span>保存</span>
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,112 +1,112 @@
@model HeaderBarModel @model HeaderBarModel
<header class="header"> <header class="header">
<div class="bg"></div> <div class="bg"></div>
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<a id="navbar" href="#" class="sidebar-toggle-box"> <a id="navbar" href="#" class="sidebar-toggle-box">
<i class="fa fa-bars"></i> <i class="fa fa-bars"></i>
<span id="websiteTitle">@Model.Title</span> <span id="websiteTitle">@Model.Title</span>
</a> </a>
<div class="nav"> <div class="nav">
@if (User.IsInRole("Administrators")) @if (User.IsInRole("Administrators"))
{ {
<!-- tasks start --> <!-- tasks start -->
<div class="dropdown"> <div class="dropdown">
<a data-toggle="dropdown" class="shadow-primary" href="#"> <a data-toggle="dropdown" class="shadow-primary" href="#">
<i class="fa fa-tasks"></i> <i class="fa fa-tasks"></i>
<span id="msgHeaderTaskBadge" class="badge badge-pill badge-primary"></span> <span id="msgHeaderTaskBadge" class="badge badge-pill badge-primary"></span>
</a> </a>
<div class="dropdown-menu"> <div class="dropdown-menu">
<div class="dropdown-arrow arrow-primary"></div> <div class="dropdown-arrow arrow-primary"></div>
<div id="msgHeaderTaskContent" class="dropdown-header bg-primary">您有 <span id="msgHeaderTask">0</span> 个未完成的任务</div> <div id="msgHeaderTaskContent" class="dropdown-header bg-primary">您有 <span id="msgHeaderTask">0</span> 个未完成的任务</div>
<div class="dropdown-footer"> <div class="dropdown-footer">
<a href="~/Admin/Tasks">查看所有任务</a> <a href="~/Admin/Tasks">查看所有任务</a>
</div> </div>
</div> </div>
</div> </div>
<!-- tasks end --> <!-- tasks end -->
<!-- message dropdown start--> <!-- message dropdown start-->
<div class="dropdown"> <div class="dropdown">
<a data-toggle="dropdown" class="shadow-info" href="#"> <a data-toggle="dropdown" class="shadow-info" href="#">
<i class="fa fa-envelope"></i> <i class="fa fa-envelope"></i>
<span id="msgHeaderMsgBadge" class="badge badge-pill badge-info"></span> <span id="msgHeaderMsgBadge" class="badge badge-pill badge-info"></span>
</a> </a>
<div class="dropdown-menu"> <div class="dropdown-menu">
<div class="dropdown-arrow arrow-info"></div> <div class="dropdown-arrow arrow-info"></div>
<div id="msgHeaderMsgContent" class="dropdown-header bg-info">您有 <span id="msgHeaderMsg">0</span> 个未读的消息</div> <div id="msgHeaderMsgContent" class="dropdown-header bg-info">您有 <span id="msgHeaderMsg">0</span> 个未读的消息</div>
<div class="dropdown-footer"> <div class="dropdown-footer">
<a href="~/Admin/Messages">查看所有消息</a> <a href="~/Admin/Messages">查看所有消息</a>
</div> </div>
</div> </div>
</div> </div>
<!-- message dropdown end --> <!-- message dropdown end -->
<!-- users dropdown start--> <!-- users dropdown start-->
<div class="dropdown"> <div class="dropdown">
<a data-toggle="dropdown" class="shadow-success" href="#"> <a data-toggle="dropdown" class="shadow-success" href="#">
<i class="fa fa-user-plus"></i> <i class="fa fa-user-plus"></i>
<span id="msgHeaderUserBadge" class="badge badge-pill badge-success"></span> <span id="msgHeaderUserBadge" class="badge badge-pill badge-success"></span>
</a> </a>
<div class="dropdown-menu"> <div class="dropdown-menu">
<div class="dropdown-arrow arrow-success"></div> <div class="dropdown-arrow arrow-success"></div>
<div id="msgHeaderUserContent" class="dropdown-header bg-success">您有 <span id="msgHeaderUser">0</span> 条新用户通知</div> <div id="msgHeaderUserContent" class="dropdown-header bg-success">您有 <span id="msgHeaderUser">0</span> 条新用户通知</div>
<div class="dropdown-footer"> <div class="dropdown-footer">
<a href="~/Admin/Notifications">查看所有通知</a> <a href="~/Admin/Notifications">查看所有通知</a>
</div> </div>
</div> </div>
</div> </div>
<!-- users dropdown end --> <!-- users dropdown end -->
<!-- apps dropdown start--> <!-- apps dropdown start-->
<div class="dropdown"> <div class="dropdown">
<a data-toggle="dropdown" class="shadow-warning" href="#"> <a data-toggle="dropdown" class="shadow-warning" href="#">
<i class="fa fa-bug"></i> <i class="fa fa-bug"></i>
<span id="msgHeaderAppBadge" class="badge badge-pill badge-warning"></span> <span id="msgHeaderAppBadge" class="badge badge-pill badge-warning"></span>
</a> </a>
<div class="dropdown-menu"> <div class="dropdown-menu">
<div class="dropdown-arrow arrow-warning"></div> <div class="dropdown-arrow arrow-warning"></div>
<div id="msgHeaderAppContent" class="dropdown-header bg-warning">您有 <span id="msgHeaderApp">0</span> 条程序异常通知</div> <div id="msgHeaderAppContent" class="dropdown-header bg-warning">您有 <span id="msgHeaderApp">0</span> 条程序异常通知</div>
<div class="dropdown-footer"> <div class="dropdown-footer">
<a href="~/Admin/Exceptions">查看所有异常</a> <a href="~/Admin/Exceptions">查看所有异常</a>
</div> </div>
</div> </div>
</div> </div>
<!-- apps dropdown end --> <!-- apps dropdown end -->
<!-- db dropdown start--> <!-- db dropdown start-->
<div class="dropdown"> <div class="dropdown">
<a data-toggle="dropdown" class="shadow-danger" href="#"> <a data-toggle="dropdown" class="shadow-danger" href="#">
<i class="fa fa-database"></i> <i class="fa fa-database"></i>
<span id="msgHeaderDbBadge" class="badge badge-pill badge-danger"></span> <span id="msgHeaderDbBadge" class="badge badge-pill badge-danger"></span>
</a> </a>
<div class="dropdown-menu"> <div class="dropdown-menu">
<div class="dropdown-arrow arrow-danger"></div> <div class="dropdown-arrow arrow-danger"></div>
<div id="msgHeaderDbContent" class="dropdown-header bg-danger">您有 <span id="msgHeaderDb">0</span> 条数据库异常通知</div> <div id="msgHeaderDbContent" class="dropdown-header bg-danger">您有 <span id="msgHeaderDb">0</span> 条数据库异常通知</div>
<div class="dropdown-footer"> <div class="dropdown-footer">
<a href="~/Admin/Exceptions">查看所有异常</a> <a href="~/Admin/Exceptions">查看所有异常</a>
</div> </div>
</div> </div>
</div> </div>
<!-- db dropdown end --> <!-- db dropdown end -->
} }
</div> </div>
<div class="dropdown userinfo"> <div class="dropdown userinfo">
<a data-toggle="dropdown" class="dropdown-toggle shadow-default" href="#"> <a data-toggle="dropdown" class="dropdown-toggle shadow-default" href="#">
<img id="headerIcon" alt="" src="@Url.Content(Model.Icon)" /> <img id="headerIcon" alt="" src="@Url.Content(Model.Icon)" />
<span id="userDisplayName" data-userName="@Model.UserName" class="username text-truncate d-inline-block">@Model.DisplayName</span> <span id="userDisplayName" data-userName="@Model.UserName" class="username text-truncate d-inline-block">@Model.DisplayName</span>
</a> </a>
<div class="dropdown-menu dropdown-menu-right"> <div class="dropdown-menu dropdown-menu-right">
<div class="dropdown-item"> <div class="dropdown-item">
<a href="~/Admin/Profiles"><i class=" fa fa-suitcase"></i>个人中心</a> <a href="~/Admin/Profiles"><i class=" fa fa-suitcase"></i>个人中心</a>
<a href="~/Admin/Index"><i class="fa fa-cog"></i>设置</a> <a href="~/Admin/Index"><i class="fa fa-cog"></i>设置</a>
<a href="~/Admin/Notifications"><i class="fa fa-bell"></i>通知<span id="logoutNoti" class="badge badge-pill badge-success"></span></a> <a href="~/Admin/Notifications"><i class="fa fa-bell"></i>通知<span id="logoutNoti" class="badge badge-pill badge-success"></span></a>
</div> </div>
<div class="dropdown-item"> <div class="dropdown-item">
<a href="~/Account/Logout"><i class="fa fa-key"></i>注销</a> <a href="~/Account/Logout"><i class="fa fa-key"></i>注销</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="breadcrumb-item"><a href="@Url.Content("~/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> <li class="breadcrumb-item d-none" id="breadNav"></li>
</ol> </ol>
</nav> </nav>
</header> </header>

View File

@ -1,11 +1,11 @@
@model NavigatorBarModel @model NavigatorBarModel
<aside> <aside>
<!-- sidebar menu start--> <!-- sidebar menu start-->
<ul class="sidebar nav nav-pills flex-column flex-nowrap"> <ul class="sidebar nav nav-pills flex-column flex-nowrap">
@foreach (var menu in Model.Navigations) @foreach (var menu in Model.Navigations)
{ {
@await Html.PartialAsync("SubNavItem", menu) @await Html.PartialAsync("SubNavItem", menu)
} }
</ul> </ul>
<!-- sidebar menu end--> <!-- sidebar menu end-->
</aside> </aside>

View File

@ -1,25 +1,25 @@
<div class="modal fade" id="dialogMenu" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myMenuModalLabel" aria-hidden="true"> <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 id="dialogSubMenu" class="modal-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="myMenuModalLabel">请选择菜单</h5> <h5 class="modal-title" id="myMenuModalLabel">请选择菜单</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="dd" id="nestable_menu"> <div class="dd" id="nestable_menu">
<ol class="dd-list"></ol> <ol class="dd-list"></ol>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"> <button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>
<span>关闭</span> <span>关闭</span>
</button> </button>
<button type="button" class="btn btn-primary" data-dismiss="modal" id="btnSubmitMenu"> <button type="button" class="btn btn-primary" data-dismiss="modal" id="btnSubmitMenu">
<i class="fa fa-save"></i> <i class="fa fa-save"></i>
<span>确认</span> <span>确认</span>
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,25 +1,25 @@
<div class="modal fade" id="dialogRole" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myRoleModalLabel" aria-hidden="true"> <div class="modal fade" id="dialogRole" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myRoleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg" role="document"> <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="myRoleModalLabel">角色授权窗口</h5> <h5 class="modal-title" id="myRoleModalLabel">角色授权窗口</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form class="form-inline"> <form class="form-inline">
<div class="row" id="roleForm"></div> <div class="row" id="roleForm"></div>
</form> </form>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"> <button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>
<span>关闭</span> <span>关闭</span>
</button> </button>
<button type="button" class="btn btn-primary" id="btnSubmitRole"> <button type="button" class="btn btn-primary" id="btnSubmitRole">
<i class="fa fa-save"></i> <i class="fa fa-save"></i>
<span>保存</span> <span>保存</span>
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,7 +1,7 @@
@model IEnumerable<Bootstrap.Security.BootstrapMenu> @model IEnumerable<Bootstrap.Security.BootstrapMenu>
<ul class="sub nav nav-pills flex-column flex-nowrap" style="display: none;"> <ul class="sub nav nav-pills flex-column flex-nowrap" style="display: none;">
@foreach (var menu in Model) @foreach (var menu in Model)
{ {
@await Html.PartialAsync("SubNavItem", menu) @await Html.PartialAsync("SubNavItem", menu)
} }
</ul> </ul>

View File

@ -1,25 +1,25 @@
<div class="modal fade" id="dialogUser" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myUserModalLabel" aria-hidden="true"> <div class="modal fade" id="dialogUser" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myUserModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg" role="document"> <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="myUserModalLabel">用户授权窗口</h5> <h5 class="modal-title" id="myUserModalLabel">用户授权窗口</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form class="form-inline"> <form class="form-inline">
<div class="row" id="userForm"></div> <div class="row" id="userForm"></div>
</form> </form>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"> <button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>
<span>关闭</span> <span>关闭</span>
</button> </button>
<button type="button" class="btn btn-primary" id="btnSubmitUser"> <button type="button" class="btn btn-primary" id="btnSubmitUser">
<i class="fa fa-save"></i> <i class="fa fa-save"></i>
<span>保存</span> <span>保存</span>
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,37 +1,37 @@
@model HeaderBarModel @model HeaderBarModel
@{ @{
Layout = "_Layout"; Layout = "_Layout";
} }
@section css { @section css {
<environment include="Development"> <environment include="Development">
<link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" /> <link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
<link href="~/lib/font-awesome/css/font-awesome.css" rel="stylesheet" /> <link href="~/lib/font-awesome/css/font-awesome.css" rel="stylesheet" />
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<link href="~/lib/twitter-bootstrap/css/bootstrap.min.css" rel="stylesheet" /> <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/font-awesome/css/font-awesome.min.css" rel="stylesheet" />
</environment> </environment>
@RenderSection("css", false) @RenderSection("css", false)
<link href="~/css/theme.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/theme.css" rel="stylesheet" asp-append-version="true" />
<link href="~/css/theme-responsive.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/theme-responsive.css" rel="stylesheet" asp-append-version="true" />
<link href="~/css/site.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/site.css" rel="stylesheet" asp-append-version="true" />
<link href="~/css/site-responsive.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/site-responsive.css" rel="stylesheet" asp-append-version="true" />
@if (!string.IsNullOrEmpty(Model.ActiveCss)) @if (!string.IsNullOrEmpty(Model.ActiveCss))
{ {
<link href="~/css/@Model.ActiveCss" rel="stylesheet" asp-append-version="true" /> <link href="~/css/@Model.ActiveCss" rel="stylesheet" asp-append-version="true" />
} }
} }
@section javascript { @section javascript {
<environment include="Development"> <environment include="Development">
<script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.js"></script> <script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.js"></script>
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.min.js"></script> <script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.min.js"></script>
</environment> </environment>
<script src="~/lib/longbow/longbow.common.js" asp-append-version="true"></script> <script src="~/lib/longbow/longbow.common.js" asp-append-version="true"></script>
@RenderSection("javascript", false) @RenderSection("javascript", false)
} }
@await Html.PartialAsync("Header") @await Html.PartialAsync("Header")
@RenderBody() @RenderBody()
@await Html.PartialAsync("Footer") @await Html.PartialAsync("Footer")
@RenderSection("modal", false) @RenderSection("modal", false)

View File

@ -1,34 +1,34 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-cn"> <html lang="zh-cn">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="~/favicon.ico" type="image/x-icon" /> <link rel="icon" href="~/favicon.ico" type="image/x-icon" />
<link rel="shortcut 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"/> <link rel="apple-touch-icon" href="~/favicon.png"/>
<title>@ViewBag.Title</title> <title>@ViewBag.Title</title>
@RenderSection("css", false) @RenderSection("css", false)
<!--[if lt IE 10 ]> <!--[if lt IE 10 ]>
<link href="../css/IE8.css" rel="stylesheet" /> <link href="../css/IE8.css" rel="stylesheet" />
<![endif]--> <![endif]-->
</head> </head>
<body> <body>
<!--[if lt IE 10 ]> <!--[if lt IE 10 ]>
<div id="ieAlert" class="alert alert-danger alert-dismissible"> <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> <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>
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">关闭</span></button> <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">关闭</span></button>
</div> </div>
<![endif]--> <![endif]-->
@RenderBody() @RenderBody()
<a id="pathBase" href="~/" hidden></a> <a id="pathBase" href="~/" hidden></a>
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 --> <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<environment include="Development"> <environment include="Development">
<script src="~/lib/jquery/jquery.js"></script> <script src="~/lib/jquery/jquery.js"></script>
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<script src="~/lib/jquery/jquery.min.js"></script> <script src="~/lib/jquery/jquery.min.js"></script>
</environment> </environment>
@RenderSection("javascript", false) @RenderSection("javascript", false)
</body> </body>
</html> </html>

View File

@ -24,10 +24,10 @@
var html = ""; var html = "";
$.each(menus, function (index, menu) { $.each(menus, function (index, menu) {
if (menu.Menus.length === 0) { if (menu.Menus.length === 0) {
html += $.format('<li class="dd-item dd3-item" data-id="{0}" data-order="{4}" data-category="{3}"><div class="dd-handle dd3-handle"></div><div class="dd3-content"><div class="checkbox"><label><input type="checkbox" value="{0}"><span><i class="{1}"></i>{2}</span></label></div><div class="radio"><label><input type="radio" name="menu" value="{0}"><span><i class="{1}"></i>{2}</span></label></div><span class="menuType">{5}</span><span class="menuOrder">{4}</span></div></li>', menu.Id, menu.Icon, menu.Name, menu.Category, menu.Order, formatCategoryName(menu)); html += $.format('<li class="dd-item dd3-item" data-id="{0}" data-order="{4}" data-category="{3}"><div class="dd-handle dd3-handle"></div><div class="dd3-content"><div class="checkbox"><label><input type="checkbox" value="{0}"><span><i class="{1}"></i>{2}</span></label></div><div class="radio"><label><input type="radio" name="menu" value="{0}"><span><i class="{1}"></i>{2}</span></label></div><span class="menuType">{5}</span><span class="menuOrder">{4}</span></div></li>', menu.Id, menu.Icon, menu.Name, menu.Category, menu.Order, formatCategoryName(menu));
} }
else { else {
html += $.format('<li class="dd-item dd3-item" data-id="{0}" data-order="{5}" data-category="{3}"><div class="dd-handle dd3-handle"></div><div class="dd3-content"><div class="checkbox"><label><input type="checkbox" value="{0}"><span><i class="{1}"></i>{2}</span></label></div><div class="radio"><label><input type="radio" name="menu" value="{0}"><span><i class="{1}"></i>{2}</span></label></div><span class="menuType">{6}</span><span class="menuOrder">{5}</span></div><ol class="dd-list">{4}</ol></li>', menu.Id, menu.Icon, menu.Name, menu.Category, cascadeSubMenu(menu.Menus), menu.Order, formatCategoryName(menu)); html += $.format('<li class="dd-item dd3-item" data-id="{0}" data-order="{5}" data-category="{3}"><div class="dd-handle dd3-handle"></div><div class="dd3-content"><div class="checkbox"><label><input type="checkbox" value="{0}"><span><i class="{1}"></i>{2}</span></label></div><div class="radio"><label><input type="radio" name="menu" value="{0}"><span><i class="{1}"></i>{2}</span></label></div><span class="menuType">{6}</span><span class="menuOrder">{5}</span></div><ol class="dd-list">{4}</ol></li>', menu.Id, menu.Icon, menu.Name, menu.Category, cascadeSubMenu(menu.Menus), menu.Order, formatCategoryName(menu));
} }
}); });
return html; return html;

View File

@ -1,121 +1,121 @@
$(function () { $(function () {
var $headerIcon = $('#headerIcon'); var $headerIcon = $('#headerIcon');
var preIcon = $headerIcon.attr('src'); var preIcon = $headerIcon.attr('src');
var $file = $('#fileIcon'); var $file = $('#fileIcon');
var defFileName = $file.attr('data-file'); var defFileName = $file.attr('data-file');
$file.fileinput({ $file.fileinput({
uploadUrl: $.formatUrl(Profiles.url), uploadUrl: $.formatUrl(Profiles.url),
deleteUrl: $.formatUrl(Profiles.del), deleteUrl: $.formatUrl(Profiles.del),
browseOnZoneClick: true, browseOnZoneClick: true,
theme: 'fa', theme: 'fa',
language: 'zh', language: 'zh',
maxFileSize: 5000, maxFileSize: 5000,
allowedFileExtensions: ['jpg', 'png', 'bmp', 'gif', 'jpeg'], allowedFileExtensions: ['jpg', 'png', 'bmp', 'gif', 'jpeg'],
initialPreview: [ initialPreview: [
preIcon preIcon
], ],
initialPreviewConfig: [ initialPreviewConfig: [
{ caption: "", size: $file.attr('data-init'), showZoom: true, showRemove: defFileName !== 'default.jpg', key: defFileName } { caption: "", size: $file.attr('data-init'), showZoom: true, showRemove: defFileName !== 'default.jpg', key: defFileName }
], ],
initialPreviewAsData: true, initialPreviewAsData: true,
overwriteInitial: true, overwriteInitial: true,
dropZoneTitle: "请选择头像", dropZoneTitle: "请选择头像",
msgPlaceholder: "请选择头像", msgPlaceholder: "请选择头像",
fileActionSettings: { showUpload: false } fileActionSettings: { showUpload: false }
}).on('fileuploaded', function (event, data, previewId, index) { }).on('fileuploaded', function (event, data, previewId, index) {
var url = data.response.initialPreview[0]; var url = data.response.initialPreview[0];
if (!!url === true) $headerIcon.attr('src', url); if (!!url === true) $headerIcon.attr('src', url);
}).on('filebeforedelete', function (e, key) { }).on('filebeforedelete', function (e, key) {
if (key === "default.jpg") return true; if (key === "default.jpg") return true;
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
swal({ swal({
title: "您确定要删除吗?", title: "您确定要删除吗?",
type: "warning", type: "warning",
showCancelButton: true, showCancelButton: true,
cancelButtonClass: 'btn-secondary', cancelButtonClass: 'btn-secondary',
confirmButtonText: "我要删除", confirmButtonText: "我要删除",
confirmButtonClass: "btn-danger ml-2", confirmButtonClass: "btn-danger ml-2",
cancelButtonText: "取消" cancelButtonText: "取消"
}, function (del) { }, function (del) {
resolve(!del); resolve(!del);
if (del) $file.fileinput('default'); if (del) $file.fileinput('default');
}); });
}); });
}).on('filedeleted', function (event, key, jqXHR, data) { }).on('filedeleted', function (event, key, jqXHR, data) {
$headerIcon.attr('src', $.formatUrl('images/uploader/default.jpg')); $headerIcon.attr('src', $.formatUrl('images/uploader/default.jpg'));
}); });
$.fn.fileinput.Constructor.prototype.default = function () { $.fn.fileinput.Constructor.prototype.default = function () {
$.extend(this, { $.extend(this, {
initialPreview: [ initialPreview: [
$.formatUrl('images/uploader/default.jpg') $.formatUrl('images/uploader/default.jpg')
], ],
initialPreviewConfig: [ initialPreviewConfig: [
{ caption: "", size: 7195, showZoom: true, showRemove: false, key: 'default.jpg' } { caption: "", size: 7195, showZoom: true, showRemove: false, key: 'default.jpg' }
] ]
}); });
this._initPreviewCache(); this._initPreviewCache();
this._initPreview(true); this._initPreview(true);
this._initPreviewActions(); this._initPreviewActions();
this._initZoom(); this._initZoom();
}; };
$.footer(); $.footer();
var dataBinder = new DataEntity({ var dataBinder = new DataEntity({
Password: "#currentPassword", Password: "#currentPassword",
NewPassword: "#newPassword", NewPassword: "#newPassword",
DisplayName: "#displayName", DisplayName: "#displayName",
UserName: "#userName", UserName: "#userName",
Css: "#css", Css: "#css",
App: '#app' App: '#app'
}); });
$('button[data-method]').on('click', function (e) { $('button[data-method]').on('click', function (e) {
var $this = $(this); var $this = $(this);
if ($this.parent().attr("data-admin") === "True") return false; if ($this.parent().attr("data-admin") === "True") return false;
var data = dataBinder.get(); var data = dataBinder.get();
switch ($this.attr('data-method')) { switch ($this.attr('data-method')) {
case 'password': case 'password':
data.UserStatus = 'ChangePassword'; data.UserStatus = 'ChangePassword';
$.bc({ url: Profiles.url, method: "put", data: data, title: "更改密码" }); $.bc({ url: Profiles.url, method: "put", data: data, title: "更改密码" });
break; break;
case 'user': case 'user':
data.UserStatus = 'ChangeDisplayName'; data.UserStatus = 'ChangeDisplayName';
$.bc({ $.bc({
url: Profiles.url, method: "put", data: data, title: "修改用户显示名称", url: Profiles.url, method: "put", data: data, title: "修改用户显示名称",
callback: function (result) { callback: function (result) {
if (result) { if (result) {
$('#userDisplayName').text(data.DisplayName); $('#userDisplayName').text(data.DisplayName);
} }
} }
}); });
break; break;
case 'profileCss': case 'profileCss':
data.UserStatus = 'ChangeTheme'; data.UserStatus = 'ChangeTheme';
$.bc({ $.bc({
url: Profiles.url, method: "put", data: data, title: "保存样式", callback: function (result) { url: Profiles.url, method: "put", data: data, title: "保存样式", callback: function (result) {
if (result) { if (result) {
window.setTimeout(function () { window.location.reload(true); }, 1000); window.setTimeout(function () { window.location.reload(true); }, 1000);
} }
} }
}); });
break; break;
case 'app': case 'app':
data.UserStatus = 'SaveApp'; data.UserStatus = 'SaveApp';
$.bc({ $.bc({
url: Profiles.url, method: "put", data: data, title: "保存应用", callback: function (result) { url: Profiles.url, method: "put", data: data, title: "保存应用", callback: function (result) {
if (result) { if (result) {
window.setTimeout(function () { window.location.reload(true); }, 1000); window.setTimeout(function () { window.location.reload(true); }, 1000);
} }
} }
}); });
break; break;
} }
}); });
if ($('[enctype="multipart/form-data"]').length === 0) { if ($('[enctype="multipart/form-data"]').length === 0) {
$('.card-img').removeClass('d-none'); $('.card-img').removeClass('d-none');
} }
$('#css').dropdown('val'); $('#css').dropdown('val');
$('#app').dropdown('val'); $('#app').dropdown('val');
}); });

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\Keys\Longbow.Utility.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>..\Keys\Longbow.Utility.snk</AssemblyOriginatorKeyFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Include="..\Keys\Longbow.Utility.snk" Link="Longbow.Utility.snk" /> <None Include="..\Keys\Longbow.Utility.snk" Link="Longbow.Utility.snk" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.1.0" /> <PackageReference Include="Bootstrap.Security.DataAccess" Version="2.1.0" />
<PackageReference Include="Longbow.Cache" Version="2.2.7" /> <PackageReference Include="Longbow.Cache" Version="2.2.7" />
<PackageReference Include="Longbow.Data" Version="2.2.8" /> <PackageReference Include="Longbow.Data" Version="2.2.8" />
<PackageReference Include="Longbow.Web" Version="2.2.11" /> <PackageReference Include="Longbow.Web" Version="2.2.11" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.4" /> <PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.4" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -34,8 +34,8 @@ namespace Bootstrap.Client.DataAccess
public static string RetrieveSettingsUrl() public static string RetrieveSettingsUrl()
{ {
return RetrieveAppName("系统设置地址"); return RetrieveAppName("系统设置地址");
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>

View File

@ -1,44 +1,44 @@
using Bootstrap.Client.Models; using Bootstrap.Client.Models;
using Longbow.Configuration; using Longbow.Configuration;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System; using System;
namespace Bootstrap.Client.Controllers namespace Bootstrap.Client.Controllers
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class HomeController : Controller public class HomeController : Controller
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public IActionResult Index() public IActionResult Index()
{ {
return View(new NavigatorBarModel(this)); return View(new NavigatorBarModel(this));
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public IActionResult About() public IActionResult About()
{ {
return View(new NavigatorBarModel(this)); return View(new NavigatorBarModel(this));
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[AllowAnonymous] [AllowAnonymous]
public IActionResult Error(int id) public IActionResult Error(int id)
{ {
var uriBuilder = new UriBuilder(ConfigurationManager.AppSettings["AuthHost"]) { Query = QueryString.Create(CookieAuthenticationDefaults.ReturnUrlParameter, $"{Request.Scheme}://{Request.Host}{Request.PathBase}").ToString() }; var uriBuilder = new UriBuilder(ConfigurationManager.AppSettings["AuthHost"]) { Query = QueryString.Create(CookieAuthenticationDefaults.ReturnUrlParameter, $"{Request.Scheme}://{Request.Host}{Request.PathBase}").ToString() };
uriBuilder.Path = uriBuilder.Path == "/" ? Request.Path.Value : uriBuilder.Path + Request.Path.Value; uriBuilder.Path = uriBuilder.Path == "/" ? Request.Path.Value : uriBuilder.Path + Request.Path.Value;
return Redirect(uriBuilder.ToString()); return Redirect(uriBuilder.ToString());
} }
} }
} }

View File

@ -25,8 +25,8 @@ namespace Bootstrap.Client.Models
/// </summary> /// </summary>
public IEnumerable<BootstrapMenu> Navigations { get; } public IEnumerable<BootstrapMenu> Navigations { get; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string ImageLibUrl { get; set; } public string ImageLibUrl { get; set; }
} }

View File

@ -1,4 +1,4 @@
@{ @{
ViewData["Title"] = "关于"; ViewData["Title"] = "关于";
} }
<p>我是关于网页</p> <p>我是关于网页</p>

View File

@ -1,20 +1,20 @@
@model NavigatorBarModel @model NavigatorBarModel
@{ @{
ViewData["Title"] = "前台首页"; ViewData["Title"] = "前台首页";
} }
@section css { @section css {
<link href="~/lib/captcha/slidercaptcha.css" rel="stylesheet" /> <link href="~/lib/captcha/slidercaptcha.css" rel="stylesheet" />
} }
@section javascript { @section javascript {
<script src="~/lib/captcha/longbow.slidercaptcha.js"></script> <script src="~/lib/captcha/longbow.slidercaptcha.js"></script>
<script src="~/js/index.js"></script> <script src="~/js/index.js"></script>
} }
<p>这是开源后台管理框架前台系统首页,欢迎使用</p> <p>这是开源后台管理框架前台系统首页,欢迎使用</p>
<p>点击右上角登录信息下拉菜单中的设置按钮进入 <b>后台管理</b> 或者 <b><a href="@Model.SettingsUrl">直接进入</a></b></p> <p>点击右上角登录信息下拉菜单中的设置按钮进入 <b>后台管理</b> 或者 <b><a href="@Model.SettingsUrl">直接进入</a></b></p>
<p class="text-danger"><b>由于本系统为演示系统,内部对一些敏感操作进行了限制操作,如一些特殊用户不能删除。</b></p> <p class="text-danger"><b>由于本系统为演示系统,内部对一些敏感操作进行了限制操作,如一些特殊用户不能删除。</b></p>
<p> <p>
<button id="btnCaptcha" class="btn btn-success"><i class="fa fa-send-o"></i><span>点击我出现行为验证码</span></button> <button id="btnCaptcha" class="btn btn-success"><i class="fa fa-send-o"></i><span>点击我出现行为验证码</span></button>
<div class="card d-none" style="padding: 10px; height: 222px;"> <div class="card d-none" style="padding: 10px; height: 222px;">
<div id="captcha" data-imageLibUrl="@Model.ImageLibUrl"></div> <div id="captcha" data-imageLibUrl="@Model.ImageLibUrl"></div>
</div> </div>
</p> </p>

View File

@ -1,49 +1,49 @@
@model ModelBase @model ModelBase
@{ @{
Layout = "_Root"; Layout = "_Root";
} }
@section css { @section css {
<environment include="Development"> <environment include="Development">
<link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" /> <link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
<link href="~/lib/font-awesome/css/font-awesome.css" rel="stylesheet" /> <link href="~/lib/font-awesome/css/font-awesome.css" rel="stylesheet" />
<link href="~/lib/toastr.js/toastr.css" rel="stylesheet" /> <link href="~/lib/toastr.js/toastr.css" rel="stylesheet" />
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<link href="~/lib/twitter-bootstrap/css/bootstrap.min.css" rel="stylesheet" /> <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/font-awesome/css/font-awesome.min.css" rel="stylesheet" />
<link href="~/lib/toastr.js/toastr.min.css" rel="stylesheet" /> <link href="~/lib/toastr.js/toastr.min.css" rel="stylesheet" />
</environment> </environment>
@RenderSection("css", false) @RenderSection("css", false)
<link href="~/css/theme.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/theme.css" rel="stylesheet" asp-append-version="true" />
<link href="~/css/theme-responsive.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/theme-responsive.css" rel="stylesheet" asp-append-version="true" />
<link href="~/css/site.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/site.css" rel="stylesheet" asp-append-version="true" />
<link href="~/css/site-responsive.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/site-responsive.css" rel="stylesheet" asp-append-version="true" />
@if (!string.IsNullOrEmpty(Model.Theme)) @if (!string.IsNullOrEmpty(Model.Theme))
{ {
<link href="~/css/@Model.Theme" rel="stylesheet" asp-append-version="true" /> <link href="~/css/@Model.Theme" rel="stylesheet" asp-append-version="true" />
} }
} }
@section javascript { @section javascript {
<environment include="Development"> <environment include="Development">
<script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.js"></script> <script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.js"></script>
<script src="~/lib/signalr/dist/browser/signalr.js"></script> <script src="~/lib/signalr/dist/browser/signalr.js"></script>
<script src="~/lib/dcjqaccordion/js/jquery.dcjqaccordion.2.7.js"></script> <script src="~/lib/dcjqaccordion/js/jquery.dcjqaccordion.2.7.js"></script>
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.min.js"></script> <script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="~/lib/signalr/dist/browser/signalr.min.js"></script> <script src="~/lib/signalr/dist/browser/signalr.min.js"></script>
<script src="~/lib/dcjqaccordion/js/jquery.dcjqaccordion.2.7.min.js"></script> <script src="~/lib/dcjqaccordion/js/jquery.dcjqaccordion.2.7.min.js"></script>
</environment> </environment>
<script src="~/lib/toastr.js/toastr.min.js"></script> <script src="~/lib/toastr.js/toastr.min.js"></script>
<script src="~/lib/dcjqaccordion/js/jquery.cookie.js"></script> <script src="~/lib/dcjqaccordion/js/jquery.cookie.js"></script>
<script src="~/lib/longbow/longbow.common.js" asp-append-version="true"></script> <script src="~/lib/longbow/longbow.common.js" asp-append-version="true"></script>
<script src="~/js/common-scripts.js" asp-append-version="true"></script> <script src="~/js/common-scripts.js" asp-append-version="true"></script>
@RenderSection("javascript", false) @RenderSection("javascript", false)
} }
@await Html.PartialAsync("Header") @await Html.PartialAsync("Header")
@await Html.PartialAsync("navigator") @await Html.PartialAsync("navigator")
<section class="container-fluid"> <section class="container-fluid">
@RenderBody() @RenderBody()
</section> </section>
@await Html.PartialAsync("Footer") @await Html.PartialAsync("Footer")
@RenderSection("modal", false) @RenderSection("modal", false)

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +1,26 @@
$(function () { $(function () {
var $captcha = $('#captcha'); var $captcha = $('#captcha');
$captcha.sliderCaptcha({ $captcha.sliderCaptcha({
localImages: function () { localImages: function () {
return '../../lib/captcha/images/Pic' + Math.round(Math.random() * 4) + '.jpg'; return '../../lib/captcha/images/Pic' + Math.round(Math.random() * 4) + '.jpg';
}, },
setSrc: function () { setSrc: function () {
return $captcha.attr('data-imageLibUrl') + 'Pic' + Math.round(Math.random() * 136) + '.jpg'; return $captcha.attr('data-imageLibUrl') + 'Pic' + Math.round(Math.random() * 136) + '.jpg';
}, },
onSuccess: function () { onSuccess: function () {
var that = this; var that = this;
setTimeout(() => { setTimeout(() => {
that.parent().removeClass('d-inline-block'); that.parent().removeClass('d-inline-block');
that.sliderCaptcha('reset'); that.sliderCaptcha('reset');
$('.userinfo .dropdown-menu a:first')[0].click(); $('.userinfo .dropdown-menu a:first')[0].click();
}, 1000); }, 1000);
} }
}); });
$('#btnCaptcha').on('click', function () { $('#btnCaptcha').on('click', function () {
$('#captcha').parent().addClass('d-inline-block'); $('#captcha').parent().addClass('d-inline-block');
}); });
$.footer(); $.footer();
}); });

View File

@ -1,131 +1,131 @@
body { body {
overflow-x: hidden; overflow-x: hidden;
} }
.block { .block {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
} }
.sliderContainer { .sliderContainer {
position: relative; position: relative;
text-align: center; text-align: center;
line-height: 40px; line-height: 40px;
background: #f7f9fa; background: #f7f9fa;
color: #45494c; color: #45494c;
border-radius: 2px; border-radius: 2px;
} }
.sliderbg { .sliderbg {
position: absolute; position: absolute;
left: 0; left: 0;
right: 0; right: 0;
top: 0; top: 0;
background-color: #f7f9fa; background-color: #f7f9fa;
height: 40px; height: 40px;
border-radius: 2px; border-radius: 2px;
border: 1px solid #e6e8eb; border: 1px solid #e6e8eb;
} }
.sliderContainer_active .slider { .sliderContainer_active .slider {
top: -1px; top: -1px;
border: 1px solid #1991FA; border: 1px solid #1991FA;
} }
.sliderContainer_active .sliderMask { .sliderContainer_active .sliderMask {
border-width: 1px 0 1px 1px; border-width: 1px 0 1px 1px;
} }
.sliderContainer_success .slider { .sliderContainer_success .slider {
top: -1px; top: -1px;
border: 1px solid #52CCBA; border: 1px solid #52CCBA;
background-color: #52CCBA !important; background-color: #52CCBA !important;
} }
.sliderContainer_success .sliderMask { .sliderContainer_success .sliderMask {
border: 1px solid #52CCBA; border: 1px solid #52CCBA;
border-width: 1px 0 1px 1px; border-width: 1px 0 1px 1px;
background-color: #D2F4EF; background-color: #D2F4EF;
} }
.sliderContainer_success .sliderIcon:before { .sliderContainer_success .sliderIcon:before {
content: "\f00c"; content: "\f00c";
} }
.sliderContainer_fail .slider { .sliderContainer_fail .slider {
top: -1px; top: -1px;
border: 1px solid #f57a7a; border: 1px solid #f57a7a;
background-color: #f57a7a !important; background-color: #f57a7a !important;
} }
.sliderContainer_fail .sliderMask { .sliderContainer_fail .sliderMask {
border: 1px solid #f57a7a; border: 1px solid #f57a7a;
background-color: #fce1e1; background-color: #fce1e1;
border-width: 1px 0 1px 1px; border-width: 1px 0 1px 1px;
} }
.sliderContainer_fail .sliderIcon:before { .sliderContainer_fail .sliderIcon:before {
content: "\f00d"; content: "\f00d";
} }
.sliderContainer_active .sliderText, .sliderContainer_success .sliderText, .sliderContainer_fail .sliderText { .sliderContainer_active .sliderText, .sliderContainer_success .sliderText, .sliderContainer_fail .sliderText {
display: none; display: none;
} }
.sliderMask { .sliderMask {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
height: 40px; height: 40px;
border: 0 solid #1991FA; border: 0 solid #1991FA;
background: #D1E9FE; background: #D1E9FE;
border-radius: 2px; border-radius: 2px;
} }
.slider { .slider {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 40px; width: 40px;
height: 40px; height: 40px;
background: #fff; background: #fff;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.3); box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
cursor: pointer; cursor: pointer;
transition: background .2s linear; transition: background .2s linear;
border-radius: 2px; border-radius: 2px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.slider:hover { .slider:hover {
background: #1991FA; background: #1991FA;
} }
.slider:hover .sliderIcon { .slider:hover .sliderIcon {
background-position: 0 -13px; background-position: 0 -13px;
} }
.sliderText { .sliderText {
position: relative; position: relative;
} }
.sliderIcon { .sliderIcon {
} }
.refreshIcon { .refreshIcon {
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
cursor: pointer; cursor: pointer;
margin: 6px; margin: 6px;
color: rgba(0,0,0,.25); color: rgba(0,0,0,.25);
font-size: 1rem; font-size: 1rem;
z-index: 5; z-index: 5;
transition: color .3s linear; transition: color .3s linear;
} }
.refreshIcon:hover { .refreshIcon:hover {
color: #6c757d; color: #6c757d;
} }

View File

@ -243,7 +243,7 @@ namespace Bootstrap.DataAccess.MongoDB
md.IdMemberMap.SetIgnoreIfDefault(true); md.IdMemberMap.SetIgnoreIfDefault(true);
md.UnmapMember(ex => ex.Period); md.UnmapMember(ex => ex.Period);
}); });
} }
if (!BsonClassMap.IsClassMapRegistered(typeof(DataAccess.Trace))) if (!BsonClassMap.IsClassMapRegistered(typeof(DataAccess.Trace)))
{ {
BsonClassMap.RegisterClassMap<DataAccess.Trace>(md => BsonClassMap.RegisterClassMap<DataAccess.Trace>(md =>
@ -252,12 +252,12 @@ namespace Bootstrap.DataAccess.MongoDB
md.IdMemberMap.SetSerializer(new StringSerializer(BsonType.ObjectId)); md.IdMemberMap.SetSerializer(new StringSerializer(BsonType.ObjectId));
md.IdMemberMap.SetIgnoreIfDefault(true); md.IdMemberMap.SetIgnoreIfDefault(true);
}); });
} }
if (!BsonClassMap.IsClassMapRegistered(typeof(DataAccess.Log))) if (!BsonClassMap.IsClassMapRegistered(typeof(DataAccess.Log)))
{ {
BsonClassMap.RegisterClassMap<DataAccess.Log>(md => BsonClassMap.RegisterClassMap<DataAccess.Log>(md =>
{ {
md.AutoMap(); md.AutoMap();
md.AddKnownType(typeof(DataAccess.Trace)); md.AddKnownType(typeof(DataAccess.Trace));
}); });
} }
@ -278,7 +278,7 @@ namespace Bootstrap.DataAccess.MongoDB
md.IdMemberMap.SetSerializer(new StringSerializer(BsonType.ObjectId)); md.IdMemberMap.SetSerializer(new StringSerializer(BsonType.ObjectId));
md.IdMemberMap.SetIgnoreIfDefault(true); md.IdMemberMap.SetIgnoreIfDefault(true);
}); });
} }
} }
} }
} }

View File

@ -1,9 +1,9 @@
using Longbow.Web.Mvc; using Longbow.Web.Mvc;
using MongoDB.Driver; using MongoDB.Driver;
using PetaPoco; using PetaPoco;
using System; using System;
using System.Linq; using System.Linq;
namespace Bootstrap.DataAccess.MongoDB namespace Bootstrap.DataAccess.MongoDB
{ {
/// <summary> /// <summary>
@ -11,16 +11,16 @@ namespace Bootstrap.DataAccess.MongoDB
/// </summary> /// </summary>
public class Log : DataAccess.Log public class Log : DataAccess.Log
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="po"></param> /// <param name="po"></param>
/// <param name="startTime"></param> /// <param name="startTime"></param>
/// <param name="endTime"></param> /// <param name="endTime"></param>
/// <param name="opType"></param> /// <param name="opType"></param>
/// <returns></returns> /// <returns></returns>
public override Page<DataAccess.Log> Retrieves(PaginationOption po, DateTime? startTime, DateTime? endTime, string opType) public override Page<DataAccess.Log> Retrieves(PaginationOption po, DateTime? startTime, DateTime? endTime, string opType)
{ {
var filterBuilder = Builders<DataAccess.Log>.Filter; var filterBuilder = Builders<DataAccess.Log>.Filter;
var filter = filterBuilder.Empty; var filter = filterBuilder.Empty;
if (startTime.HasValue) filter = filterBuilder.Gte("LogTime", startTime.Value); if (startTime.HasValue) filter = filterBuilder.Gte("LogTime", startTime.Value);
@ -30,24 +30,24 @@ namespace Bootstrap.DataAccess.MongoDB
// sort // sort
var sortBuilder = Builders<DataAccess.Log>.Sort; var sortBuilder = Builders<DataAccess.Log>.Sort;
SortDefinition<DataAccess.Log> sort = null; SortDefinition<DataAccess.Log> sort = null;
switch (po.Sort) switch (po.Sort)
{ {
case "CRUD": case "CRUD":
sort = po.Order == "asc" ? sortBuilder.Ascending(t => t.CRUD) : sortBuilder.Descending(t => t.CRUD); sort = po.Order == "asc" ? sortBuilder.Ascending(t => t.CRUD) : sortBuilder.Descending(t => t.CRUD);
break; break;
case "UserName": case "UserName":
sort = po.Order == "asc" ? sortBuilder.Ascending(t => t.UserName) : sortBuilder.Descending(t => t.UserName); sort = po.Order == "asc" ? sortBuilder.Ascending(t => t.UserName) : sortBuilder.Descending(t => t.UserName);
break; break;
case "LogTime": case "LogTime":
sort = po.Order == "asc" ? sortBuilder.Ascending(t => t.LogTime) : sortBuilder.Descending(t => t.LogTime); sort = po.Order == "asc" ? sortBuilder.Ascending(t => t.LogTime) : sortBuilder.Descending(t => t.LogTime);
break; break;
case "Ip": case "Ip":
sort = po.Order == "asc" ? sortBuilder.Ascending(t => t.Ip) : sortBuilder.Descending(t => t.Ip); sort = po.Order == "asc" ? sortBuilder.Ascending(t => t.Ip) : sortBuilder.Descending(t => t.Ip);
break; break;
case "RequestUrl": case "RequestUrl":
sort = po.Order == "asc" ? sortBuilder.Ascending(t => t.RequestUrl) : sortBuilder.Descending(t => t.RequestUrl); sort = po.Order == "asc" ? sortBuilder.Ascending(t => t.RequestUrl) : sortBuilder.Descending(t => t.RequestUrl);
break; break;
} }
var logs = DbManager.Logs.Find(filter).Sort(sort).ToList(); var logs = DbManager.Logs.Find(filter).Sort(sort).ToList();
@ -60,8 +60,8 @@ namespace Bootstrap.DataAccess.MongoDB
TotalPages = (long)Math.Ceiling(logs.Count * 1.0 / po.Limit), TotalPages = (long)Math.Ceiling(logs.Count * 1.0 / po.Limit),
Items = logs.Skip(po.Offset).Take(po.Limit).ToList() Items = logs.Skip(po.Offset).Take(po.Limit).ToList()
}; };
} }
/// <summary> /// <summary>
/// 删除日志信息 /// 删除日志信息
/// </summary> /// </summary>

View File

@ -1,10 +1,10 @@
using Longbow.Web.Mvc; using Longbow.Web.Mvc;
using MongoDB.Driver; using MongoDB.Driver;
using PetaPoco; using PetaPoco;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Bootstrap.DataAccess.MongoDB namespace Bootstrap.DataAccess.MongoDB
{ {
/// <summary> /// <summary>
@ -28,8 +28,8 @@ namespace Bootstrap.DataAccess.MongoDB
/// </summary> /// </summary>
/// <param name="po"></param> /// <param name="po"></param>
/// <returns></returns> /// <returns></returns>
public override Page<DataAccess.LoginUser> Retrieves(PaginationOption po) public override Page<DataAccess.LoginUser> Retrieves(PaginationOption po)
{ {
var logs = DbManager.LoginUsers var logs = DbManager.LoginUsers
.Find(Builders<DataAccess.LoginUser>.Filter.Empty) .Find(Builders<DataAccess.LoginUser>.Filter.Empty)
.Sort(Builders<DataAccess.LoginUser>.Sort.Descending(t => t.LoginTime)) .Sort(Builders<DataAccess.LoginUser>.Sort.Descending(t => t.LoginTime))
@ -44,6 +44,6 @@ namespace Bootstrap.DataAccess.MongoDB
TotalPages = (long)Math.Ceiling(logs.Count * 1.0 / po.Limit), TotalPages = (long)Math.Ceiling(logs.Count * 1.0 / po.Limit),
Items = logs.Skip(po.Offset).Take(po.Limit).ToList() Items = logs.Skip(po.Offset).Take(po.Limit).ToList()
}; };
} }
} }
} }

View File

@ -1,24 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\Keys\Longbow.Utility.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>..\Keys\Longbow.Utility.snk</AssemblyOriginatorKeyFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Include="..\Keys\Longbow.Utility.snk" Link="Longbow.Utility.snk" /> <None Include="..\Keys\Longbow.Utility.snk" Link="Longbow.Utility.snk" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.1.0" /> <PackageReference Include="Bootstrap.Security.DataAccess" Version="2.1.0" />
<PackageReference Include="Longbow.Data" Version="2.2.8" /> <PackageReference Include="Longbow.Data" Version="2.2.8" />
<PackageReference Include="Longbow.Logging" Version="2.2.6" /> <PackageReference Include="Longbow.Logging" Version="2.2.6" />
<PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" /> <PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" />
<PackageReference Include="Longbow.Web" Version="2.2.11" /> <PackageReference Include="Longbow.Web" Version="2.2.11" />
<PackageReference Include="Longbow.Cache" Version="2.2.7" /> <PackageReference Include="Longbow.Cache" Version="2.2.7" />
<PackageReference Include="Longbow" Version="2.2.9" /> <PackageReference Include="Longbow" Version="2.2.9" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.4" /> <PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.4" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,97 +1,97 @@
using Longbow.Cache; using Longbow.Cache;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public static class CacheCleanUtility public static class CacheCleanUtility
{ {
private const string RetrieveAllRolesDataKey = "BootstrapAdminRoleMiddleware-RetrieveRoles"; private const string RetrieveAllRolesDataKey = "BootstrapAdminRoleMiddleware-RetrieveRoles";
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="roleIds"></param> /// <param name="roleIds"></param>
/// <param name="userIds"></param> /// <param name="userIds"></param>
/// <param name="groupIds"></param> /// <param name="groupIds"></param>
/// <param name="menuIds"></param> /// <param name="menuIds"></param>
/// <param name="appIds"></param> /// <param name="appIds"></param>
/// <param name="dictIds"></param> /// <param name="dictIds"></param>
/// <param name="cacheKey"></param> /// <param name="cacheKey"></param>
public static void ClearCache(IEnumerable<string> roleIds = null, IEnumerable<string> userIds = null, IEnumerable<string> groupIds = null, IEnumerable<string> menuIds = null, IEnumerable<string> appIds = null, IEnumerable<string> dictIds = null, string cacheKey = null) public static void ClearCache(IEnumerable<string> roleIds = null, IEnumerable<string> userIds = null, IEnumerable<string> groupIds = null, IEnumerable<string> menuIds = null, IEnumerable<string> appIds = null, IEnumerable<string> dictIds = null, string cacheKey = null)
{ {
var cacheKeys = new List<string>(); var cacheKeys = new List<string>();
var corsKeys = new List<string>(); var corsKeys = new List<string>();
if (roleIds != null) if (roleIds != null)
{ {
roleIds.ToList().ForEach(id => roleIds.ToList().ForEach(id =>
{ {
cacheKeys.Add(string.Format("{0}-{1}", UserHelper.RetrieveUsersByRoleIdDataKey, id)); cacheKeys.Add(string.Format("{0}-{1}", UserHelper.RetrieveUsersByRoleIdDataKey, id));
cacheKeys.Add(string.Format("{0}-{1}", GroupHelper.RetrieveGroupsByRoleIdDataKey, id)); cacheKeys.Add(string.Format("{0}-{1}", GroupHelper.RetrieveGroupsByRoleIdDataKey, id));
cacheKeys.Add(string.Format("{0}-{1}", MenuHelper.RetrieveMenusByRoleIdDataKey, id)); cacheKeys.Add(string.Format("{0}-{1}", MenuHelper.RetrieveMenusByRoleIdDataKey, id));
}); });
cacheKeys.Add(RoleHelper.RetrieveRolesDataKey + "*"); cacheKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*"); cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*");
cacheKeys.Add(RetrieveAllRolesDataKey + "*"); cacheKeys.Add(RetrieveAllRolesDataKey + "*");
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*"); corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
} }
if (userIds != null) if (userIds != null)
{ {
userIds.ToList().ForEach(id => userIds.ToList().ForEach(id =>
{ {
cacheKeys.Add(string.Format("{0}-{1}", RoleHelper.RetrieveRolesByUserIdDataKey, id)); cacheKeys.Add(string.Format("{0}-{1}", RoleHelper.RetrieveRolesByUserIdDataKey, id));
cacheKeys.Add(string.Format("{0}-{1}", GroupHelper.RetrieveGroupsByUserIdDataKey, id)); cacheKeys.Add(string.Format("{0}-{1}", GroupHelper.RetrieveGroupsByUserIdDataKey, id));
cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*"); cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*");
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*"); corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
}); });
cacheKeys.Add(UserHelper.RetrieveNewUsersDataKey + "*"); cacheKeys.Add(UserHelper.RetrieveNewUsersDataKey + "*");
cacheKeys.Add(UserHelper.RetrieveUsersDataKey + "*"); cacheKeys.Add(UserHelper.RetrieveUsersDataKey + "*");
corsKeys.Add(UserHelper.RetrieveUsersDataKey + "*"); corsKeys.Add(UserHelper.RetrieveUsersDataKey + "*");
} }
if (groupIds != null) if (groupIds != null)
{ {
groupIds.ToList().ForEach(id => groupIds.ToList().ForEach(id =>
{ {
cacheKeys.Add(string.Format("{0}-{1}", RoleHelper.RetrieveRolesByGroupIdDataKey, id)); cacheKeys.Add(string.Format("{0}-{1}", RoleHelper.RetrieveRolesByGroupIdDataKey, id));
cacheKeys.Add(string.Format("{0}-{1}", UserHelper.RetrieveUsersByGroupIdDataKey, id)); cacheKeys.Add(string.Format("{0}-{1}", UserHelper.RetrieveUsersByGroupIdDataKey, id));
}); });
cacheKeys.Add(GroupHelper.RetrieveGroupsDataKey + "*"); cacheKeys.Add(GroupHelper.RetrieveGroupsDataKey + "*");
cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*"); cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*");
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*"); corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
cacheKeys.Add(RetrieveAllRolesDataKey + "*"); cacheKeys.Add(RetrieveAllRolesDataKey + "*");
} }
if (menuIds != null) if (menuIds != null)
{ {
menuIds.ToList().ForEach(id => menuIds.ToList().ForEach(id =>
{ {
cacheKeys.Add(string.Format("{0}-{1}", RoleHelper.RetrieveRolesByMenuIdDataKey, id)); cacheKeys.Add(string.Format("{0}-{1}", RoleHelper.RetrieveRolesByMenuIdDataKey, id));
}); });
cacheKeys.Add(MenuHelper.RetrieveMenusByRoleIdDataKey + "*"); cacheKeys.Add(MenuHelper.RetrieveMenusByRoleIdDataKey + "*");
cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*"); cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*");
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*"); corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
} }
if (appIds != null) if (appIds != null)
{ {
appIds.ToList().ForEach(id => appIds.ToList().ForEach(id =>
{ {
cacheKeys.Add(string.Format("{0}-{1}", AppHelper.RetrieveAppsByRoleIdDataKey, id)); cacheKeys.Add(string.Format("{0}-{1}", AppHelper.RetrieveAppsByRoleIdDataKey, id));
}); });
} }
if (dictIds != null) if (dictIds != null)
{ {
cacheKeys.Add(DictHelper.RetrieveDictsDataKey + "*"); cacheKeys.Add(DictHelper.RetrieveDictsDataKey + "*");
cacheKeys.Add(DictHelper.RetrieveCategoryDataKey); cacheKeys.Add(DictHelper.RetrieveCategoryDataKey);
corsKeys.Add(DictHelper.RetrieveDictsDataKey + "*"); corsKeys.Add(DictHelper.RetrieveDictsDataKey + "*");
} }
if (cacheKey != null) if (cacheKey != null)
{ {
cacheKeys.Add(cacheKey); cacheKeys.Add(cacheKey);
corsKeys.Add(cacheKey); corsKeys.Add(cacheKey);
} }
CacheManager.Clear(cacheKeys); CacheManager.Clear(cacheKeys);
CacheManager.CorsClear(corsKeys); CacheManager.CorsClear(corsKeys);
} }
} }
} }

View File

@ -1,38 +1,38 @@
using PetaPoco; using PetaPoco;
using System; using System;
using System.Collections.Specialized; using System.Collections.Specialized;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public static class DbManager public static class DbManager
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="connectionName"></param> /// <param name="connectionName"></param>
/// <returns></returns> /// <returns></returns>
public static IDatabase Create(string connectionName = null, bool keepAlive = false) public static IDatabase Create(string connectionName = null, bool keepAlive = false)
{ {
var db = Longbow.Data.DbManager.Create(connectionName, keepAlive); var db = Longbow.Data.DbManager.Create(connectionName, keepAlive);
db.ExceptionThrown += (sender, args) => args.Exception.Log(new NameValueCollection() { ["LastCmd"] = db.LastCommand }); db.ExceptionThrown += (sender, args) => args.Exception.Log(new NameValueCollection() { ["LastCmd"] = db.LastCommand });
return db.AddMaps(); return db.AddMaps();
} }
private static IDatabase AddMaps(this IDatabase database) private static IDatabase AddMaps(this IDatabase database)
{ {
database.AddMap<Dict>("Dicts"); database.AddMap<Dict>("Dicts");
database.AddMap<User>("Users", new string[] { "Checked", "Period", "NewPassword", "UserStatus" }); database.AddMap<User>("Users", new string[] { "Checked", "Period", "NewPassword", "UserStatus" });
database.AddMap<Exceptions>("Exceptions", new string[] { "Period" }); database.AddMap<Exceptions>("Exceptions", new string[] { "Period" });
database.AddMap<Group>("Groups", new string[] { "Checked" }); database.AddMap<Group>("Groups", new string[] { "Checked" });
database.AddMap<Log>("Logs"); database.AddMap<Log>("Logs");
database.AddMap<Menu>("Navigations", new string[] { "ParentName", "CategoryName", "Active", "Menus" }); database.AddMap<Menu>("Navigations", new string[] { "ParentName", "CategoryName", "Active", "Menus" });
database.AddMap<Role>("Roles", new string[] { "Checked" }); database.AddMap<Role>("Roles", new string[] { "Checked" });
database.AddMap<Task>("Tasks"); database.AddMap<Task>("Tasks");
database.AddMap<Trace>("Traces"); database.AddMap<Trace>("Traces");
return database; return database;
} }
} }
} }

View File

@ -1,186 +1,186 @@
using Bootstrap.Security; using Bootstrap.Security;
using Bootstrap.Security.DataAccess; using Bootstrap.Security.DataAccess;
using Longbow; using Longbow;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class Dict : BootstrapDict public class Dict : BootstrapDict
{ {
/// <summary> /// <summary>
/// 删除字典中的数据 /// 删除字典中的数据
/// </summary> /// </summary>
/// <param name="value">需要删除的IDs</param> /// <param name="value">需要删除的IDs</param>
/// <returns></returns> /// <returns></returns>
public virtual bool Delete(IEnumerable<string> value) public virtual bool Delete(IEnumerable<string> value)
{ {
if (!value.Any()) return true; if (!value.Any()) return true;
var ids = string.Join(",", value); var ids = string.Join(",", value);
string sql = $"where ID in ({ids})"; string sql = $"where ID in ({ids})";
DbManager.Create().Delete<BootstrapDict>(sql); DbManager.Create().Delete<BootstrapDict>(sql);
return true; return true;
} }
/// <summary> /// <summary>
/// 保存新建/更新的字典信息 /// 保存新建/更新的字典信息
/// </summary> /// </summary>
/// <param name="dict"></param> /// <param name="dict"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool Save(BootstrapDict dict) public virtual bool Save(BootstrapDict dict)
{ {
if (dict.Category.Length > 50) dict.Category = dict.Category.Substring(0, 50); if (dict.Category.Length > 50) dict.Category = dict.Category.Substring(0, 50);
if (dict.Name.Length > 50) dict.Name = dict.Name.Substring(0, 50); if (dict.Name.Length > 50) dict.Name = dict.Name.Substring(0, 50);
if (dict.Code.Length > 2000) dict.Code = dict.Code.Substring(0, 2000); if (dict.Code.Length > 2000) dict.Code = dict.Code.Substring(0, 2000);
DbManager.Create().Save(dict); DbManager.Create().Save(dict);
return true; return true;
} }
/// <summary> /// <summary>
/// 保存网站个性化设置 /// 保存网站个性化设置
/// </summary> /// </summary>
/// <param name="dict"></param> /// <param name="dict"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool SaveSettings(BootstrapDict dict) public virtual bool SaveSettings(BootstrapDict dict)
{ {
DbManager.Create().Update<BootstrapDict>("set Code = @Code where Category = @Category and Name = @Name", dict); DbManager.Create().Update<BootstrapDict>("set Code = @Code where Category = @Category and Name = @Name", dict);
return true; return true;
} }
/// <summary> /// <summary>
/// 获取字典分类名称 /// 获取字典分类名称
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<string> RetrieveCategories() => DictHelper.RetrieveDicts().OrderBy(d => d.Category).Select(d => d.Category).Distinct(); public virtual IEnumerable<string> RetrieveCategories() => DictHelper.RetrieveDicts().OrderBy(d => d.Category).Select(d => d.Category).Distinct();
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual string RetrieveWebTitle() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站标题" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "后台管理系统" }).Code; public virtual string RetrieveWebTitle() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站标题" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "后台管理系统" }).Code;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual string RetrieveWebFooter() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站页脚" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "2016 © 通用后台管理系统" }).Code; public virtual string RetrieveWebFooter() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站页脚" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "2016 © 通用后台管理系统" }).Code;
/// <summary> /// <summary>
/// 获得系统中配置的可以使用的网站样式 /// 获得系统中配置的可以使用的网站样式
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<BootstrapDict> RetrieveThemes() => DictHelper.RetrieveDicts().Where(d => d.Category == "网站样式"); public virtual IEnumerable<BootstrapDict> RetrieveThemes() => DictHelper.RetrieveDicts().Where(d => d.Category == "网站样式");
/// <summary> /// <summary>
/// 获得网站设置中的当前样式 /// 获得网站设置中的当前样式
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual string RetrieveActiveTheme() public virtual string RetrieveActiveTheme()
{ {
var theme = DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "使用样式" && d.Category == "当前样式" && d.Define == 0); var theme = DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "使用样式" && d.Category == "当前样式" && d.Define == 0);
return theme == null ? string.Empty : (theme.Code.Equals("site.css", StringComparison.OrdinalIgnoreCase) ? string.Empty : theme.Code); return theme == null ? string.Empty : (theme.Code.Equals("site.css", StringComparison.OrdinalIgnoreCase) ? string.Empty : theme.Code);
} }
/// <summary> /// <summary>
/// 获取头像路径 /// 获取头像路径
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual string RetrieveIconFolderPath() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "头像路径" && d.Category == "头像地址" && d.Define == 0) ?? new BootstrapDict { Code = "~/images/uploader/" }).Code; public virtual string RetrieveIconFolderPath() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "头像路径" && d.Category == "头像地址" && d.Define == 0) ?? new BootstrapDict { Code = "~/images/uploader/" }).Code;
/// <summary> /// <summary>
/// 获得默认的前台首页地址,默认为~/Home/Index /// 获得默认的前台首页地址,默认为~/Home/Index
/// </summary> /// </summary>
/// <param name="appCode"></param> /// <param name="appCode"></param>
/// <returns></returns> /// <returns></returns>
public virtual string RetrieveHomeUrl(string appCode) public virtual string RetrieveHomeUrl(string appCode)
{ {
// https://gitee.com/LongbowEnterprise/dashboard/issues?id=IS0WK // https://gitee.com/LongbowEnterprise/dashboard/issues?id=IS0WK
var url = "~/Home/Index"; var url = "~/Home/Index";
var dicts = DictHelper.RetrieveDicts(); var dicts = DictHelper.RetrieveDicts();
if (appCode != "0") if (appCode != "0")
{ {
var appUrl = dicts.FirstOrDefault(d => d.Name.Equals(appCode, StringComparison.OrdinalIgnoreCase) && d.Category == "应用首页" && d.Define == 0)?.Code; var appUrl = dicts.FirstOrDefault(d => d.Name.Equals(appCode, StringComparison.OrdinalIgnoreCase) && d.Category == "应用首页" && d.Define == 0)?.Code;
if (!string.IsNullOrEmpty(appUrl)) if (!string.IsNullOrEmpty(appUrl))
{ {
url = appUrl; url = appUrl;
return url; return url;
} }
} }
var defaultUrl = dicts.FirstOrDefault(d => d.Name == "前台首页" && d.Category == "网站设置" && d.Define == 0)?.Code; var defaultUrl = dicts.FirstOrDefault(d => d.Name == "前台首页" && d.Category == "网站设置" && d.Define == 0)?.Code;
if (!string.IsNullOrEmpty(defaultUrl)) url = defaultUrl; if (!string.IsNullOrEmpty(defaultUrl)) url = defaultUrl;
return url; return url;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<KeyValuePair<string, string>> RetrieveApps() => DictHelper.RetrieveDicts().Where(d => d.Category == "应用程序" && d.Define == 0).Select(d => new KeyValuePair<string, string>(d.Code, d.Name)).OrderBy(d => d.Key); public virtual IEnumerable<KeyValuePair<string, string>> RetrieveApps() => DictHelper.RetrieveDicts().Where(d => d.Category == "应用程序" && d.Define == 0).Select(d => new KeyValuePair<string, string>(d.Code, d.Name)).OrderBy(d => d.Key);
/// <summary> /// <summary>
/// 通过数据库获得所有字典表配置信息缓存Key=DictHelper-RetrieveDicts /// 通过数据库获得所有字典表配置信息缓存Key=DictHelper-RetrieveDicts
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<BootstrapDict> RetrieveDicts() => DbHelper.RetrieveDicts(); public virtual IEnumerable<BootstrapDict> RetrieveDicts() => DbHelper.RetrieveDicts();
/// <summary> /// <summary>
/// 程序异常时长 默认1月 /// 程序异常时长 默认1月
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public int RetrieveExceptionsLogPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "程序异常保留时长" && d.Define == 0)?.Code, 1); public int RetrieveExceptionsLogPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "程序异常保留时长" && d.Define == 0)?.Code, 1);
/// <summary> /// <summary>
/// 操作日志时长 默认12月 /// 操作日志时长 默认12月
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public int RetrieveLogsPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "操作日志保留时长" && d.Define == 0)?.Code, 12); public int RetrieveLogsPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "操作日志保留时长" && d.Define == 0)?.Code, 12);
/// <summary> /// <summary>
/// 登录日志时长 默认12月 /// 登录日志时长 默认12月
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public int RetrieveLoginLogsPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "登录日志保留时长" && d.Define == 0)?.Code, 12); public int RetrieveLoginLogsPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "登录日志保留时长" && d.Define == 0)?.Code, 12);
/// <summary> /// <summary>
/// Cookie保存时长 默认7天 /// Cookie保存时长 默认7天
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public int RetrieveCookieExpiresPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "Cookie保留时长" && d.Define == 0)?.Code, 7); public int RetrieveCookieExpiresPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "Cookie保留时长" && d.Define == 0)?.Code, 7);
/// <summary> /// <summary>
/// 获得 IP地理位置 /// 获得 IP地理位置
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public string RetrieveLocaleIPSvr() => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "IP地理位置接口" && d.Define == 0)?.Code; public string RetrieveLocaleIPSvr() => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "IP地理位置接口" && d.Define == 0)?.Code;
/// <summary> /// <summary>
/// 获得 项目是否获取登录地点 默认为false /// 获得 项目是否获取登录地点 默认为false
/// </summary> /// </summary>
/// <param name="ipSvr">服务提供名称</param> /// <param name="ipSvr">服务提供名称</param>
/// <returns></returns> /// <returns></returns>
public string RetrieveLocaleIPSvrUrl(string ipSvr) => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == ipSvr && d.Define == 0)?.Code; public string RetrieveLocaleIPSvrUrl(string ipSvr) => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == ipSvr && d.Define == 0)?.Code;
/// <summary> /// <summary>
/// 获得 访问日志保留时长 默认为1个月 /// 获得 访问日志保留时长 默认为1个月
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public int RetrieveAccessLogPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "访问日志保留时长" && d.Define == 0)?.Code, 1); public int RetrieveAccessLogPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "访问日志保留时长" && d.Define == 0)?.Code, 1);
/// <summary> /// <summary>
/// 获得 是否为演示系统 默认为 false 不是演示系统 /// 获得 是否为演示系统 默认为 false 不是演示系统
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public bool RetrieveSystemModel() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "演示系统" && d.Define == 0)?.Code, "0") == "1"; public bool RetrieveSystemModel() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "演示系统" && d.Define == 0)?.Code, "0") == "1";
/// <summary> /// <summary>
/// 获得 验证码图床地址 /// 获得 验证码图床地址
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public string RetrieveImagesLibUrl() => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "验证码图床" && d.Define == 0)?.Code ?? "http://images.sdgxgz.com/"; public string RetrieveImagesLibUrl() => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "验证码图床" && d.Define == 0)?.Code ?? "http://images.sdgxgz.com/";
} }
} }

View File

@ -3,8 +3,8 @@ using PetaPoco;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Data.Common; using System.Data.Common;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>
@ -62,8 +62,8 @@ namespace Bootstrap.DataAccess
/// </summary> /// </summary>
public string Period { get; set; } public string Period { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string Category { get; set; } public string Category { get; set; }
@ -82,17 +82,17 @@ namespace Bootstrap.DataAccess
{ {
if (ex == null) return true; if (ex == null) return true;
var errorPage = additionalInfo?["ErrorPage"] ?? (ex.GetType().Name.Length > 50 ? ex.GetType().Name.Substring(0, 50) : ex.GetType().Name); var errorPage = additionalInfo?["ErrorPage"] ?? (ex.GetType().Name.Length > 50 ? ex.GetType().Name.Substring(0, 50) : ex.GetType().Name);
var loopEx = ex; var loopEx = ex;
var category = "App"; var category = "App";
while (loopEx != null) while (loopEx != null)
{ {
if (typeof(DbException).IsAssignableFrom(loopEx.GetType())) if (typeof(DbException).IsAssignableFrom(loopEx.GetType()))
{ {
category = "DB"; category = "DB";
break; break;
} }
loopEx = loopEx.InnerException; loopEx = loopEx.InnerException;
} }
DbManager.Create().Insert(new Exceptions DbManager.Create().Insert(new Exceptions
{ {

View File

@ -1,161 +1,161 @@
using Bootstrap.Security.DataAccess; using Bootstrap.Security.DataAccess;
using Longbow.Data; using Longbow.Data;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class Group public class Group
{ {
/// <summary> /// <summary>
/// 获得/设置 群组主键ID /// 获得/设置 群组主键ID
/// </summary> /// </summary>
public string Id { get; set; } public string Id { get; set; }
/// <summary> /// <summary>
/// 获得/设置 群组名称 /// 获得/设置 群组名称
/// </summary> /// </summary>
public string GroupName { get; set; } public string GroupName { get; set; }
/// <summary> /// <summary>
/// 获得/设置 群组描述 /// 获得/设置 群组描述
/// </summary> /// </summary>
public string Description { get; set; } public string Description { get; set; }
/// <summary> /// <summary>
/// 获取/设置 用户群组关联状态 checked 标示已经关联 '' 标示未关联 /// 获取/设置 用户群组关联状态 checked 标示已经关联 '' 标示未关联
/// </summary> /// </summary>
public string Checked { get; set; } public string Checked { get; set; }
/// <summary> /// <summary>
/// 查询所有群组信息 /// 查询所有群组信息
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<Group> Retrieves() => DbManager.Create().Fetch<Group>(); public virtual IEnumerable<Group> Retrieves() => DbManager.Create().Fetch<Group>();
/// <summary> /// <summary>
/// 删除群组信息 /// 删除群组信息
/// </summary> /// </summary>
/// <param name="ids"></param> /// <param name="ids"></param>
public virtual bool Delete(IEnumerable<string> value) public virtual bool Delete(IEnumerable<string> value)
{ {
bool ret = false; bool ret = false;
var ids = string.Join(",", value); var ids = string.Join(",", value);
var db = DbManager.Create(); var db = DbManager.Create();
try try
{ {
db.BeginTransaction(); db.BeginTransaction();
db.Execute($"delete from UserGroup where GroupID in ({ids})"); db.Execute($"delete from UserGroup where GroupID in ({ids})");
db.Execute($"delete from RoleGroup where GroupID in ({ids})"); db.Execute($"delete from RoleGroup where GroupID in ({ids})");
db.Execute($"delete from {db.Provider.EscapeSqlIdentifier("Groups")} where ID in ({ids})"); db.Execute($"delete from {db.Provider.EscapeSqlIdentifier("Groups")} where ID in ({ids})");
db.CompleteTransaction(); db.CompleteTransaction();
ret = true; ret = true;
} }
catch (Exception e) catch (Exception e)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw e; throw e;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// 保存新建/更新的群组信息 /// 保存新建/更新的群组信息
/// </summary> /// </summary>
/// <param name="p"></param> /// <param name="p"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool Save(Group p) public virtual bool Save(Group p)
{ {
DbManager.Create().Save(p); DbManager.Create().Save(p);
return !p.Id.IsNullOrEmpty(); return !p.Id.IsNullOrEmpty();
} }
/// <summary> /// <summary>
/// 根据用户查询部门信息 /// 根据用户查询部门信息
/// </summary> /// </summary>
/// <param name="userId"></param> /// <param name="userId"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<Group> RetrievesByUserId(string userId) public virtual IEnumerable<Group> RetrievesByUserId(string userId)
{ {
var db = DbManager.Create(); var db = DbManager.Create();
return db.Fetch<Group>($"select g.ID, g.GroupName, g.Description, case ug.GroupID when g.ID then 'checked' else '' end Checked from {db.Provider.EscapeSqlIdentifier("Groups")} g left join UserGroup ug on g.ID = ug.GroupID and UserID = @0", userId); return db.Fetch<Group>($"select g.ID, g.GroupName, g.Description, case ug.GroupID when g.ID then 'checked' else '' end Checked from {db.Provider.EscapeSqlIdentifier("Groups")} g left join UserGroup ug on g.ID = ug.GroupID and UserID = @0", userId);
} }
/// <summary> /// <summary>
/// 根据角色ID指派部门 /// 根据角色ID指派部门
/// </summary> /// </summary>
/// <param name="roleId"></param> /// <param name="roleId"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<Group> RetrievesByRoleId(string roleId) public virtual IEnumerable<Group> RetrievesByRoleId(string roleId)
{ {
var db = DbManager.Create(); var db = DbManager.Create();
return db.Fetch<Group>($"select g.ID, g.GroupName, g.Description, case rg.GroupID when g.ID then 'checked' else '' end Checked from {db.Provider.EscapeSqlIdentifier("Groups")} g left join RoleGroup rg on g.ID = rg.GroupID and RoleID = @0", roleId); return db.Fetch<Group>($"select g.ID, g.GroupName, g.Description, case rg.GroupID when g.ID then 'checked' else '' end Checked from {db.Provider.EscapeSqlIdentifier("Groups")} g left join RoleGroup rg on g.ID = rg.GroupID and RoleID = @0", roleId);
} }
/// <summary> /// <summary>
/// 保存用户部门关系 /// 保存用户部门关系
/// </summary> /// </summary>
/// <param name="userId"></param> /// <param name="userId"></param>
/// <param name="groupIds"></param> /// <param name="groupIds"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool SaveByUserId(string userId, IEnumerable<string> groupIds) public virtual bool SaveByUserId(string userId, IEnumerable<string> groupIds)
{ {
var ret = false; var ret = false;
var db = DbManager.Create(); var db = DbManager.Create();
try try
{ {
db.BeginTransaction(); db.BeginTransaction();
//删除用户部门表中该用户所有的部门关系 //删除用户部门表中该用户所有的部门关系
db.Execute("delete from UserGroup where UserID = @0", userId); db.Execute("delete from UserGroup where UserID = @0", userId);
db.InsertBatch("UserGroup", groupIds.Select(g => new { UserID = userId, GroupID = g })); db.InsertBatch("UserGroup", groupIds.Select(g => new { UserID = userId, GroupID = g }));
db.CompleteTransaction(); db.CompleteTransaction();
ret = true; ret = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw ex; throw ex;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// 根据角色ID以及选定的部门ID保到角色部门表 /// 根据角色ID以及选定的部门ID保到角色部门表
/// </summary> /// </summary>
/// <param name="roleId"></param> /// <param name="roleId"></param>
/// <param name="groupIds"></param> /// <param name="groupIds"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool SaveByRoleId(string roleId, IEnumerable<string> groupIds) public virtual bool SaveByRoleId(string roleId, IEnumerable<string> groupIds)
{ {
bool ret = false; bool ret = false;
var db = DbManager.Create(); var db = DbManager.Create();
try try
{ {
db.BeginTransaction(); db.BeginTransaction();
//删除角色部门表该角色所有的部门 //删除角色部门表该角色所有的部门
db.Execute("delete from RoleGroup where RoleID = @0", roleId); db.Execute("delete from RoleGroup where RoleID = @0", roleId);
db.InsertBatch("RoleGroup", groupIds.Select(g => new { RoleID = roleId, GroupID = g })); db.InsertBatch("RoleGroup", groupIds.Select(g => new { RoleID = roleId, GroupID = g }));
db.CompleteTransaction(); db.CompleteTransaction();
ret = true; ret = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw ex; throw ex;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<string> RetrievesByUserName(string userName) => DbHelper.RetrieveGroupsByUserName(userName); public virtual IEnumerable<string> RetrievesByUserName(string userName) => DbHelper.RetrieveGroupsByUserName(userName);
} }
} }

View File

@ -201,9 +201,9 @@ namespace Bootstrap.DataAccess
/// <returns></returns> /// <returns></returns>
public static bool RetrieveSystemModel() => DbContextManager.Create<Dict>().RetrieveSystemModel(); public static bool RetrieveSystemModel() => DbContextManager.Create<Dict>().RetrieveSystemModel();
/// <summary> /// <summary>
/// 获得验证码图床地址 /// 获得验证码图床地址
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static string RetrieveImagesLibUrl() => DbContextManager.Create<Dict>().RetrieveImagesLibUrl(); public static string RetrieveImagesLibUrl() => DbContextManager.Create<Dict>().RetrieveImagesLibUrl();
} }

View File

@ -1,8 +1,8 @@
using Longbow.Data; using Longbow.Data;
using Longbow.Web.Mvc; using Longbow.Web.Mvc;
using PetaPoco; using PetaPoco;
using System; using System;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>

View File

@ -1,7 +1,7 @@
using Longbow.Data; using Longbow.Data;
using Longbow.Web.Mvc; using Longbow.Web.Mvc;
using PetaPoco; using PetaPoco;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>
@ -20,6 +20,6 @@ namespace Bootstrap.DataAccess
/// 查询所有登录日志 /// 查询所有登录日志
/// </summary> /// </summary>
/// <param name="po"></param> /// <param name="po"></param>
public static Page<LoginUser> Retrieves(PaginationOption po) => DbContextManager.Create<LoginUser>().Retrieves(po); public static Page<LoginUser> Retrieves(PaginationOption po) => DbContextManager.Create<LoginUser>().Retrieves(po);
} }
} }

View File

@ -1,69 +1,69 @@
using Longbow.Web.Mvc; using Longbow.Web.Mvc;
using PetaPoco; using PetaPoco;
using System; using System;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class Log : Trace public class Log : Trace
{ {
/// <summary> /// <summary>
/// 获得/设置 操作类型 /// 获得/设置 操作类型
/// </summary> /// </summary>
public string CRUD { get; set; } public string CRUD { get; set; }
/// <summary> /// <summary>
/// 获得/设置 请求数据 /// 获得/设置 请求数据
/// </summary> /// </summary>
public string RequestData { get; set; } public string RequestData { get; set; }
/// <summary> /// <summary>
/// 查询所有操作日志信息 /// 查询所有操作日志信息
/// </summary> /// </summary>
/// <param name="po"></param> /// <param name="po"></param>
/// <param name="startTime"></param> /// <param name="startTime"></param>
/// <param name="endTime"></param> /// <param name="endTime"></param>
/// <param name="opType"></param> /// <param name="opType"></param>
/// <returns></returns> /// <returns></returns>
public virtual Page<Log> Retrieves(PaginationOption po, DateTime? startTime, DateTime? endTime, string opType) public virtual Page<Log> Retrieves(PaginationOption po, DateTime? startTime, DateTime? endTime, string opType)
{ {
var sql = new Sql("select CRUD, UserName, LogTime, Ip, Browser, OS, City, RequestUrl, RequestData from Logs"); var sql = new Sql("select CRUD, UserName, LogTime, Ip, Browser, OS, City, RequestUrl, RequestData from Logs");
if (startTime.HasValue) sql.Append("where LogTime >= @0", startTime.Value); if (startTime.HasValue) sql.Append("where LogTime >= @0", startTime.Value);
if (endTime.HasValue) sql.Append("where LogTime < @0", endTime.Value.AddDays(1).AddSeconds(-1)); if (endTime.HasValue) sql.Append("where LogTime < @0", endTime.Value.AddDays(1).AddSeconds(-1));
if (startTime == null && endTime == null) sql.Append("where LogTime > @0", DateTime.Today.AddMonths(0 - DictHelper.RetrieveExceptionsLogPeriod())); if (startTime == null && endTime == null) sql.Append("where LogTime > @0", DateTime.Today.AddMonths(0 - DictHelper.RetrieveExceptionsLogPeriod()));
if (!string.IsNullOrEmpty(opType)) sql.Append("where CRUD = @0", opType); if (!string.IsNullOrEmpty(opType)) sql.Append("where CRUD = @0", opType);
sql.Append($"order by {po.Sort} {po.Order}"); sql.Append($"order by {po.Sort} {po.Order}");
return DbManager.Create().Page<Log>(po.PageIndex, po.Limit, sql); return DbManager.Create().Page<Log>(po.PageIndex, po.Limit, sql);
} }
/// <summary> /// <summary>
/// 删除日志信息 /// 删除日志信息
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private static void DeleteLogAsync() private static void DeleteLogAsync()
{ {
System.Threading.Tasks.Task.Run(() => System.Threading.Tasks.Task.Run(() =>
{ {
var dtm = DateTime.Now.AddMonths(0 - DictHelper.RetrieveLogsPeriod()); var dtm = DateTime.Now.AddMonths(0 - DictHelper.RetrieveLogsPeriod());
DbManager.Create().Execute("delete from Logs where LogTime < @0", dtm); DbManager.Create().Execute("delete from Logs where LogTime < @0", dtm);
}); });
} }
/// <summary> /// <summary>
/// 保存新增的日志信息 /// 保存新增的日志信息
/// </summary> /// </summary>
/// <param name="p"></param> /// <param name="p"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool Save(Log p) public virtual bool Save(Log p)
{ {
if (p == null) throw new ArgumentNullException(nameof(p)); if (p == null) throw new ArgumentNullException(nameof(p));
DeleteLogAsync(); DeleteLogAsync();
p.LogTime = DateTime.Now; p.LogTime = DateTime.Now;
DbManager.Create().Save(p); DbManager.Create().Save(p);
return true; return true;
} }
} }
} }

View File

@ -1,4 +1,4 @@
using Longbow.Web.Mvc; using Longbow.Web.Mvc;
using PetaPoco; using PetaPoco;
using System; using System;
@ -50,8 +50,8 @@ namespace Bootstrap.DataAccess
/// </summary> /// </summary>
public string Result { get; set; } public string Result { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string UserAgent { get; set; } public string UserAgent { get; set; }
@ -72,6 +72,6 @@ namespace Bootstrap.DataAccess
/// </summary> /// </summary>
/// <param name="po"></param> /// <param name="po"></param>
/// <returns></returns> /// <returns></returns>
public virtual Page<LoginUser> Retrieves(PaginationOption po) => DbManager.Create().Page<LoginUser>(po.PageIndex, po.Limit, "select UserName, LoginTime, Ip, Browser, OS, City, Result from LoginLogs Order by LoginTime desc"); public virtual Page<LoginUser> Retrieves(PaginationOption po) => DbManager.Create().Page<LoginUser>(po.PageIndex, po.Limit, "select UserName, LoginTime, Ip, Browser, OS, City, Result from LoginLogs Order by LoginTime desc");
} }
} }

View File

@ -1,158 +1,158 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class Message public class Message
{ {
/// <summary> /// <summary>
/// 消息主键 数据库自增 /// 消息主键 数据库自增
/// </summary> /// </summary>
public string Id { get; set; } public string Id { get; set; }
/// <summary> /// <summary>
/// 标题 /// 标题
/// </summary> /// </summary>
public string Title { get; set; } public string Title { get; set; }
/// <summary> /// <summary>
/// 内容 /// 内容
/// </summary> /// </summary>
public string Content { get; set; } public string Content { get; set; }
/// <summary> /// <summary>
/// 发消息人 /// 发消息人
/// </summary> /// </summary>
public string From { get; set; } public string From { get; set; }
/// <summary> /// <summary>
/// 收消息人 /// 收消息人
/// </summary> /// </summary>
public string To { get; set; } public string To { get; set; }
/// <summary> /// <summary>
/// 消息发送时间 /// 消息发送时间
/// </summary> /// </summary>
public DateTime SendTime { get; set; } public DateTime SendTime { get; set; }
/// <summary> /// <summary>
/// 消息状态0-未读1-已读 和Dict表的通知消息关联 /// 消息状态0-未读1-已读 和Dict表的通知消息关联
/// </summary> /// </summary>
public string Status { get; set; } public string Status { get; set; }
/// <summary> /// <summary>
/// 标旗状态0-未标旗1-已标旗 /// 标旗状态0-未标旗1-已标旗
/// </summary> /// </summary>
public int Mark { get; set; } public int Mark { get; set; }
/// <summary> /// <summary>
/// 删除状态0-未删除1-已删除 /// 删除状态0-未删除1-已删除
/// </summary> /// </summary>
public int IsDelete { get; set; } public int IsDelete { get; set; }
/// <summary> /// <summary>
/// 消息标签0-一般1-紧要 和Dict表的消息标签关联 /// 消息标签0-一般1-紧要 和Dict表的消息标签关联
/// </summary> /// </summary>
public string Label { get; set; } public string Label { get; set; }
/// <summary> /// <summary>
/// 获得/设置 标签名称 /// 获得/设置 标签名称
/// </summary> /// </summary>
public string LabelName { get; set; } public string LabelName { get; set; }
/// <summary> /// <summary>
/// 获得/设置 时间描述 2分钟内为刚刚 /// 获得/设置 时间描述 2分钟内为刚刚
/// </summary> /// </summary>
public string Period { get; set; } public string Period { get; set; }
/// <summary> /// <summary>
/// 获得/设置 发件人头像 /// 获得/设置 发件人头像
/// </summary> /// </summary>
public string FromIcon { get; set; } public string FromIcon { get; set; }
/// <summary> /// <summary>
/// 获得/设置 发件人昵称 /// 获得/设置 发件人昵称
/// </summary> /// </summary>
public string FromDisplayName { get; set; } public string FromDisplayName { get; set; }
//TODO: SQL语句不兼容 //TODO: SQL语句不兼容
/// <summary> /// <summary>
/// 所有有关userName所有消息列表 /// 所有有关userName所有消息列表
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <returns></returns> /// <returns></returns>
protected virtual IEnumerable<Message> Retrieves(string userName) protected virtual IEnumerable<Message> Retrieves(string userName)
{ {
var db = DbManager.Create(); var db = DbManager.Create();
var t = db.Provider.EscapeSqlIdentifier("To"); var t = db.Provider.EscapeSqlIdentifier("To");
var f = db.Provider.EscapeSqlIdentifier("From"); var f = db.Provider.EscapeSqlIdentifier("From");
return db.Fetch<Message>($"select m.*, d.Name, u.DisplayName from Messages m left join Dicts d on m.Label = d.Code and d.Category = @Category and d.Define = 0 inner join Users u on m.{f} = u.UserName where {t} = @UserName or {f} = @UserName order by SendTime desc", new { UserName = userName, Category = "消息标签" }); return db.Fetch<Message>($"select m.*, d.Name, u.DisplayName from Messages m left join Dicts d on m.Label = d.Code and d.Category = @Category and d.Define = 0 inner join Users u on m.{f} = u.UserName where {t} = @UserName or {f} = @UserName order by SendTime desc", new { UserName = userName, Category = "消息标签" });
} }
/// <summary> /// <summary>
/// 收件箱 /// 收件箱
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
public virtual IEnumerable<Message> Inbox(string userName) public virtual IEnumerable<Message> Inbox(string userName)
{ {
var messageRet = Retrieves(userName); var messageRet = Retrieves(userName);
return messageRet.Where(n => n.To.Equals(userName, StringComparison.OrdinalIgnoreCase)); return messageRet.Where(n => n.To.Equals(userName, StringComparison.OrdinalIgnoreCase));
} }
/// <summary> /// <summary>
/// 发件箱 /// 发件箱
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<Message> SendMail(string userName) public virtual IEnumerable<Message> SendMail(string userName)
{ {
var messageRet = Retrieves(userName); var messageRet = Retrieves(userName);
return messageRet.Where(n => n.From.Equals(userName, StringComparison.OrdinalIgnoreCase)); return messageRet.Where(n => n.From.Equals(userName, StringComparison.OrdinalIgnoreCase));
} }
/// <summary> /// <summary>
/// 垃圾箱 /// 垃圾箱
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<Message> Trash(string userName) public virtual IEnumerable<Message> Trash(string userName)
{ {
var messageRet = Retrieves(userName); var messageRet = Retrieves(userName);
return messageRet.Where(n => n.IsDelete == 1); return messageRet.Where(n => n.IsDelete == 1);
} }
/// <summary> /// <summary>
/// 标旗 /// 标旗
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<Message> Flag(string userName) public virtual IEnumerable<Message> Flag(string userName)
{ {
var messageRet = Retrieves(userName); var messageRet = Retrieves(userName);
return messageRet.Where(n => n.Mark == 1); return messageRet.Where(n => n.Mark == 1);
} }
/// <summary> /// <summary>
/// 获取Header处显示的消息列表 /// 获取Header处显示的消息列表
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<Message> RetrieveHeaders(string userName) public virtual IEnumerable<Message> RetrieveHeaders(string userName)
{ {
var messageRet = Inbox(userName); var messageRet = Inbox(userName);
messageRet.AsParallel().ForAll(n => messageRet.AsParallel().ForAll(n =>
{ {
var ts = DateTime.Now - n.SendTime; var ts = DateTime.Now - n.SendTime;
if (ts.TotalMinutes < 5) n.Period = "刚刚"; if (ts.TotalMinutes < 5) n.Period = "刚刚";
else if (ts.Days > 0) n.Period = string.Format("{0}天", ts.Days); else if (ts.Days > 0) n.Period = string.Format("{0}天", ts.Days);
else if (ts.Hours > 0) n.Period = string.Format("{0}小时", ts.Hours); else if (ts.Hours > 0) n.Period = string.Format("{0}小时", ts.Hours);
else if (ts.Minutes > 0) n.Period = string.Format("{0}分钟", ts.Minutes); else if (ts.Minutes > 0) n.Period = string.Format("{0}分钟", ts.Minutes);
}); });
return messageRet; return messageRet;
} }
} }
} }

View File

@ -1,197 +1,197 @@
using Bootstrap.Security.DataAccess; using Bootstrap.Security.DataAccess;
using Longbow.Data; using Longbow.Data;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class Role public class Role
{ {
/// <summary> /// <summary>
/// 获得/设置 角色主键ID /// 获得/设置 角色主键ID
/// </summary> /// </summary>
public string Id { get; set; } public string Id { get; set; }
/// <summary> /// <summary>
/// 获得/设置 角色名称 /// 获得/设置 角色名称
/// </summary> /// </summary>
public string RoleName { get; set; } public string RoleName { get; set; }
/// <summary> /// <summary>
/// 获得/设置 角色描述 /// 获得/设置 角色描述
/// </summary> /// </summary>
public string Description { get; set; } public string Description { get; set; }
/// <summary> /// <summary>
/// 获取/设置 用户角色关联状态 checked 标示已经关联 '' 标示未关联 /// 获取/设置 用户角色关联状态 checked 标示已经关联 '' 标示未关联
/// </summary> /// </summary>
public string Checked { get; set; } public string Checked { get; set; }
/// <summary> /// <summary>
/// 查询所有角色 /// 查询所有角色
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<Role> Retrieves() => DbManager.Create().Fetch<Role>(); public virtual IEnumerable<Role> Retrieves() => DbManager.Create().Fetch<Role>();
/// <summary> /// <summary>
/// 保存用户角色关系 /// 保存用户角色关系
/// </summary> /// </summary>
/// <param name="userId"></param> /// <param name="userId"></param>
/// <param name="roleIds"></param> /// <param name="roleIds"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool SaveByUserId(string userId, IEnumerable<string> roleIds) public virtual bool SaveByUserId(string userId, IEnumerable<string> roleIds)
{ {
var ret = false; var ret = false;
var db = DbManager.Create(); var db = DbManager.Create();
try try
{ {
db.BeginTransaction(); db.BeginTransaction();
// delete user from config table // delete user from config table
db.Execute("delete from UserRole where UserID = @0", userId); db.Execute("delete from UserRole where UserID = @0", userId);
db.InsertBatch("UserRole", roleIds.Select(g => new { UserID = userId, RoleID = g })); db.InsertBatch("UserRole", roleIds.Select(g => new { UserID = userId, RoleID = g }));
db.CompleteTransaction(); db.CompleteTransaction();
ret = true; ret = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw ex; throw ex;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// 查询某个用户所拥有的角色 /// 查询某个用户所拥有的角色
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<Role> RetrievesByUserId(string userId) => DbManager.Create().Fetch<Role>("select r.ID, r.RoleName, r.Description, case ur.RoleID when r.ID then 'checked' else '' end Checked from Roles r left join UserRole ur on r.ID = ur.RoleID and UserID = @0", userId); public virtual IEnumerable<Role> RetrievesByUserId(string userId) => DbManager.Create().Fetch<Role>("select r.ID, r.RoleName, r.Description, case ur.RoleID when r.ID then 'checked' else '' end Checked from Roles r left join UserRole ur on r.ID = ur.RoleID and UserID = @0", userId);
/// <summary> /// <summary>
/// 删除角色表 /// 删除角色表
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
public virtual bool Delete(IEnumerable<string> value) public virtual bool Delete(IEnumerable<string> value)
{ {
if (!value.Any()) return true; if (!value.Any()) return true;
bool ret = false; bool ret = false;
var ids = string.Join(",", value); var ids = string.Join(",", value);
var db = DbManager.Create(); var db = DbManager.Create();
try try
{ {
db.BeginTransaction(); db.BeginTransaction();
db.Execute($"delete from UserRole where RoleID in ({ids})"); db.Execute($"delete from UserRole where RoleID in ({ids})");
db.Execute($"delete from RoleGroup where RoleID in ({ids})"); db.Execute($"delete from RoleGroup where RoleID in ({ids})");
db.Execute($"delete from NavigationRole where RoleID in ({ids})"); db.Execute($"delete from NavigationRole where RoleID in ({ids})");
db.Execute($"delete from Roles where ID in ({ids})"); db.Execute($"delete from Roles where ID in ({ids})");
db.CompleteTransaction(); db.CompleteTransaction();
ret = true; ret = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw ex; throw ex;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// 保存新建/更新的角色信息 /// 保存新建/更新的角色信息
/// </summary> /// </summary>
/// <param name="p"></param> /// <param name="p"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool Save(Role p) public virtual bool Save(Role p)
{ {
if (!string.IsNullOrEmpty(p.RoleName) && p.RoleName.Length > 50) p.RoleName = p.RoleName.Substring(0, 50); if (!string.IsNullOrEmpty(p.RoleName) && p.RoleName.Length > 50) p.RoleName = p.RoleName.Substring(0, 50);
if (!string.IsNullOrEmpty(p.Description) && p.Description.Length > 50) p.Description = p.Description.Substring(0, 500); if (!string.IsNullOrEmpty(p.Description) && p.Description.Length > 50) p.Description = p.Description.Substring(0, 500);
DbManager.Create().Save(p); DbManager.Create().Save(p);
return true; return true;
} }
/// <summary> /// <summary>
/// 查询某个菜单所拥有的角色 /// 查询某个菜单所拥有的角色
/// </summary> /// </summary>
/// <param name="menuId"></param> /// <param name="menuId"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<Role> RetrievesByMenuId(string menuId) => DbManager.Create().Fetch<Role>("select r.ID, r.RoleName, r.Description, case ur.RoleID when r.ID then 'checked' else '' end Checked from Roles r left join NavigationRole ur on r.ID = ur.RoleID and NavigationID = @0", menuId); public virtual IEnumerable<Role> RetrievesByMenuId(string menuId) => DbManager.Create().Fetch<Role>("select r.ID, r.RoleName, r.Description, case ur.RoleID when r.ID then 'checked' else '' end Checked from Roles r left join NavigationRole ur on r.ID = ur.RoleID and NavigationID = @0", menuId);
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="menuId"></param> /// <param name="menuId"></param>
/// <param name="roleIds"></param> /// <param name="roleIds"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool SavaByMenuId(string menuId, IEnumerable<string> roleIds) public virtual bool SavaByMenuId(string menuId, IEnumerable<string> roleIds)
{ {
var ret = false; var ret = false;
var db = DbManager.Create(); var db = DbManager.Create();
db.BeginTransaction(); db.BeginTransaction();
try try
{ {
// delete role from config table // delete role from config table
db.Execute("delete from NavigationRole where NavigationID = @0", menuId); db.Execute("delete from NavigationRole where NavigationID = @0", menuId);
db.InsertBatch("NavigationRole", roleIds.Select(g => new { NavigationID = menuId, RoleID = g })); db.InsertBatch("NavigationRole", roleIds.Select(g => new { NavigationID = menuId, RoleID = g }));
db.CompleteTransaction(); db.CompleteTransaction();
ret = true; ret = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw ex; throw ex;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// 根据GroupId查询和该Group有关的所有Roles /// 根据GroupId查询和该Group有关的所有Roles
/// </summary> /// </summary>
/// <param name="groupId"></param> /// <param name="groupId"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<Role> RetrievesByGroupId(string groupId) => DbManager.Create().Fetch<Role>("select r.ID, r.RoleName, r.Description, case ur.RoleID when r.ID then 'checked' else '' end Checked from Roles r left join RoleGroup ur on r.ID = ur.RoleID and GroupID = @0", groupId); public virtual IEnumerable<Role> RetrievesByGroupId(string groupId) => DbManager.Create().Fetch<Role>("select r.ID, r.RoleName, r.Description, case ur.RoleID when r.ID then 'checked' else '' end Checked from Roles r left join RoleGroup ur on r.ID = ur.RoleID and GroupID = @0", groupId);
/// <summary> /// <summary>
/// 根据GroupId更新Roles信息删除旧的Roles信息插入新的Roles信息 /// 根据GroupId更新Roles信息删除旧的Roles信息插入新的Roles信息
/// </summary> /// </summary>
/// <param name="groupId"></param> /// <param name="groupId"></param>
/// <param name="roleIds"></param> /// <param name="roleIds"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool SaveByGroupId(string groupId, IEnumerable<string> roleIds) public virtual bool SaveByGroupId(string groupId, IEnumerable<string> roleIds)
{ {
var ret = false; var ret = false;
var db = DbManager.Create(); var db = DbManager.Create();
try try
{ {
// delete user from config table // delete user from config table
db.Execute("delete from RoleGroup where GroupID = @0", groupId); db.Execute("delete from RoleGroup where GroupID = @0", groupId);
db.InsertBatch("RoleGroup", roleIds.Select(g => new { GroupID = groupId, RoleID = g })); db.InsertBatch("RoleGroup", roleIds.Select(g => new { GroupID = groupId, RoleID = g }));
db.CompleteTransaction(); db.CompleteTransaction();
ret = true; ret = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw ex; throw ex;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<string> RetrieveRolesByUserName(string userName) => DbHelper.RetrieveRolesByUserName(userName); public virtual IEnumerable<string> RetrieveRolesByUserName(string userName) => DbHelper.RetrieveRolesByUserName(userName);
/// <summary> /// <summary>
/// 根据菜单url查询某个所拥有的角色 /// 根据菜单url查询某个所拥有的角色
/// 从NavigatorRole表查 /// 从NavigatorRole表查
/// 从Navigators-〉GroupNavigatorRole-〉Role查查询某个用户所拥有的角色 /// 从Navigators-〉GroupNavigatorRole-〉Role查查询某个用户所拥有的角色
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<string> RetrieveRolesByUrl(string url) => DbHelper.RetrieveRolesByUrl(url); public virtual IEnumerable<string> RetrieveRolesByUrl(string url) => DbHelper.RetrieveRolesByUrl(url);
} }
} }

View File

@ -1,57 +1,57 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class Task public class Task
{ {
/// <summary> /// <summary>
/// 获取/设置 任务ID /// 获取/设置 任务ID
/// </summary> /// </summary>
public string Id { get; set; } public string Id { get; set; }
/// <summary> /// <summary>
/// 获取/设置 任务名称 /// 获取/设置 任务名称
/// </summary> /// </summary>
public string TaskName { get; set; } public string TaskName { get; set; }
/// <summary> /// <summary>
/// 获取/设置 分配人 /// 获取/设置 分配人
/// </summary> /// </summary>
public string AssignName { get; set; } public string AssignName { get; set; }
/// <summary> /// <summary>
/// 获得/设置 分配人昵称 /// 获得/设置 分配人昵称
/// </summary> /// </summary>
public string AssignDisplayName { get; set; } public string AssignDisplayName { get; set; }
/// <summary> /// <summary>
/// 获取/设置 完成任务人 /// 获取/设置 完成任务人
/// </summary> /// </summary>
public string UserName { get; set; } public string UserName { get; set; }
/// <summary> /// <summary>
/// 获取/设置 任务所需时间(天) /// 获取/设置 任务所需时间(天)
/// </summary> /// </summary>
public int TaskTime { get; set; } public int TaskTime { get; set; }
/// <summary> /// <summary>
/// 获取/设置 任务进度 /// 获取/设置 任务进度
/// </summary> /// </summary>
public double TaskProgress { get; set; } public double TaskProgress { get; set; }
/// <summary> /// <summary>
/// 获取/设置 分配时间 /// 获取/设置 分配时间
/// </summary> /// </summary>
public DateTime AssignTime { get; set; } public DateTime AssignTime { get; set; }
/// <summary> /// <summary>
/// 查询所有任务 /// 查询所有任务
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<Task> Retrieves() => DbManager.Create().SkipTake<Task>(0, 1000, "select t.*, u.DisplayName AssignDisplayName from Tasks t inner join Users u on t.UserName = u.UserName order by AssignTime desc"); public virtual IEnumerable<Task> Retrieves() => DbManager.Create().SkipTake<Task>(0, 1000, "select t.*, u.DisplayName AssignDisplayName from Tasks t inner join Users u on t.UserName = u.UserName order by AssignTime desc");
} }
} }

View File

@ -49,8 +49,8 @@ namespace Bootstrap.DataAccess
/// </summary> /// </summary>
public string RequestUrl { get; set; } public string RequestUrl { get; set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public string UserAgent { get; set; } public string UserAgent { get; set; }

View File

@ -1,421 +1,421 @@
using Bootstrap.Security; using Bootstrap.Security;
using Bootstrap.Security.DataAccess; using Bootstrap.Security.DataAccess;
using Longbow.Data; using Longbow.Data;
using Longbow.Security.Cryptography; using Longbow.Security.Cryptography;
using PetaPoco; using PetaPoco;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>
/// 用户表实体类 /// 用户表实体类
/// </summary> /// </summary>
public class User : BootstrapUser public class User : BootstrapUser
{ {
/// <summary> /// <summary>
/// 获得/设置 用户主键ID /// 获得/设置 用户主键ID
/// </summary> /// </summary>
public string Id { get; set; } public string Id { get; set; }
/// <summary> /// <summary>
/// 获取/设置 密码 /// 获取/设置 密码
/// </summary> /// </summary>
public string Password { get; set; } public string Password { get; set; }
/// <summary> /// <summary>
/// 获取/设置 密码盐 /// 获取/设置 密码盐
/// </summary> /// </summary>
public string PassSalt { get; set; } public string PassSalt { get; set; }
/// <summary> /// <summary>
/// 获取/设置 角色用户关联状态 checked 标示已经关联 '' 标示未关联 /// 获取/设置 角色用户关联状态 checked 标示已经关联 '' 标示未关联
/// </summary> /// </summary>
public string Checked { get; set; } public string Checked { get; set; }
/// <summary> /// <summary>
/// 获得/设置 用户注册时间 /// 获得/设置 用户注册时间
/// </summary> /// </summary>
public DateTime RegisterTime { get; set; } public DateTime RegisterTime { get; set; }
/// <summary> /// <summary>
/// 获得/设置 用户被批复时间 /// 获得/设置 用户被批复时间
/// </summary> /// </summary>
public DateTime? ApprovedTime { get; set; } public DateTime? ApprovedTime { get; set; }
/// <summary> /// <summary>
/// 获得/设置 用户批复人 /// 获得/设置 用户批复人
/// </summary> /// </summary>
public string ApprovedBy { get; set; } public string ApprovedBy { get; set; }
/// <summary> /// <summary>
/// 获得/设置 用户的申请理由 /// 获得/设置 用户的申请理由
/// </summary> /// </summary>
public string Description { get; set; } public string Description { get; set; }
/// <summary> /// <summary>
/// 获得/设置 用户当前状态 0 表示管理员注册用户 1 表示用户注册 2 表示更改密码 3 表示更改个人皮肤 4 表示更改显示名称 5 批复新用户注册操作 /// 获得/设置 用户当前状态 0 表示管理员注册用户 1 表示用户注册 2 表示更改密码 3 表示更改个人皮肤 4 表示更改显示名称 5 批复新用户注册操作
/// </summary> /// </summary>
public UserStates UserStatus { get; set; } public UserStates UserStatus { get; set; }
/// <summary> /// <summary>
/// 获得/设置 通知描述 2分钟内为刚刚 /// 获得/设置 通知描述 2分钟内为刚刚
/// </summary> /// </summary>
public string Period { get; set; } public string Period { get; set; }
/// <summary> /// <summary>
/// 获得/设置 新密码 /// 获得/设置 新密码
/// </summary> /// </summary>
public string NewPassword { get; set; } public string NewPassword { get; set; }
/// <summary> /// <summary>
/// 获得/设置 是否重置密码 /// 获得/设置 是否重置密码
/// </summary> /// </summary>
[Ignore] [Ignore]
public int IsReset { get; set; } public int IsReset { get; set; }
/// <summary> /// <summary>
/// 验证用户登陆账号与密码正确 /// 验证用户登陆账号与密码正确
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <param name="password"></param> /// <param name="password"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool Authenticate(string userName, string password) public virtual bool Authenticate(string userName, string password)
{ {
var user = DbManager.Create().SingleOrDefault<User>("select Password, PassSalt from Users where ApprovedTime is not null and UserName = @0", userName); var user = DbManager.Create().SingleOrDefault<User>("select Password, PassSalt from Users where ApprovedTime is not null and UserName = @0", userName);
return user != null && !string.IsNullOrEmpty(user.PassSalt) && user.Password == LgbCryptography.ComputeHash(password, user.PassSalt); return user != null && !string.IsNullOrEmpty(user.PassSalt) && user.Password == LgbCryptography.ComputeHash(password, user.PassSalt);
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <param name="app"></param> /// <param name="app"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool SaveApp(string userName, string app) => DbManager.Create().Update<User>("set App = @1 where UserName = @0", userName, app) == 1; public virtual bool SaveApp(string userName, string app) => DbManager.Create().Update<User>("set App = @1 where UserName = @0", userName, app) == 1;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <param name="password"></param> /// <param name="password"></param>
/// <param name="newPass"></param> /// <param name="newPass"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool ChangePassword(string userName, string password, string newPass) public virtual bool ChangePassword(string userName, string password, string newPass)
{ {
bool ret = false; bool ret = false;
if (Authenticate(userName, password)) if (Authenticate(userName, password))
{ {
string sql = "set Password = @0, PassSalt = @1 where UserName = @2"; string sql = "set Password = @0, PassSalt = @1 where UserName = @2";
var passSalt = LgbCryptography.GenerateSalt(); var passSalt = LgbCryptography.GenerateSalt();
var newPassword = LgbCryptography.ComputeHash(newPass, passSalt); var newPassword = LgbCryptography.ComputeHash(newPass, passSalt);
ret = DbManager.Create().Update<User>(sql, newPassword, passSalt, userName) == 1; ret = DbManager.Create().Update<User>(sql, newPassword, passSalt, userName) == 1;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// 查询所有用户 /// 查询所有用户
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<User> Retrieves() => DbManager.Create().Fetch<User>("select u.ID, u.UserName, u.DisplayName, RegisterTime, ApprovedTime, ApprovedBy, Description, ru.IsReset from Users u left join (select 1 as IsReset, UserName from ResetUsers group by UserName) ru on u.UserName = ru.UserName Where ApprovedTime is not null"); public virtual IEnumerable<User> Retrieves() => DbManager.Create().Fetch<User>("select u.ID, u.UserName, u.DisplayName, RegisterTime, ApprovedTime, ApprovedBy, Description, ru.IsReset from Users u left join (select 1 as IsReset, UserName from ResetUsers group by UserName) ru on u.UserName = ru.UserName Where ApprovedTime is not null");
/// <summary> /// <summary>
/// 查询所有的新注册用户 /// 查询所有的新注册用户
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<User> RetrieveNewUsers() => DbManager.Create().Fetch<User>("select ID, UserName, DisplayName, RegisterTime, Description from Users Where ApprovedTime is null order by RegisterTime desc"); public virtual IEnumerable<User> RetrieveNewUsers() => DbManager.Create().Fetch<User>("select ID, UserName, DisplayName, RegisterTime, Description from Users Where ApprovedTime is null order by RegisterTime desc");
/// <summary> /// <summary>
/// 删除用户 /// 删除用户
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
public virtual bool Delete(IEnumerable<string> value) public virtual bool Delete(IEnumerable<string> value)
{ {
if (!value.Any()) return true; if (!value.Any()) return true;
bool ret = false; bool ret = false;
var db = DbManager.Create(); var db = DbManager.Create();
try try
{ {
var ids = string.Join(",", value); var ids = string.Join(",", value);
db.BeginTransaction(); db.BeginTransaction();
db.Execute($"Delete from UserRole where UserID in ({ids})"); db.Execute($"Delete from UserRole where UserID in ({ids})");
db.Execute($"delete from UserGroup where UserID in ({ids})"); db.Execute($"delete from UserGroup where UserID in ({ids})");
db.Execute($"delete from Users where ID in ({ids})"); db.Execute($"delete from Users where ID in ({ids})");
db.CompleteTransaction(); db.CompleteTransaction();
ret = true; ret = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw ex; throw ex;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <param name="password"></param> /// <param name="password"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool ResetPassword(string userName, string password) public virtual bool ResetPassword(string userName, string password)
{ {
var ret = false; var ret = false;
var resetUser = UserHelper.RetrieveResetUserByUserName(userName); var resetUser = UserHelper.RetrieveResetUserByUserName(userName);
if (resetUser == null) return ret; if (resetUser == null) return ret;
string sql = "set Password = @0, PassSalt = @1 where UserName = @2"; string sql = "set Password = @0, PassSalt = @1 where UserName = @2";
var passSalt = LgbCryptography.GenerateSalt(); var passSalt = LgbCryptography.GenerateSalt();
var newPassword = LgbCryptography.ComputeHash(password, passSalt); var newPassword = LgbCryptography.ComputeHash(password, passSalt);
var db = DbManager.Create(); var db = DbManager.Create();
try try
{ {
db.BeginTransaction(); db.BeginTransaction();
ret = db.Update<User>(sql, newPassword, passSalt, userName) == 1; ret = db.Update<User>(sql, newPassword, passSalt, userName) == 1;
if (ret) db.Execute("delete from ResetUsers where UserName = @0", userName); if (ret) db.Execute("delete from ResetUsers where UserName = @0", userName);
db.CompleteTransaction(); db.CompleteTransaction();
} }
catch (Exception ex) catch (Exception ex)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw ex; throw ex;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="user"></param> /// <param name="user"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool ForgotPassword(ResetUser user) public virtual bool ForgotPassword(ResetUser user)
{ {
user.ResetTime = DateTime.Now; user.ResetTime = DateTime.Now;
return user.Save(); return user.Save();
} }
/// <summary> /// <summary>
/// 新建前台User View调用/注册用户调用 /// 新建前台User View调用/注册用户调用
/// </summary> /// </summary>
/// <param name="user"></param> /// <param name="user"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool Save(User user) public virtual bool Save(User user)
{ {
var ret = false; var ret = false;
user.PassSalt = LgbCryptography.GenerateSalt(); user.PassSalt = LgbCryptography.GenerateSalt();
user.Password = LgbCryptography.ComputeHash(user.Password, user.PassSalt); user.Password = LgbCryptography.ComputeHash(user.Password, user.PassSalt);
user.RegisterTime = DateTime.Now; user.RegisterTime = DateTime.Now;
var db = DbManager.Create(); var db = DbManager.Create();
try try
{ {
db.BeginTransaction(); db.BeginTransaction();
if (!db.Exists<User>("where UserName = @0", user.UserName)) if (!db.Exists<User>("where UserName = @0", user.UserName))
{ {
db.Insert(user); db.Insert(user);
db.Execute("insert into UserRole (UserID, RoleID) select ID, (select ID from Roles where RoleName = 'Default') RoleId from Users where UserName = @0", user.UserName); db.Execute("insert into UserRole (UserID, RoleID) select ID, (select ID from Roles where RoleName = 'Default') RoleId from Users where UserName = @0", user.UserName);
} }
db.CompleteTransaction(); db.CompleteTransaction();
ret = true; ret = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw ex; throw ex;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// User List 视图保存按钮调用 /// User List 视图保存按钮调用
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
/// <param name="password"></param> /// <param name="password"></param>
/// <param name="displayName"></param> /// <param name="displayName"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool Update(string id, string password, string displayName) public virtual bool Update(string id, string password, string displayName)
{ {
var passSalt = LgbCryptography.GenerateSalt(); var passSalt = LgbCryptography.GenerateSalt();
var newPassword = LgbCryptography.ComputeHash(password, passSalt); var newPassword = LgbCryptography.ComputeHash(password, passSalt);
return DbManager.Create().Update<User>("set Password = @1, PassSalt = @2, DisplayName = @3 where ID = @0", id, newPassword, passSalt, displayName) == 1; return DbManager.Create().Update<User>("set Password = @1, PassSalt = @2, DisplayName = @3 where ID = @0", id, newPassword, passSalt, displayName) == 1;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
/// <param name="approvedBy"></param> /// <param name="approvedBy"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool Approve(string id, string approvedBy) => DbManager.Create().Update<User>("set ApprovedTime = @1, ApprovedBy = @2 where ID = @0", id, DateTime.Now, approvedBy) == 1; public virtual bool Approve(string id, string approvedBy) => DbManager.Create().Update<User>("set ApprovedTime = @1, ApprovedBy = @2 where ID = @0", id, DateTime.Now, approvedBy) == 1;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
/// <param name="rejectBy"></param> /// <param name="rejectBy"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool Reject(string id, string rejectBy) public virtual bool Reject(string id, string rejectBy)
{ {
var ret = false; var ret = false;
var db = DbManager.Create(); var db = DbManager.Create();
try try
{ {
db.BeginTransaction(); db.BeginTransaction();
db.Execute("insert into RejectUsers (UserName, DisplayName, RegisterTime, RejectedBy, RejectedTime, RejectedReason) select UserName, DisplayName, Registertime, @1, @2, @3 from Users where ID = @0", id, rejectBy, DateTime.Now, "未填写"); db.Execute("insert into RejectUsers (UserName, DisplayName, RegisterTime, RejectedBy, RejectedTime, RejectedReason) select UserName, DisplayName, Registertime, @1, @2, @3 from Users where ID = @0", id, rejectBy, DateTime.Now, "未填写");
db.Execute("delete from UserRole where UserId = @0", id); db.Execute("delete from UserRole where UserId = @0", id);
db.Execute("delete from UserGroup where UserId = @0", id); db.Execute("delete from UserGroup where UserId = @0", id);
db.Execute("delete from users where ID = @0", id); db.Execute("delete from users where ID = @0", id);
db.CompleteTransaction(); db.CompleteTransaction();
ret = true; ret = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw ex; throw ex;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// 通过roleId获取所有用户 /// 通过roleId获取所有用户
/// </summary> /// </summary>
/// <param name="roleId"></param> /// <param name="roleId"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<User> RetrievesByRoleId(string roleId) => DbManager.Create().Fetch<User>("select u.ID, u.UserName, u.DisplayName, case ur.UserID when u.ID then 'checked' else '' end Checked from Users u left join UserRole ur on u.ID = ur.UserID and RoleID = @0 where u.ApprovedTime is not null", roleId); public virtual IEnumerable<User> RetrievesByRoleId(string roleId) => DbManager.Create().Fetch<User>("select u.ID, u.UserName, u.DisplayName, case ur.UserID when u.ID then 'checked' else '' end Checked from Users u left join UserRole ur on u.ID = ur.UserID and RoleID = @0 where u.ApprovedTime is not null", roleId);
/// <summary> /// <summary>
/// 通过角色ID保存当前授权用户插入 /// 通过角色ID保存当前授权用户插入
/// </summary> /// </summary>
/// <param name="roleId">角色ID</param> /// <param name="roleId">角色ID</param>
/// <param name="userIds">用户ID数组</param> /// <param name="userIds">用户ID数组</param>
/// <returns></returns> /// <returns></returns>
public virtual bool SaveByRoleId(string roleId, IEnumerable<string> userIds) public virtual bool SaveByRoleId(string roleId, IEnumerable<string> userIds)
{ {
bool ret = false; bool ret = false;
var db = DbManager.Create(); var db = DbManager.Create();
try try
{ {
db.BeginTransaction(); db.BeginTransaction();
//删除用户角色表该角色所有的用户 //删除用户角色表该角色所有的用户
db.Execute("delete from UserRole where RoleID = @0", roleId); db.Execute("delete from UserRole where RoleID = @0", roleId);
db.InsertBatch("UserRole", userIds.Select(g => new { UserID = g, RoleID = roleId })); db.InsertBatch("UserRole", userIds.Select(g => new { UserID = g, RoleID = roleId }));
db.CompleteTransaction(); db.CompleteTransaction();
ret = true; ret = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw ex; throw ex;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// 通过groupId获取所有用户 /// 通过groupId获取所有用户
/// </summary> /// </summary>
/// <param name="groupId"></param> /// <param name="groupId"></param>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<User> RetrievesByGroupId(string groupId) => DbManager.Create().Fetch<User>("select u.ID, u.UserName, u.DisplayName, case ur.UserID when u.ID then 'checked' else '' end Checked from Users u left join UserGroup ur on u.ID = ur.UserID and GroupID = @0 where u.ApprovedTime is not null", groupId); public virtual IEnumerable<User> RetrievesByGroupId(string groupId) => DbManager.Create().Fetch<User>("select u.ID, u.UserName, u.DisplayName, case ur.UserID when u.ID then 'checked' else '' end Checked from Users u left join UserGroup ur on u.ID = ur.UserID and GroupID = @0 where u.ApprovedTime is not null", groupId);
/// <summary> /// <summary>
/// 通过部门ID保存当前授权用户插入 /// 通过部门ID保存当前授权用户插入
/// </summary> /// </summary>
/// <param name="groupId">GroupID</param> /// <param name="groupId">GroupID</param>
/// <param name="userIds">用户ID数组</param> /// <param name="userIds">用户ID数组</param>
/// <returns></returns> /// <returns></returns>
public virtual bool SaveByGroupId(string groupId, IEnumerable<string> userIds) public virtual bool SaveByGroupId(string groupId, IEnumerable<string> userIds)
{ {
bool ret = false; bool ret = false;
var db = DbManager.Create(); var db = DbManager.Create();
try try
{ {
db.BeginTransaction(); db.BeginTransaction();
//删除用户角色表该角色所有的用户 //删除用户角色表该角色所有的用户
db.Execute("delete from UserGroup where GroupID = @0", groupId); db.Execute("delete from UserGroup where GroupID = @0", groupId);
db.InsertBatch("UserGroup", userIds.Select(g => new { UserID = g, GroupID = groupId })); db.InsertBatch("UserGroup", userIds.Select(g => new { UserID = g, GroupID = groupId }));
db.CompleteTransaction(); db.CompleteTransaction();
ret = true; ret = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
db.AbortTransaction(); db.AbortTransaction();
throw ex; throw ex;
} }
return ret; return ret;
} }
/// <summary> /// <summary>
/// 根据用户名修改用户头像 /// 根据用户名修改用户头像
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <param name="iconName"></param> /// <param name="iconName"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool SaveUserIconByName(string userName, string iconName) => DbManager.Create().Update<User>("set Icon = @1 where UserName = @0", userName, iconName) == 1; public virtual bool SaveUserIconByName(string userName, string iconName) => DbManager.Create().Update<User>("set Icon = @1 where UserName = @0", userName, iconName) == 1;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <param name="displayName"></param> /// <param name="displayName"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool SaveDisplayName(string userName, string displayName) => DbManager.Create().Update<User>("set DisplayName = @1 where UserName = @0", userName, displayName) == 1; public virtual bool SaveDisplayName(string userName, string displayName) => DbManager.Create().Update<User>("set DisplayName = @1 where UserName = @0", userName, displayName) == 1;
/// <summary> /// <summary>
/// 根据用户名更改用户皮肤 /// 根据用户名更改用户皮肤
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <param name="cssName"></param> /// <param name="cssName"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool SaveUserCssByName(string userName, string cssName) => DbManager.Create().Update<User>("set Css = @1 where UserName = @0", userName, cssName) == 1; public virtual bool SaveUserCssByName(string userName, string cssName) => DbManager.Create().Update<User>("set Css = @1 where UserName = @0", userName, cssName) == 1;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="userName"></param> /// <param name="userName"></param>
/// <returns></returns> /// <returns></returns>
public virtual BootstrapUser RetrieveUserByUserName(string userName) => DbHelper.RetrieveUserByUserName(userName); public virtual BootstrapUser RetrieveUserByUserName(string userName) => DbHelper.RetrieveUserByUserName(userName);
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public override string ToString() public override string ToString()
{ {
return string.Format("{0} ({1})", UserName, DisplayName); return string.Format("{0} ({1})", UserName, DisplayName);
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public enum UserStates public enum UserStates
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
ChangePassword, ChangePassword,
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
ChangeTheme, ChangeTheme,
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
ChangeDisplayName, ChangeDisplayName,
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
ApproveUser, ApproveUser,
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
RejectUser, RejectUser,
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
SaveApp SaveApp
} }
} }

View File

@ -1,104 +1,104 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 16
VisualStudioVersion = 16.0.28407.52 VisualStudioVersion = 16.0.28407.52
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SQLServer", "SQLServer", "{87319AF5-7C40-4362-B67C-35F9DD737DB4}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SQLServer", "SQLServer", "{87319AF5-7C40-4362-B67C-35F9DD737DB4}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
DatabaseScripts\InitData.sql = DatabaseScripts\InitData.sql DatabaseScripts\InitData.sql = DatabaseScripts\InitData.sql
DatabaseScripts\Install.sql = DatabaseScripts\Install.sql DatabaseScripts\Install.sql = DatabaseScripts\Install.sql
EndProjectSection EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Admin", "Bootstrap.Admin\Bootstrap.Admin.csproj", "{7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Admin", "Bootstrap.Admin\Bootstrap.Admin.csproj", "{7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{792A0B12-3F41-4BC4-A768-7D8D91C213B2}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{792A0B12-3F41-4BC4-A768-7D8D91C213B2}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
README.md = README.md README.md = README.md
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{586410F2-C1F0-47CD-AB28-2CF506DED2C8}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{586410F2-C1F0-47CD-AB28-2CF506DED2C8}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
Scripts\Longbow.lic = Scripts\Longbow.lic Scripts\Longbow.lic = Scripts\Longbow.lic
EndProjectSection EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client", "Bootstrap.Client\Bootstrap.Client.csproj", "{C82A6E45-AB90-43D1-8429-5CBE953D8151}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client", "Bootstrap.Client\Bootstrap.Client.csproj", "{C82A6E45-AB90-43D1-8429-5CBE953D8151}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client.DataAccess", "Bootstrap.Client.DataAccess\Bootstrap.Client.DataAccess.csproj", "{B6B29DE5-D7B0-4A4D-9E7A-AADC68E9C43F}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.Client.DataAccess", "Bootstrap.Client.DataAccess\Bootstrap.Client.DataAccess.csproj", "{B6B29DE5-D7B0-4A4D-9E7A-AADC68E9C43F}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.DataAccess", "Bootstrap.DataAccess\Bootstrap.DataAccess.csproj", "{8D62BE79-BE13-43C8-969B-C9B00B3C84B7}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.DataAccess", "Bootstrap.DataAccess\Bootstrap.DataAccess.csproj", "{8D62BE79-BE13-43C8-969B-C9B00B3C84B7}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SQLite", "SQLite", "{523515EC-2AD7-4282-9AF4-9D20371183B0}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SQLite", "SQLite", "{523515EC-2AD7-4282-9AF4-9D20371183B0}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
DatabaseScripts\SQLite\InitData.sql = DatabaseScripts\SQLite\InitData.sql DatabaseScripts\SQLite\InitData.sql = DatabaseScripts\SQLite\InitData.sql
DatabaseScripts\SQLite\Install.sql = DatabaseScripts\SQLite\Install.sql DatabaseScripts\SQLite\Install.sql = DatabaseScripts\SQLite\Install.sql
EndProjectSection EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.DataAccess.MongoDB", "Bootstrap.DataAccess.MongoDB\Bootstrap.DataAccess.MongoDB.csproj", "{8336F096-4B4A-4710-A1FA-0F5E44CD8D26}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bootstrap.DataAccess.MongoDB", "Bootstrap.DataAccess.MongoDB\Bootstrap.DataAccess.MongoDB.csproj", "{8336F096-4B4A-4710-A1FA-0F5E44CD8D26}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MongoDB", "MongoDB", "{A06A0AD8-A246-4329-B024-7174AE4A3EDE}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MongoDB", "MongoDB", "{A06A0AD8-A246-4329-B024-7174AE4A3EDE}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
DatabaseScripts\MongoDB\BootstrapAdmin.Dicts.json = DatabaseScripts\MongoDB\BootstrapAdmin.Dicts.json DatabaseScripts\MongoDB\BootstrapAdmin.Dicts.json = DatabaseScripts\MongoDB\BootstrapAdmin.Dicts.json
DatabaseScripts\MongoDB\BootstrapAdmin.Groups.json = DatabaseScripts\MongoDB\BootstrapAdmin.Groups.json DatabaseScripts\MongoDB\BootstrapAdmin.Groups.json = DatabaseScripts\MongoDB\BootstrapAdmin.Groups.json
DatabaseScripts\MongoDB\BootstrapAdmin.Navigations.json = DatabaseScripts\MongoDB\BootstrapAdmin.Navigations.json DatabaseScripts\MongoDB\BootstrapAdmin.Navigations.json = DatabaseScripts\MongoDB\BootstrapAdmin.Navigations.json
DatabaseScripts\MongoDB\BootstrapAdmin.Roles.json = DatabaseScripts\MongoDB\BootstrapAdmin.Roles.json DatabaseScripts\MongoDB\BootstrapAdmin.Roles.json = DatabaseScripts\MongoDB\BootstrapAdmin.Roles.json
DatabaseScripts\MongoDB\BootstrapAdmin.Users.json = DatabaseScripts\MongoDB\BootstrapAdmin.Users.json DatabaseScripts\MongoDB\BootstrapAdmin.Users.json = DatabaseScripts\MongoDB\BootstrapAdmin.Users.json
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MySQL", "MySQL", "{084E2E94-6B7D-4D3E-9BF1-6972427FBF80}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MySQL", "MySQL", "{084E2E94-6B7D-4D3E-9BF1-6972427FBF80}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
DatabaseScripts\MySQL\initData.sql = DatabaseScripts\MySQL\initData.sql DatabaseScripts\MySQL\initData.sql = DatabaseScripts\MySQL\initData.sql
DatabaseScripts\MySQL\install.sql = DatabaseScripts\MySQL\install.sql DatabaseScripts\MySQL\install.sql = DatabaseScripts\MySQL\install.sql
EndProjectSection EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "UnitTest\UnitTest.csproj", "{CFE75C48-F9D5-403A-8419-D07939BBD769}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "UnitTest\UnitTest.csproj", "{CFE75C48-F9D5-403A-8419-D07939BBD769}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Postgresql", "Postgresql", "{6F61C2AC-84D4-48A9-8A48-680657CC8175}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Postgresql", "Postgresql", "{6F61C2AC-84D4-48A9-8A48-680657CC8175}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
DatabaseScripts\Postgresql\initData.sql = DatabaseScripts\Postgresql\initData.sql DatabaseScripts\Postgresql\initData.sql = DatabaseScripts\Postgresql\initData.sql
DatabaseScripts\Postgresql\install.sql = DatabaseScripts\Postgresql\install.sql DatabaseScripts\Postgresql\install.sql = DatabaseScripts\Postgresql\install.sql
EndProjectSection EndProjectSection
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A}.Release|Any CPU.ActiveCfg = Release|Any CPU {7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A}.Release|Any CPU.Build.0 = Release|Any CPU {7B2B7043-3CB2-4C5A-BDF2-8C47F1A5471A}.Release|Any CPU.Build.0 = Release|Any CPU
{C82A6E45-AB90-43D1-8429-5CBE953D8151}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C82A6E45-AB90-43D1-8429-5CBE953D8151}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C82A6E45-AB90-43D1-8429-5CBE953D8151}.Debug|Any CPU.Build.0 = Debug|Any CPU {C82A6E45-AB90-43D1-8429-5CBE953D8151}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C82A6E45-AB90-43D1-8429-5CBE953D8151}.Release|Any CPU.ActiveCfg = Release|Any CPU {C82A6E45-AB90-43D1-8429-5CBE953D8151}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C82A6E45-AB90-43D1-8429-5CBE953D8151}.Release|Any CPU.Build.0 = Release|Any CPU {C82A6E45-AB90-43D1-8429-5CBE953D8151}.Release|Any CPU.Build.0 = Release|Any CPU
{B6B29DE5-D7B0-4A4D-9E7A-AADC68E9C43F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B6B29DE5-D7B0-4A4D-9E7A-AADC68E9C43F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6B29DE5-D7B0-4A4D-9E7A-AADC68E9C43F}.Debug|Any CPU.Build.0 = Debug|Any CPU {B6B29DE5-D7B0-4A4D-9E7A-AADC68E9C43F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6B29DE5-D7B0-4A4D-9E7A-AADC68E9C43F}.Release|Any CPU.ActiveCfg = Release|Any CPU {B6B29DE5-D7B0-4A4D-9E7A-AADC68E9C43F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6B29DE5-D7B0-4A4D-9E7A-AADC68E9C43F}.Release|Any CPU.Build.0 = Release|Any CPU {B6B29DE5-D7B0-4A4D-9E7A-AADC68E9C43F}.Release|Any CPU.Build.0 = Release|Any CPU
{8D62BE79-BE13-43C8-969B-C9B00B3C84B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8D62BE79-BE13-43C8-969B-C9B00B3C84B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8D62BE79-BE13-43C8-969B-C9B00B3C84B7}.Debug|Any CPU.Build.0 = Debug|Any CPU {8D62BE79-BE13-43C8-969B-C9B00B3C84B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8D62BE79-BE13-43C8-969B-C9B00B3C84B7}.Release|Any CPU.ActiveCfg = Release|Any CPU {8D62BE79-BE13-43C8-969B-C9B00B3C84B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8D62BE79-BE13-43C8-969B-C9B00B3C84B7}.Release|Any CPU.Build.0 = Release|Any CPU {8D62BE79-BE13-43C8-969B-C9B00B3C84B7}.Release|Any CPU.Build.0 = Release|Any CPU
{8336F096-4B4A-4710-A1FA-0F5E44CD8D26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8336F096-4B4A-4710-A1FA-0F5E44CD8D26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8336F096-4B4A-4710-A1FA-0F5E44CD8D26}.Debug|Any CPU.Build.0 = Debug|Any CPU {8336F096-4B4A-4710-A1FA-0F5E44CD8D26}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8336F096-4B4A-4710-A1FA-0F5E44CD8D26}.Release|Any CPU.ActiveCfg = Release|Any CPU {8336F096-4B4A-4710-A1FA-0F5E44CD8D26}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8336F096-4B4A-4710-A1FA-0F5E44CD8D26}.Release|Any CPU.Build.0 = Release|Any CPU {8336F096-4B4A-4710-A1FA-0F5E44CD8D26}.Release|Any CPU.Build.0 = Release|Any CPU
{CFE75C48-F9D5-403A-8419-D07939BBD769}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CFE75C48-F9D5-403A-8419-D07939BBD769}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CFE75C48-F9D5-403A-8419-D07939BBD769}.Debug|Any CPU.Build.0 = Debug|Any CPU {CFE75C48-F9D5-403A-8419-D07939BBD769}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CFE75C48-F9D5-403A-8419-D07939BBD769}.Release|Any CPU.ActiveCfg = Release|Any CPU {CFE75C48-F9D5-403A-8419-D07939BBD769}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CFE75C48-F9D5-403A-8419-D07939BBD769}.Release|Any CPU.Build.0 = Release|Any CPU {CFE75C48-F9D5-403A-8419-D07939BBD769}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{C82A6E45-AB90-43D1-8429-5CBE953D8151} = {C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0} {C82A6E45-AB90-43D1-8429-5CBE953D8151} = {C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0}
{B6B29DE5-D7B0-4A4D-9E7A-AADC68E9C43F} = {C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0} {B6B29DE5-D7B0-4A4D-9E7A-AADC68E9C43F} = {C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {221EAE38-5F75-4391-9A48-E462A9F3B8FC} SolutionGuid = {221EAE38-5F75-4391-9A48-E462A9F3B8FC}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

File diff suppressed because it is too large Load Diff

248
README.md
View File

@ -1,124 +1,124 @@
# BootstrapAdmin # BootstrapAdmin
## 项目介绍 ## 项目介绍
一直需要一款后台管理系统,但是网上很多开源项目都是 **Java** 开发的,本人是 **NET** 平台的对 **Java** 一窍不通C#版本的本来就少而且还没有合适的。于是决定自己开发一套后台管理系统。由于前台采用 **Bootstrap** 布局样式,所以就叫做 **BootstrapAdmin** 。本系统可以用于所有的 Web 应用程序,目前版本已经升级到 **NET CORE** 具备跨平台能力。数据库方面同时支持多种数据库,详细列表见后面**数据库**的详细列表切换数据源仅需更改配置文件无需重启应用程序配置简单灵活。UI 前端使用流行的 Bootstrap 框架布局对移动设备的兼容性非常好,自适应目前市场几乎所有终端设备。本系统还具备单一后台支持多前台的特色,提供 **单点登录SSO** 的能力。 一直需要一款后台管理系统,但是网上很多开源项目都是 **Java** 开发的,本人是 **NET** 平台的对 **Java** 一窍不通C#版本的本来就少而且还没有合适的。于是决定自己开发一套后台管理系统。由于前台采用 **Bootstrap** 布局样式,所以就叫做 **BootstrapAdmin** 。本系统可以用于所有的 Web 应用程序,目前版本已经升级到 **NET CORE** 具备跨平台能力。数据库方面同时支持多种数据库,详细列表见后面**数据库**的详细列表切换数据源仅需更改配置文件无需重启应用程序配置简单灵活。UI 前端使用流行的 Bootstrap 框架布局对移动设备的兼容性非常好,自适应目前市场几乎所有终端设备。本系统还具备单一后台支持多前台的特色,提供 **单点登录SSO** 的能力。
使用 HTML 5 + jQuery + NET Core 2.2 + Bootstrap 4.1 + PetaPoco 构建的后台管理平台 使用 HTML 5 + jQuery + NET Core 2.2 + Bootstrap 4.1 + PetaPoco 构建的后台管理平台
### 主要功能 ### 主要功能
1. 通过配置与前台网站集成 1. 通过配置与前台网站集成
2. 构建前台系统分层级菜单 2. 构建前台系统分层级菜单
3. 提供单一后台支持多前台应用配置 3. 提供单一后台支持多前台应用配置
4. 提供单点登录 4. 提供单点登录
5. 集成系统认证授权模块 5. 集成系统认证授权模块
6. 提供角色,部门,用户,菜单,前台应用程序授权 6. 提供角色,部门,用户,菜单,前台应用程序授权
角色对用户授权 角色对用户授权
角色对菜单授权 角色对菜单授权
角色对部门授权 角色对部门授权
角色对应用程序授权(多个前台应用公用一个后台权限管理系统) 角色对应用程序授权(多个前台应用公用一个后台权限管理系统)
部门对用户授权 部门对用户授权
7. 提供字典表用于前台网站个性化配置 7. 提供字典表用于前台网站个性化配置
8. 完全响应式布局(支持电脑、平板、手机等所有主流设备) 8. 完全响应式布局(支持电脑、平板、手机等所有主流设备)
9. 内置多数据源支持,配置简单立即生效无需重启 9. 内置多数据源支持,配置简单立即生效无需重启
10. 内置数据内存缓存机制,页面快速响应 10. 内置数据内存缓存机制,页面快速响应
11. 内置数据 **操作日志** 与用户 **登录日志** 11. 内置数据 **操作日志** 与用户 **登录日志**
跟踪记录用户 **登录主机地点** **浏览器** **操作系统** 信息 跟踪记录用户 **登录主机地点** **浏览器** **操作系统** 信息
#### 优势 #### 优势
1. 前台系统不用编写登录、授权、认证模块;只负责编写业务模块即可 1. 前台系统不用编写登录、授权、认证模块;只负责编写业务模块即可
2. 后台系统无需任何二次开发,直接发布即可使用 2. 后台系统无需任何二次开发,直接发布即可使用
3. 前台与后台系统分离,无任何依赖关系 3. 前台与后台系统分离,无任何依赖关系
详细资料请点击 [查看文档](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/项目介绍) 详细资料请点击 [查看文档](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/项目介绍)
### 数据库 ### 数据库
数据库支持列表如下: 数据库支持列表如下:
**MSSQL/Oracle/SQLite/MySql/MariaDB/Postgresql/Firebird/MsAccess/MongoDB** **MSSQL/Oracle/SQLite/MySql/MariaDB/Postgresql/Firebird/MsAccess/MongoDB**
### 浏览器支持 ### 浏览器支持
```json ```json
"browserslist": [ "browserslist": [
"Chrome >= 45", "Chrome >= 45",
"Firefox >= 38", "Firefox >= 38",
"Edge >= 12", "Edge >= 12",
"Explorer >= 10", "Explorer >= 10",
"iOS >= 9", "iOS >= 9",
"Safari >= 9", "Safari >= 9",
"Android >= 4.4", "Android >= 4.4",
"Opera >= 30" "Opera >= 30"
] ]
``` ```
### 移动端支持 ### 移动端支持
| | **Chrome** | **Firefox** | **Safari** | **Android Browser & WebView** | **Microsoft Edge** | | | **Chrome** | **Firefox** | **Safari** | **Android Browser & WebView** | **Microsoft Edge** |
| ------- | --------- | --------- | ------ | ------------------------- | -------------- | | ------- | --------- | --------- | ------ | ------------------------- | -------------- |
| **Android** | Supported | Supported | N/A | Android v5.0+ supported | Supported | | **Android** | Supported | Supported | N/A | Android v5.0+ supported | Supported |
| **iOS** | Supported | Supported | Supported | N/A | Supported | | **iOS** | Supported | Supported | Supported | N/A | Supported |
| **Windows 10 Mobile** | N/A | N/A | N/A | N/A | Supported | | **Windows 10 Mobile** | N/A | N/A | N/A | N/A | Supported |
### 桌面浏览器支持 ### 桌面浏览器支持
| | Chrome | Firefox | Internet Explorer | Microsoft Edge | Opera | Safari | | | Chrome | Firefox | Internet Explorer | Microsoft Edge | Opera | Safari |
| ------- | --------- | --------- | ----------------- | -------------- | --------- | ------------- | | ------- | --------- | --------- | ----------------- | -------------- | --------- | ------------- |
| Mac | Supported | Supported | N/A | N/A | Supported | Supported | | Mac | Supported | Supported | N/A | N/A | Supported | Supported |
| Windows | Supported | Supported | Supported, IE10+ | Supported | Supported | Not supported | | Windows | Supported | Supported | Supported, IE10+ | Supported | Supported | Not supported |
## QQ交流群 ## QQ交流群
群号 群号
795206915 795206915
[快速加群](https://shang.qq.com/wpa/qunwpa?idkey=d381355e50ff91db410c3da3eadb081ba859f64c2877e86343f4709b171f28b8) [快速加群](https://shang.qq.com/wpa/qunwpa?idkey=d381355e50ff91db410c3da3eadb081ba859f64c2877e86343f4709b171f28b8)
## 安装教程 ## 安装教程
1. 安装 .net core sdk [官方网址](http://www.microsoft.com/net/download) 1. 安装 .net core sdk [官方网址](http://www.microsoft.com/net/download)
2. 安装 Visual Studio IDE 2017以上 [官方网址](https://visualstudio.microsoft.com/vs/getting-started/) 2. 安装 Visual Studio IDE 2017以上 [官方网址](https://visualstudio.microsoft.com/vs/getting-started/)
3. 获取本项目代码 [BootstrapAdmin](https://gitee.com/LongbowEnterprise/BootstrapAdmin) 3. 获取本项目代码 [BootstrapAdmin](https://gitee.com/LongbowEnterprise/BootstrapAdmin)
4. 安装数据库 4. 安装数据库
以微软MSSQL为例执行解决方案中SQLServer目录物理硬盘中DatabaseScripts目录下Install.sql脚本创建数据库 以微软MSSQL为例执行解决方案中SQLServer目录物理硬盘中DatabaseScripts目录下Install.sql脚本创建数据库
5. 初始化数据 5. 初始化数据
执行对应目录下InitData.sql脚本 执行对应目录下InitData.sql脚本
6. 拷贝Longbow.lic文件 6. 拷贝Longbow.lic文件
拷贝Scripts目录下Longbow.lic文件到bin目录下 拷贝Scripts目录下Longbow.lic文件到bin目录下
7. 系统登录用户名与口令 7. 系统登录用户名与口令
用户名:**Admin** 用户名:**Admin**
密码:**123789** 密码:**123789**
## 分支说明 ## 分支说明
**dev** 开发分支目前开发环境配置是 windows + SQLite **dev** 开发分支目前开发环境配置是 windows + SQLite
**master** 发布分支与在线演示版本同步 **master** 发布分支与在线演示版本同步
## 演示地址 ## 演示地址
**在线演示** <a href="http://argo.zylweb.cn" target="_blank">[传送门]</a> **在线演示** <a href="http://argo.zylweb.cn" target="_blank">[传送门]</a>
**备用地址** <a href="http://ba.sdgxgz.com" target="_blank">[传送门]</a> **备用地址** <a href="http://ba.sdgxgz.com" target="_blank">[传送门]</a>
#### 登录用户名与密码 #### 登录用户名与密码
管理员:**Admin/123789** 管理员:**Admin/123789**
普通用户:**User/123789** 普通用户:**User/123789**
#### 网站服务器配置: #### 网站服务器配置:
CPU: 1核 CPU: 1核
MEM: 2G MEM: 2G
## 配置说明 ## 配置说明
详细配置说明请点击 [查看文档](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis) 查看配置说明小节 详细配置说明请点击 [查看文档](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis) 查看配置说明小节
## 常见问题Q&A ## 常见问题Q&A
请点击 [查看文档](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/常见问题Q&A) 查看常见问题小节 请点击 [查看文档](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/常见问题Q&A) 查看常见问题小节
## 项目截图 ## 项目截图
后台首页 后台首页
![后台首页](https://gitee.com/LongbowEnterprise/Pictures/raw/master/BootstrapAdmin/BA02-01.png "BAHome-01.png") ![后台首页](https://gitee.com/LongbowEnterprise/Pictures/raw/master/BootstrapAdmin/BA02-01.png "BAHome-01.png")
更多截图请点击 [查看文档](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis) 查看项目截图小节 更多截图请点击 [查看文档](https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis) 查看项目截图小节
## 特别鸣谢 ## 特别鸣谢
1. <a href="https://gitee.com/571183806" target="_blank">**云龙**</a> 提供云服务器搭建在线演示系统 1. <a href="https://gitee.com/571183806" target="_blank">**云龙**</a> 提供云服务器搭建在线演示系统
2. <a href="https://gitee.com/Ysmc" target="_blank">**一事冇诚**</a> 对MongoDB数据库提供了详细测试 2. <a href="https://gitee.com/Ysmc" target="_blank">**一事冇诚**</a> 对MongoDB数据库提供了详细测试
3. <a href="https://gitee.com/Axxbis" target="_blank">**爱吃油麦菜**</a> 提供云服务器与二级域名搭建备份演示系统、测试环境以及图床 3. <a href="https://gitee.com/Axxbis" target="_blank">**爱吃油麦菜**</a> 提供云服务器与二级域名搭建备份演示系统、测试环境以及图床
## 参与贡献 ## 参与贡献
1. Fork 本项目 1. Fork 本项目
2. 新建 Feat_xxx 分支 2. 新建 Feat_xxx 分支
3. 提交代码 3. 提交代码
4. 新建 Pull Request 4. 新建 Pull Request

View File

@ -1,10 +1,10 @@
using Xunit; using Xunit;
namespace Bootstrap.Admin.Api.MySql namespace Bootstrap.Admin.Api.MySql
{ {
[Collection("MySqlContext")] [Collection("MySqlContext")]
public class ProfilesTest : Api.ProfilesTest public class ProfilesTest : Api.ProfilesTest
{ {
public ProfilesTest(MySqlBAWebHost factory) : base(factory) { } public ProfilesTest(MySqlBAWebHost factory) : base(factory) { }
} }
} }

View File

@ -1,10 +1,10 @@
using Xunit; using Xunit;
namespace Bootstrap.Admin.Api.MySql namespace Bootstrap.Admin.Api.MySql
{ {
[Collection("MySqlContext")] [Collection("MySqlContext")]
public class TracesTest : Api.TracesTest public class TracesTest : Api.TracesTest
{ {
public TracesTest(MySqlBAWebHost factory) : base(factory) { } public TracesTest(MySqlBAWebHost factory) : base(factory) { }
} }
} }

View File

@ -1,33 +1,33 @@
using Longbow.Web; using Longbow.Web;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Xunit; using Xunit;
namespace Bootstrap.Admin.Api namespace Bootstrap.Admin.Api
{ {
public class OnlineTest : ControllerTest public class OnlineTest : ControllerTest
{ {
public OnlineTest(BAWebHost factory) : base(factory, "api/OnlineUsers") { } public OnlineTest(BAWebHost factory) : base(factory, "api/OnlineUsers") { }
[Fact] [Fact]
public async void Get_Ok() public async void Get_Ok()
{ {
var users = await Client.GetAsJsonAsync<IEnumerable<OnlineUser>>(); var users = await Client.GetAsJsonAsync<IEnumerable<OnlineUser>>();
Assert.Single(users); Assert.Single(users);
} }
[Fact] [Fact]
public async void GetById_Ok() public async void GetById_Ok()
{ {
var urls = await Client.GetAsJsonAsync<IEnumerable<KeyValuePair<DateTime, string>>>("UnitTest"); var urls = await Client.GetAsJsonAsync<IEnumerable<KeyValuePair<DateTime, string>>>("UnitTest");
Assert.Empty(urls); Assert.Empty(urls);
} }
[Fact] [Fact]
public async void Put_Ok() public async void Put_Ok()
{ {
var ret = await Client.PutAsJsonAsync<string, bool>(""); var ret = await Client.PutAsJsonAsync<string, bool>("");
Assert.False(ret); Assert.False(ret);
} }
} }
} }

View File

@ -1,10 +1,10 @@
using Xunit; using Xunit;
namespace Bootstrap.Admin.Api.SQLite namespace Bootstrap.Admin.Api.SQLite
{ {
[Collection("SQLiteContext")] [Collection("SQLiteContext")]
public class ProfilesTest : Api.ProfilesTest public class ProfilesTest : Api.ProfilesTest
{ {
public ProfilesTest(SQLiteBAWebHost factory) : base(factory) { } public ProfilesTest(SQLiteBAWebHost factory) : base(factory) { }
} }
} }

View File

@ -1,10 +1,10 @@
using Xunit; using Xunit;
namespace Bootstrap.Admin.Api.SQLite namespace Bootstrap.Admin.Api.SQLite
{ {
[Collection("SQLiteContext")] [Collection("SQLiteContext")]
public class TracesTest : Api.TracesTest public class TracesTest : Api.TracesTest
{ {
public TracesTest(SQLiteBAWebHost factory) : base(factory) { } public TracesTest(SQLiteBAWebHost factory) : base(factory) { }
} }
} }

View File

@ -1,12 +1,12 @@
using Bootstrap.DataAccess; using Bootstrap.DataAccess;
using Longbow.Web.Mvc; using Longbow.Web.Mvc;
using System; using System;
using Xunit; using Xunit;
namespace Bootstrap.Admin.Api namespace Bootstrap.Admin.Api
{ {
public class TracesTest : ControllerTest public class TracesTest : ControllerTest
{ {
public TracesTest(BAWebHost factory) : base(factory, "api/Traces") { } public TracesTest(BAWebHost factory) : base(factory, "api/Traces") { }
[Fact] [Fact]
@ -22,6 +22,6 @@ namespace Bootstrap.Admin.Api
// clean // clean
DbManager.Create().Execute("Delete from Traces where LogTime = @0", trac.LogTime); DbManager.Create().Execute("Delete from Traces where LogTime = @0", trac.LogTime);
} }
} }
} }

View File

@ -1,10 +1,10 @@
using Xunit; using Xunit;
namespace Bootstrap.DataAccess.MySql namespace Bootstrap.DataAccess.MySql
{ {
[Collection("MySqlContext")] [Collection("MySqlContext")]
public class TracesTest : DataAccess.TracesTest public class TracesTest : DataAccess.TracesTest
{ {
} }
} }

View File

@ -1,10 +1,10 @@
using Xunit; using Xunit;
namespace Bootstrap.DataAccess.SQLite namespace Bootstrap.DataAccess.SQLite
{ {
[Collection("SQLiteContext")] [Collection("SQLiteContext")]
public class TracesTest : DataAccess.TracesTest public class TracesTest : DataAccess.TracesTest
{ {
} }
} }

View File

@ -1,12 +1,12 @@
using Longbow.Web.Mvc; using Longbow.Web.Mvc;
using System; using System;
using Xunit; using Xunit;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
[Collection("SQLServerContext")] [Collection("SQLServerContext")]
public class TracesTest public class TracesTest
{ {
[Fact] [Fact]
public void Save_Ok() public void Save_Ok()
{ {
@ -33,11 +33,11 @@ namespace Bootstrap.DataAccess
City = "本地连接", City = "本地连接",
OS = "UnitTest", OS = "UnitTest",
Ip = "::1", Ip = "::1",
LogTime = DateTime.Now, LogTime = DateTime.Now,
RequestUrl = "~/Home/Index" RequestUrl = "~/Home/Index"
}; };
log.Save(log); log.Save(log);
Assert.NotEmpty(log.Retrieves(new PaginationOption() { Limit = 20, Offset = 0, Order = "desc", Sort = "LogTime" }, null, null).Items); Assert.NotEmpty(log.Retrieves(new PaginationOption() { Limit = 20, Offset = 0, Order = "desc", Sort = "LogTime" }, null, null).Items);
} }
} }
} }