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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,11 +1,11 @@
@model NavigatorBarModel
@{
ViewBag.Title = "图标集";
}
@section css {
<link href="~/css/fa.css" rel="stylesheet" asp-append-version="true" />
}
@section javascript {
<script src="~/js/icon.js" asp-append-version="true"></script>
}
@model NavigatorBarModel
@{
ViewBag.Title = "图标集";
}
@section css {
<link href="~/css/fa.css" rel="stylesheet" asp-append-version="true" />
}
@section javascript {
<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>

View File

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

View File

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

View File

@ -1,46 +1,46 @@
@model NavigatorBarModel
@{
ViewBag.Title = "站内消息";
}
@section javascript {
<script src="~/js/message.js" asp-append-version="true"></script>
}
<div class="mail-box">
<div class="sm-side">
<div class="user-head">
<a href="javascript:;" class="inbox-avatar">
<img src="~/images/logo6.jpg" alt="">
</a>
<div class="user-name"><h5><a href="#">@Model.DisplayName</a></h5></div>
</div>
<div class="inbox-body">
<a class="btn btn-compose" data-toggle="modal" href="#myModal">
写消息
</a>
</div>
<ul id="mailBox" class="inbox-nav inbox-divider">
<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>
</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>
</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>
</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>
</li>
</ul>
</div>
<div class="lg-side">
<div class="inbox-head">
<h3>消息列表</h3>
</div>
<div class="inbox-body">
<table class="table table-inbox table-hover">
<tbody id="tbMsg"></tbody>
</table>
</div>
</div>
@model NavigatorBarModel
@{
ViewBag.Title = "站内消息";
}
@section javascript {
<script src="~/js/message.js" asp-append-version="true"></script>
}
<div class="mail-box">
<div class="sm-side">
<div class="user-head">
<a href="javascript:;" class="inbox-avatar">
<img src="~/images/logo6.jpg" alt="">
</a>
<div class="user-name"><h5><a href="#">@Model.DisplayName</a></h5></div>
</div>
<div class="inbox-body">
<a class="btn btn-compose" data-toggle="modal" href="#myModal">
写消息
</a>
</div>
<ul id="mailBox" class="inbox-nav inbox-divider">
<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>
</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>
</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>
</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>
</li>
</ul>
</div>
<div class="lg-side">
<div class="inbox-head">
<h3>消息列表</h3>
</div>
<div class="inbox-body">
<table class="table table-inbox table-hover">
<tbody id="tbMsg"></tbody>
</table>
</div>
</div>
</div>

View File

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

View File

@ -1,29 +1,29 @@
@model NavigatorBarModel
@{
ViewBag.Title = "通知管理";
}
@section css {
<environment include="Development">
<link href="~/lib/bootstrap-table/bootstrap-table.css" rel="stylesheet" />
</environment>
<environment exclude="Development">
<link href="~/lib/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" />
</environment>
}
@section javascript {
<environment include="Development">
<script src="~/lib/bootstrap-table/bootstrap-table.js"></script>
<script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script>
</environment>
<environment exclude="Development">
<script src="~/lib/bootstrap-table/bootstrap-table.min.js"></script>
<script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.min.js"></script>
</environment>
<script src="~/js/noti.js" asp-append-version="true"></script>
}
<div class="card">
<div class="card-header">用户注册<span class="pull-right"><a id="refreshUsers" href="javascript:;" class="fa fa-refresh" title="点击刷新" data-toggle="tooltip" data-placement="left"></a></span></div>
<div class="card-body" style="padding-top: 25px;">
<table></table>
</div>
@model NavigatorBarModel
@{
ViewBag.Title = "通知管理";
}
@section css {
<environment include="Development">
<link href="~/lib/bootstrap-table/bootstrap-table.css" rel="stylesheet" />
</environment>
<environment exclude="Development">
<link href="~/lib/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" />
</environment>
}
@section javascript {
<environment include="Development">
<script src="~/lib/bootstrap-table/bootstrap-table.js"></script>
<script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script>
</environment>
<environment exclude="Development">
<script src="~/lib/bootstrap-table/bootstrap-table.min.js"></script>
<script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.min.js"></script>
</environment>
<script src="~/js/noti.js" asp-append-version="true"></script>
}
<div class="card">
<div class="card-header">用户注册<span class="pull-right"><a id="refreshUsers" href="javascript:;" class="fa fa-refresh" title="点击刷新" data-toggle="tooltip" data-placement="left"></a></span></div>
<div class="card-body" style="padding-top: 25px;">
<table></table>
</div>
</div>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
@model ModelBase
<footer class="position-fixed">
<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">
<i class="fa fa-angle-up"></i>
</a>
@model ModelBase
<footer class="position-fixed">
<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">
<i class="fa fa-angle-up"></i>
</a>
</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-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="myGroupModalLabel">部门授权窗口</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
<form class="form-inline">
<div class="row" id="groupForm"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i>
<span>关闭</span>
</button>
<button type="button" class="btn btn-primary" id="btnSubmitGroup">
<i class="fa fa-save"></i>
<span>保存</span>
</button>
</div>
</div>
</div>
</div>
<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-content">
<div class="modal-header">
<h5 class="modal-title" id="myGroupModalLabel">部门授权窗口</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
<form class="form-inline">
<div class="row" id="groupForm"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i>
<span>关闭</span>
</button>
<button type="button" class="btn btn-primary" id="btnSubmitGroup">
<i class="fa fa-save"></i>
<span>保存</span>
</button>
</div>
</div>
</div>
</div>

View File

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

View File

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

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

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-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="myRoleModalLabel">角色授权窗口</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
<form class="form-inline">
<div class="row" id="roleForm"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i>
<span>关闭</span>
</button>
<button type="button" class="btn btn-primary" id="btnSubmitRole">
<i class="fa fa-save"></i>
<span>保存</span>
</button>
</div>
</div>
</div>
<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-content">
<div class="modal-header">
<h5 class="modal-title" id="myRoleModalLabel">角色授权窗口</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
<form class="form-inline">
<div class="row" id="roleForm"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i>
<span>关闭</span>
</button>
<button type="button" class="btn btn-primary" id="btnSubmitRole">
<i class="fa fa-save"></i>
<span>保存</span>
</button>
</div>
</div>
</div>
</div>

View File

@ -1,7 +1,7 @@
@model IEnumerable<Bootstrap.Security.BootstrapMenu>
<ul class="sub nav nav-pills flex-column flex-nowrap" style="display: none;">
@foreach (var menu in Model)
{
@await Html.PartialAsync("SubNavItem", menu)
}
</ul>
@model IEnumerable<Bootstrap.Security.BootstrapMenu>
<ul class="sub nav nav-pills flex-column flex-nowrap" style="display: none;">
@foreach (var menu in Model)
{
@await Html.PartialAsync("SubNavItem", menu)
}
</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-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="myUserModalLabel">用户授权窗口</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
<form class="form-inline">
<div class="row" id="userForm"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i>
<span>关闭</span>
</button>
<button type="button" class="btn btn-primary" id="btnSubmitUser">
<i class="fa fa-save"></i>
<span>保存</span>
</button>
</div>
</div>
</div>
<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-content">
<div class="modal-header">
<h5 class="modal-title" id="myUserModalLabel">用户授权窗口</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
<form class="form-inline">
<div class="row" id="userForm"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i>
<span>关闭</span>
</button>
<button type="button" class="btn btn-primary" id="btnSubmitUser">
<i class="fa fa-save"></i>
<span>保存</span>
</button>
</div>
</div>
</div>
</div>

View File

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

View File

@ -1,34 +1,34 @@
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="~/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="~/favicon.ico" type="image/x-icon" />
<link rel="apple-touch-icon" href="~/favicon.png"/>
<title>@ViewBag.Title</title>
@RenderSection("css", false)
<!--[if lt IE 10 ]>
<link href="../css/IE8.css" rel="stylesheet" />
<![endif]-->
</head>
<body>
<!--[if lt IE 10 ]>
<div id="ieAlert" class="alert alert-danger alert-dismissible">
<div>当前浏览器版本太低不支持本系统请升级到至少IE10 <a href="../browser/IE10.exe" target="_blank">本地下载</a> <a href="https://support.microsoft.com/zh-cn/help/17621/internet-explorer-downloads" target="_blank">微软下载</a>或者使用Chrome浏览器 <a href="../browser/ChromeSetup.exe" target="_blank">本地下载</a></div>
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">关闭</span></button>
</div>
<![endif]-->
@RenderBody()
<a id="pathBase" href="~/" hidden></a>
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<environment include="Development">
<script src="~/lib/jquery/jquery.js"></script>
</environment>
<environment exclude="Development">
<script src="~/lib/jquery/jquery.min.js"></script>
</environment>
@RenderSection("javascript", false)
</body>
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="~/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="~/favicon.ico" type="image/x-icon" />
<link rel="apple-touch-icon" href="~/favicon.png"/>
<title>@ViewBag.Title</title>
@RenderSection("css", false)
<!--[if lt IE 10 ]>
<link href="../css/IE8.css" rel="stylesheet" />
<![endif]-->
</head>
<body>
<!--[if lt IE 10 ]>
<div id="ieAlert" class="alert alert-danger alert-dismissible">
<div>当前浏览器版本太低不支持本系统请升级到至少IE10 <a href="../browser/IE10.exe" target="_blank">本地下载</a> <a href="https://support.microsoft.com/zh-cn/help/17621/internet-explorer-downloads" target="_blank">微软下载</a>或者使用Chrome浏览器 <a href="../browser/ChromeSetup.exe" target="_blank">本地下载</a></div>
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">关闭</span></button>
</div>
<![endif]-->
@RenderBody()
<a id="pathBase" href="~/" hidden></a>
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<environment include="Development">
<script src="~/lib/jquery/jquery.js"></script>
</environment>
<environment exclude="Development">
<script src="~/lib/jquery/jquery.min.js"></script>
</environment>
@RenderSection("javascript", false)
</body>
</html>

View File

@ -24,10 +24,10 @@
var html = "";
$.each(menus, function (index, menu) {
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 {
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;

View File

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

View File

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

View File

@ -1,44 +1,44 @@
using Bootstrap.Client.Models;
using Longbow.Configuration;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
namespace Bootstrap.Client.Controllers
{
/// <summary>
///
/// </summary>
public class HomeController : Controller
{
/// <summary>
///
/// </summary>
/// <returns></returns>
public IActionResult Index()
{
return View(new NavigatorBarModel(this));
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public IActionResult About()
{
return View(new NavigatorBarModel(this));
}
/// <summary>
///
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public IActionResult Error(int id)
{
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;
return Redirect(uriBuilder.ToString());
}
}
}
using Bootstrap.Client.Models;
using Longbow.Configuration;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
namespace Bootstrap.Client.Controllers
{
/// <summary>
///
/// </summary>
public class HomeController : Controller
{
/// <summary>
///
/// </summary>
/// <returns></returns>
public IActionResult Index()
{
return View(new NavigatorBarModel(this));
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public IActionResult About()
{
return View(new NavigatorBarModel(this));
}
/// <summary>
///
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public IActionResult Error(int id)
{
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;
return Redirect(uriBuilder.ToString());
}
}
}

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -1,10 +1,10 @@
using Longbow.Web.Mvc;
using Longbow.Web.Mvc;
using MongoDB.Driver;
using PetaPoco;
using System;
using PetaPoco;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq;
namespace Bootstrap.DataAccess.MongoDB
{
/// <summary>
@ -28,8 +28,8 @@ namespace Bootstrap.DataAccess.MongoDB
/// </summary>
/// <param name="po"></param>
/// <returns></returns>
public override Page<DataAccess.LoginUser> Retrieves(PaginationOption po)
{
public override Page<DataAccess.LoginUser> Retrieves(PaginationOption po)
{
var logs = DbManager.LoginUsers
.Find(Builders<DataAccess.LoginUser>.Filter.Empty)
.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),
Items = logs.Skip(po.Offset).Take(po.Limit).ToList()
};
}
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
using Longbow.Data;
using Longbow.Web.Mvc;
using PetaPoco;
using Longbow.Web.Mvc;
using PetaPoco;
namespace Bootstrap.DataAccess
{
/// <summary>
@ -20,6 +20,6 @@ namespace Bootstrap.DataAccess
/// 查询所有登录日志
/// </summary>
/// <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 PetaPoco;
using System;
namespace Bootstrap.DataAccess
{
/// <summary>
///
/// </summary>
public class Log : Trace
{
/// <summary>
/// 获得/设置 操作类型
/// </summary>
public string CRUD { get; set; }
/// <summary>
/// 获得/设置 请求数据
/// </summary>
public string RequestData { get; set; }
/// <summary>
/// 查询所有操作日志信息
/// </summary>
/// <param name="po"></param>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <param name="opType"></param>
/// <returns></returns>
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");
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 (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);
sql.Append($"order by {po.Sort} {po.Order}");
return DbManager.Create().Page<Log>(po.PageIndex, po.Limit, sql);
}
/// <summary>
/// 删除日志信息
/// </summary>
/// <returns></returns>
private static void DeleteLogAsync()
{
System.Threading.Tasks.Task.Run(() =>
{
var dtm = DateTime.Now.AddMonths(0 - DictHelper.RetrieveLogsPeriod());
DbManager.Create().Execute("delete from Logs where LogTime < @0", dtm);
});
}
/// <summary>
/// 保存新增的日志信息
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
public virtual bool Save(Log p)
{
if (p == null) throw new ArgumentNullException(nameof(p));
DeleteLogAsync();
p.LogTime = DateTime.Now;
DbManager.Create().Save(p);
return true;
}
}
}
using Longbow.Web.Mvc;
using PetaPoco;
using System;
namespace Bootstrap.DataAccess
{
/// <summary>
///
/// </summary>
public class Log : Trace
{
/// <summary>
/// 获得/设置 操作类型
/// </summary>
public string CRUD { get; set; }
/// <summary>
/// 获得/设置 请求数据
/// </summary>
public string RequestData { get; set; }
/// <summary>
/// 查询所有操作日志信息
/// </summary>
/// <param name="po"></param>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <param name="opType"></param>
/// <returns></returns>
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");
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 (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);
sql.Append($"order by {po.Sort} {po.Order}");
return DbManager.Create().Page<Log>(po.PageIndex, po.Limit, sql);
}
/// <summary>
/// 删除日志信息
/// </summary>
/// <returns></returns>
private static void DeleteLogAsync()
{
System.Threading.Tasks.Task.Run(() =>
{
var dtm = DateTime.Now.AddMonths(0 - DictHelper.RetrieveLogsPeriod());
DbManager.Create().Execute("delete from Logs where LogTime < @0", dtm);
});
}
/// <summary>
/// 保存新增的日志信息
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
public virtual bool Save(Log p)
{
if (p == null) throw new ArgumentNullException(nameof(p));
DeleteLogAsync();
p.LogTime = DateTime.Now;
DbManager.Create().Save(p);
return true;
}
}
}

View File

@ -1,4 +1,4 @@
using Longbow.Web.Mvc;
using Longbow.Web.Mvc;
using PetaPoco;
using System;
@ -50,8 +50,8 @@ namespace Bootstrap.DataAccess
/// </summary>
public string Result { get; set; }
/// <summary>
///
/// <summary>
///
/// </summary>
public string UserAgent { get; set; }
@ -72,6 +72,6 @@ namespace Bootstrap.DataAccess
/// </summary>
/// <param name="po"></param>
/// <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.Collections.Generic;
using System.Linq;
namespace Bootstrap.DataAccess
{
/// <summary>
///
/// </summary>
public class Message
{
/// <summary>
/// 消息主键 数据库自增
/// </summary>
public string Id { get; set; }
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 发消息人
/// </summary>
public string From { get; set; }
/// <summary>
/// 收消息人
/// </summary>
public string To { get; set; }
/// <summary>
/// 消息发送时间
/// </summary>
public DateTime SendTime { get; set; }
/// <summary>
/// 消息状态0-未读1-已读 和Dict表的通知消息关联
/// </summary>
public string Status { get; set; }
/// <summary>
/// 标旗状态0-未标旗1-已标旗
/// </summary>
public int Mark { get; set; }
/// <summary>
/// 删除状态0-未删除1-已删除
/// </summary>
public int IsDelete { get; set; }
/// <summary>
/// 消息标签0-一般1-紧要 和Dict表的消息标签关联
/// </summary>
public string Label { get; set; }
/// <summary>
/// 获得/设置 标签名称
/// </summary>
public string LabelName { get; set; }
/// <summary>
/// 获得/设置 时间描述 2分钟内为刚刚
/// </summary>
public string Period { get; set; }
/// <summary>
/// 获得/设置 发件人头像
/// </summary>
public string FromIcon { get; set; }
/// <summary>
/// 获得/设置 发件人昵称
/// </summary>
public string FromDisplayName { get; set; }
//TODO: SQL语句不兼容
/// <summary>
/// 所有有关userName所有消息列表
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
protected virtual IEnumerable<Message> Retrieves(string userName)
{
var db = DbManager.Create();
var t = db.Provider.EscapeSqlIdentifier("To");
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 = "消息标签" });
}
/// <summary>
/// 收件箱
/// </summary>
/// <param name="userName"></param>
public virtual IEnumerable<Message> Inbox(string userName)
{
var messageRet = Retrieves(userName);
return messageRet.Where(n => n.To.Equals(userName, StringComparison.OrdinalIgnoreCase));
}
/// <summary>
/// 发件箱
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public virtual IEnumerable<Message> SendMail(string userName)
{
var messageRet = Retrieves(userName);
return messageRet.Where(n => n.From.Equals(userName, StringComparison.OrdinalIgnoreCase));
}
/// <summary>
/// 垃圾箱
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public virtual IEnumerable<Message> Trash(string userName)
{
var messageRet = Retrieves(userName);
return messageRet.Where(n => n.IsDelete == 1);
}
/// <summary>
/// 标旗
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public virtual IEnumerable<Message> Flag(string userName)
{
var messageRet = Retrieves(userName);
return messageRet.Where(n => n.Mark == 1);
}
/// <summary>
/// 获取Header处显示的消息列表
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public virtual IEnumerable<Message> RetrieveHeaders(string userName)
{
var messageRet = Inbox(userName);
messageRet.AsParallel().ForAll(n =>
{
var ts = DateTime.Now - n.SendTime;
if (ts.TotalMinutes < 5) n.Period = "刚刚";
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.Minutes > 0) n.Period = string.Format("{0}分钟", ts.Minutes);
});
return messageRet;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace Bootstrap.DataAccess
{
/// <summary>
///
/// </summary>
public class Message
{
/// <summary>
/// 消息主键 数据库自增
/// </summary>
public string Id { get; set; }
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 发消息人
/// </summary>
public string From { get; set; }
/// <summary>
/// 收消息人
/// </summary>
public string To { get; set; }
/// <summary>
/// 消息发送时间
/// </summary>
public DateTime SendTime { get; set; }
/// <summary>
/// 消息状态0-未读1-已读 和Dict表的通知消息关联
/// </summary>
public string Status { get; set; }
/// <summary>
/// 标旗状态0-未标旗1-已标旗
/// </summary>
public int Mark { get; set; }
/// <summary>
/// 删除状态0-未删除1-已删除
/// </summary>
public int IsDelete { get; set; }
/// <summary>
/// 消息标签0-一般1-紧要 和Dict表的消息标签关联
/// </summary>
public string Label { get; set; }
/// <summary>
/// 获得/设置 标签名称
/// </summary>
public string LabelName { get; set; }
/// <summary>
/// 获得/设置 时间描述 2分钟内为刚刚
/// </summary>
public string Period { get; set; }
/// <summary>
/// 获得/设置 发件人头像
/// </summary>
public string FromIcon { get; set; }
/// <summary>
/// 获得/设置 发件人昵称
/// </summary>
public string FromDisplayName { get; set; }
//TODO: SQL语句不兼容
/// <summary>
/// 所有有关userName所有消息列表
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
protected virtual IEnumerable<Message> Retrieves(string userName)
{
var db = DbManager.Create();
var t = db.Provider.EscapeSqlIdentifier("To");
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 = "消息标签" });
}
/// <summary>
/// 收件箱
/// </summary>
/// <param name="userName"></param>
public virtual IEnumerable<Message> Inbox(string userName)
{
var messageRet = Retrieves(userName);
return messageRet.Where(n => n.To.Equals(userName, StringComparison.OrdinalIgnoreCase));
}
/// <summary>
/// 发件箱
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public virtual IEnumerable<Message> SendMail(string userName)
{
var messageRet = Retrieves(userName);
return messageRet.Where(n => n.From.Equals(userName, StringComparison.OrdinalIgnoreCase));
}
/// <summary>
/// 垃圾箱
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public virtual IEnumerable<Message> Trash(string userName)
{
var messageRet = Retrieves(userName);
return messageRet.Where(n => n.IsDelete == 1);
}
/// <summary>
/// 标旗
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public virtual IEnumerable<Message> Flag(string userName)
{
var messageRet = Retrieves(userName);
return messageRet.Where(n => n.Mark == 1);
}
/// <summary>
/// 获取Header处显示的消息列表
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public virtual IEnumerable<Message> RetrieveHeaders(string userName)
{
var messageRet = Inbox(userName);
messageRet.AsParallel().ForAll(n =>
{
var ts = DateTime.Now - n.SendTime;
if (ts.TotalMinutes < 5) n.Period = "刚刚";
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.Minutes > 0) n.Period = string.Format("{0}分钟", ts.Minutes);
});
return messageRet;
}
}
}

View File

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

View File

@ -1,57 +1,57 @@
using System;
using System.Collections.Generic;
namespace Bootstrap.DataAccess
{
/// <summary>
///
/// </summary>
public class Task
{
/// <summary>
/// 获取/设置 任务ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 获取/设置 任务名称
/// </summary>
public string TaskName { get; set; }
/// <summary>
/// 获取/设置 分配人
/// </summary>
public string AssignName { get; set; }
/// <summary>
/// 获得/设置 分配人昵称
/// </summary>
public string AssignDisplayName { get; set; }
/// <summary>
/// 获取/设置 完成任务人
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 获取/设置 任务所需时间(天)
/// </summary>
public int TaskTime { get; set; }
/// <summary>
/// 获取/设置 任务进度
/// </summary>
public double TaskProgress { get; set; }
/// <summary>
/// 获取/设置 分配时间
/// </summary>
public DateTime AssignTime { get; set; }
/// <summary>
/// 查询所有任务
/// </summary>
/// <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");
}
}
using System;
using System.Collections.Generic;
namespace Bootstrap.DataAccess
{
/// <summary>
///
/// </summary>
public class Task
{
/// <summary>
/// 获取/设置 任务ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 获取/设置 任务名称
/// </summary>
public string TaskName { get; set; }
/// <summary>
/// 获取/设置 分配人
/// </summary>
public string AssignName { get; set; }
/// <summary>
/// 获得/设置 分配人昵称
/// </summary>
public string AssignDisplayName { get; set; }
/// <summary>
/// 获取/设置 完成任务人
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 获取/设置 任务所需时间(天)
/// </summary>
public int TaskTime { get; set; }
/// <summary>
/// 获取/设置 任务进度
/// </summary>
public double TaskProgress { get; set; }
/// <summary>
/// 获取/设置 分配时间
/// </summary>
public DateTime AssignTime { get; set; }
/// <summary>
/// 查询所有任务
/// </summary>
/// <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");
}
}

View File

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

View File

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

View File

@ -1,104 +1,104 @@

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

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

File diff suppressed because it is too large Load Diff

248
README.md
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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