!27 增加功能:Bootstrap.Client 增加对 MongoDB 支持

Merge pull request !27 from Argo/dev-Mongo
This commit is contained in:
Argo 2019-08-30 15:21:45 +08:00 committed by Gitee
commit 5d083bcd7f
39 changed files with 1152 additions and 60 deletions

View File

@ -12,7 +12,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.13" /> <PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.13" />
<PackageReference Include="Longbow.Configuration" Version="2.2.7" /> <PackageReference Include="Longbow.Configuration" Version="2.2.7" />
<PackageReference Include="Longbow.Tasks" Version="1.8.0" /> <PackageReference Include="Longbow.Tasks" Version="1.9.0" />
<PackageReference Include="Microsoft.AspNetCore.App" /> <PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="3.1.6" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="3.1.6" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" PrivateAssets="All" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" PrivateAssets="All" />

View File

@ -15,7 +15,6 @@
"ConnectionStrings": { "ConnectionStrings": {
"ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa" "ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa"
}, },
"MongoDB": "BootstrapAdmin",
"DB": [ "DB": [
{ {
"Enabled": false "Enabled": false
@ -28,25 +27,25 @@
} }
}, },
{ {
"Enabled": true, "Enabled": false,
"ProviderName": "MySql", "ProviderName": "MySql",
"ConnectionStrings": { "ConnectionStrings": {
"ba": "Server=localhost;Database=BA;Uid=argozhang;Pwd=argo@163.com;SslMode=none;" "ba": "Server=localhost;Database=BA;Uid=argozhang;Pwd=argo@163.com;SslMode=none;"
} }
}, },
{ {
"Enabled": true, "Enabled": false,
"ProviderName": "Npgsql", "ProviderName": "Npgsql",
"ConnectionStrings": { "ConnectionStrings": {
"ba": "Server=localhost;Database=BootstrapAdmin;User ID=argozhang;Password=argo@163.com;" "ba": "Server=localhost;Database=BootstrapAdmin;User ID=argozhang;Password=argo@163.com;"
} }
}, },
{ {
"Enabled": true, "Enabled": false,
"Widget": "Bootstrap.DataAccess.MongoDB", "Widget": "Bootstrap.DataAccess.MongoDB",
"ProviderName": "MongoDB", "ProviderName": "MongoDB",
"ConnectionStrings": { "ConnectionStrings": {
"ba": "mongodb://localhost:27017" "ba": "mongodb://localhost:27017;Database=BootstrapAdmin"
} }
} }
], ],
@ -244,4 +243,4 @@
} }
] ]
} }
} }

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Bootstrap.Client.DataAccess.MongoDB
{
/// <summary>
///
/// </summary>
public class App : DataAccess.App
{
/// <summary>
/// 根据指定用户名获得授权应用程序集合
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public override IEnumerable<string> RetrievesByUserName(string userName)
{
var ret = new List<string>();
var roles = RoleHelper.RetrievesByUserName(userName);
if (roles.Contains("Administrators", StringComparer.OrdinalIgnoreCase))
{
ret.AddRange(DictHelper.RetrieveApps().Select(kv => kv.Key));
}
else
{
RoleHelper.Retrieves().Cast<Role>().Where(r => roles.Any(rn => rn == r.RoleName)).ToList().ForEach(r => ret.AddRange(r.Apps));
}
return ret;
}
}
}

View File

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MongoDB.Driver" Version="2.9.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Bootstrap.Client.DataAccess\Bootstrap.Client.DataAccess.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,171 @@
using Bootstrap.Security;
using Longbow.Configuration;
using Microsoft.Extensions.Primitives;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver;
namespace Bootstrap.Client.DataAccess.MongoDB
{
/// <summary>
/// 数据库操作类
/// </summary>
internal static class DbManager
{
private static IMongoDatabase _db = null;
private static bool _register = false;
private static readonly object _locker = new object();
/// <summary>
///
/// </summary>
private static IMongoDatabase BADatabase
{
get
{
if (_db == null)
{
lock (_locker)
{
if (!_register)
{
_register = true;
ChangeToken.OnChange(() => ConfigurationManager.AppSettings.GetReloadToken(), () => _db = null);
InitClassMap();
}
if (_db == null)
InitDb("ba");
}
}
return _db;
}
}
#region Collections
/// <summary>
/// Dicts 集合
/// </summary>
public static IMongoCollection<BootstrapDict> Dicts
{
get
{
return BADatabase.GetCollection<BootstrapDict>("Dicts");
}
}
/// <summary>
/// Users 集合
/// </summary>
public static IMongoCollection<User> Users
{
get
{
return BADatabase.GetCollection<User>("Users");
}
}
/// <summary>
/// Roles 集合
/// </summary>
public static IMongoCollection<Role> Roles
{
get
{
return BADatabase.GetCollection<Role>("Roles");
}
}
/// <summary>
/// Groups 集合
/// </summary>
public static IMongoCollection<Group> Groups
{
get
{
return BADatabase.GetCollection<Group>("Groups");
}
}
/// <summary>
/// Menus 集合
/// </summary>
public static IMongoCollection<BootstrapMenu> Menus
{
get
{
return BADatabase.GetCollection<BootstrapMenu>("Navigations");
}
}
#endregion
private static void InitDb(string name = null)
{
var (connectString, databaseName) = Longbow.Data.DbManager.GetMongoDB(name);
var client = new MongoClient(connectString);
_db = client.GetDatabase(databaseName);
}
private static void InitClassMap()
{
BsonSerializer.RegisterSerializer(DateTimeSerializer.LocalInstance);
if (!BsonClassMap.IsClassMapRegistered(typeof(BootstrapDict)))
{
BsonClassMap.RegisterClassMap<BootstrapDict>(md =>
{
md.AutoMap();
md.IdMemberMap.SetSerializer(new StringSerializer(BsonType.ObjectId));
md.IdMemberMap.SetIgnoreIfDefault(true);
});
}
if (!BsonClassMap.IsClassMapRegistered(typeof(User)))
{
BsonClassMap.RegisterClassMap<User>(md =>
{
md.AutoMap();
md.IdMemberMap.SetSerializer(new StringSerializer(BsonType.ObjectId));
md.IdMemberMap.SetIgnoreIfDefault(true);
});
}
if (!BsonClassMap.IsClassMapRegistered(typeof(BootstrapMenu)))
{
BsonClassMap.RegisterClassMap<BootstrapMenu>(md =>
{
md.AutoMap();
md.IdMemberMap.SetSerializer(new StringSerializer(BsonType.ObjectId));
md.IdMemberMap.SetIgnoreIfDefault(true);
md.UnmapMember(m => m.CategoryName);
md.UnmapMember(m => m.Active);
md.UnmapMember(m => m.ParentName);
md.UnmapMember(m => m.Menus);
});
}
if (!BsonClassMap.IsClassMapRegistered(typeof(BootstrapGroup)))
{
BsonClassMap.RegisterClassMap<BootstrapGroup>(md =>
{
md.AutoMap();
md.IdMemberMap.SetSerializer(new StringSerializer(BsonType.ObjectId));
md.IdMemberMap.SetIgnoreIfDefault(true);
});
}
if (!BsonClassMap.IsClassMapRegistered(typeof(Group)))
{
BsonClassMap.RegisterClassMap<Group>(md =>
{
md.AutoMap();
});
}
if (!BsonClassMap.IsClassMapRegistered(typeof(Role)))
{
BsonClassMap.RegisterClassMap<Role>(md =>
{
md.AutoMap();
md.IdMemberMap.SetSerializer(new StringSerializer(BsonType.ObjectId));
md.IdMemberMap.SetIgnoreIfDefault(true);
});
}
}
}
}

View File

@ -0,0 +1,45 @@
using Bootstrap.Security;
using Longbow.Configuration;
using MongoDB.Driver;
using System.Collections.Generic;
using System.Linq;
namespace Bootstrap.Client.DataAccess.MongoDB
{
/// <summary>
///
/// </summary>
public class Dict : DataAccess.Dict
{
/// <summary>
///
/// </summary>
/// <returns></returns>
public override IEnumerable<BootstrapDict> RetrieveDicts() => DbManager.Dicts.Find(FilterDefinition<BootstrapDict>.Empty).ToList();
private static string RetrieveAppName(string name, string defaultValue = "未设置")
{
var dicts = DictHelper.RetrieveDicts();
var platName = dicts.FirstOrDefault(d => d.Category == "应用程序" && d.Code == ConfigurationManager.AppSettings["AppId"])?.Name;
return dicts.FirstOrDefault(d => d.Category == platName && d.Name == name)?.Code ?? $"{name}{defaultValue}";
}
/// <summary>
/// 获得系统设置地址
/// </summary>
/// <returns></returns>
public override string RetrieveSettingsUrl() => RetrieveAppName("系统设置地址");
/// <summary>
/// 获得系统个人中心地址
/// </summary>
/// <returns></returns>
public override string RetrieveProfilesUrl() => RetrieveAppName("个人中心地址");
/// <summary>
/// 获得系统通知地址地址
/// </summary>
/// <returns></returns>
public override string RetrieveNotisUrl() => RetrieveAppName("系统通知地址");
}
}

View File

@ -0,0 +1,28 @@
using Bootstrap.Security;
using MongoDB.Driver;
using System.Collections.Generic;
namespace Bootstrap.Client.DataAccess.MongoDB
{
class Group : BootstrapGroup
{
/// <summary>
/// 获得/设置 群组描述
/// </summary>
public string Description { get; set; }
/// <summary>
///
/// </summary>
public IEnumerable<string> Roles { get; set; }
/// <summary>
///
/// </summary>
/// <returns></returns>
public IEnumerable<Group> Retrieves()
{
return DbManager.Groups.Find(FilterDefinition<Group>.Empty).ToList();
}
}
}

View File

@ -0,0 +1,24 @@
using Longbow.Cache;
using MongoDB.Driver;
using System.Collections.Generic;
using System.Linq;
namespace Bootstrap.Client.DataAccess.MongoDB
{
class GroupHelper
{
/// <summary>
///
/// </summary>
public const string RetrieveGroupsDataKey = "GroupHelper-RetrieveGroups";
/// <summary>
///
/// </summary>
/// <returns></returns>
public static IEnumerable<Group> Retrieves()
{
return CacheManager.GetOrAdd(RetrieveGroupsDataKey, key => DbManager.Groups.Find(FilterDefinition<Group>.Empty).ToList());
}
}
}

View File

@ -0,0 +1,39 @@
using Longbow.Cache;
using MongoDB.Driver;
using System.Collections.Generic;
using System.Linq;
namespace Bootstrap.Client.DataAccess.MongoDB
{
class RoleHelper
{
/// <summary>
///
/// </summary>
public const string RetrieveRolesDataKey = "RoleHelper-RetrieveRoles";
/// <summary>
/// 查询所有角色
/// </summary>
/// <returns></returns>
public static IEnumerable<Role> Retrieves() => CacheManager.GetOrAdd(RetrieveRolesDataKey, key => DbManager.Roles.Find(FilterDefinition<Role>.Empty).ToList());
/// <summary>
///
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public static IEnumerable<string> RetrievesByUserName(string userName)
{
var roles = new List<string>();
var user = UserHelper.Retrieves().FirstOrDefault(u => u.UserName.ToLowerInvariant() == userName.ToLowerInvariant());
if (user != null)
{
var role = Retrieves();
roles.AddRange(role.Where(r => user.Roles.Any(rl => rl == r.Id)).Select(r => r.RoleName));
if (roles.Count == 0) roles.Add("Default");
}
return roles;
}
}
}

View File

@ -0,0 +1,30 @@
using Longbow.Cache;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
namespace Bootstrap.Client.DataAccess.MongoDB
{
class UserHelper
{
/// <summary>
/// 获取所有用户缓存数据键值
/// </summary>
public const string RetrieveUsersDataKey = "UserHelper-RetrieveUsers";
/// <summary>
/// 查询所有用户
/// </summary>
/// <returns></returns>
public static IEnumerable<User> Retrieves() => CacheManager.GetOrAdd(RetrieveUsersDataKey, key =>
{
var project = Builders<User>.Projection.Include(u => u.Id)
.Include(u => u.UserName)
.Include(u => u.DisplayName)
.Include(u => u.Groups)
.Include(u => u.Roles)
.Include(u => u.ApprovedTime);
return DbManager.Users.Find(user => user.ApprovedTime != DateTime.MinValue).Project<User>(project).ToList();
});
}
}

View File

@ -0,0 +1,50 @@
using Bootstrap.Security;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Bootstrap.Client.DataAccess.MongoDB
{
/// <summary>
/// 菜单实体类
/// </summary>
public class Menu : DataAccess.Menu
{
/// <summary>
/// 通过当前用户名获得所有菜单
/// </summary>
/// <param name="userName">当前登录的用户名</param>
/// <returns></returns>
public override IEnumerable<BootstrapMenu> RetrieveAllMenus(string userName)
{
var user = UserHelper.Retrieves().Cast<User>().FirstOrDefault(u => u.UserName.ToLowerInvariant() == userName.ToLowerInvariant());
if (user == null) return Enumerable.Empty<BootstrapMenu>();
var roles = RoleHelper.Retrieves().Cast<Role>();
var groups = GroupHelper.Retrieves().Cast<Group>();
// 通过用户获取 组列表相关联的角色列表
var userRoles = user.Groups.Aggregate(user.Roles.ToList(), (r, g) =>
{
var groupRoles = groups.Where(group => group.Id == g).FirstOrDefault()?.Roles;
if (groupRoles != null) r.AddRange(groupRoles);
return r;
}).Distinct().ToList();
var allRoles = roles.Where(r => userRoles.Any(rl => rl == r.Id)).ToList();
var menus = DbManager.Menus.Find(FilterDefinition<BootstrapMenu>.Empty).ToList()
.Where(m => allRoles.Any(r => r.RoleName.Equals("Administrators", StringComparison.OrdinalIgnoreCase) || r.Menus.Any(rm => rm.Equals(m.Id, StringComparison.OrdinalIgnoreCase))))
.ToList();
var dicts = DictHelper.RetrieveDicts().Where(m => m.Category == "菜单");
menus.ForEach(m =>
{
m.CategoryName = dicts.FirstOrDefault(d => d.Code == m.Category)?.Name;
if (m.ParentId != "0") m.ParentName = menus.FirstOrDefault(p => p.Id == m.ParentId)?.Name;
});
return menus;
}
}
}

View File

@ -0,0 +1,69 @@
using MongoDB.Driver;
using System.Collections.Generic;
using System.Linq;
namespace Bootstrap.Client.DataAccess.MongoDB
{
/// <summary>
///
/// </summary>
public class Role : DataAccess.Role
{
/// <summary>
/// 此角色关联的所有菜单
/// </summary>
public IEnumerable<string> Menus { get; set; }
/// <summary>
/// 此角色关联的所有应用程序
/// </summary>
public IEnumerable<string> Apps { get; set; }
/// <summary>
/// 获得/设置 角色主键ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 获得/设置 角色名称
/// </summary>
public string RoleName { get; set; }
/// <summary>
/// 获得/设置 角色描述
/// </summary>
public string Description { get; set; }
/// <summary>
///
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public override IEnumerable<string> RetrievesByUserName(string userName)
{
var roles = new List<string>();
var user = UserHelper.Retrieves().Cast<User>().FirstOrDefault(u => u.UserName.ToLowerInvariant() == userName.ToLowerInvariant());
if (user != null)
{
var role = RoleHelper.Retrieves();
roles.AddRange(role.Where(r => user.Roles.Any(rl => rl == r.Id)).Select(r => r.RoleName));
if (roles.Count == 0) roles.Add("Default");
}
return roles;
}
/// <summary>
/// 根据菜单url查询某个所拥有的角色
/// 从NavigatorRole表查
/// 从Navigators -> GroupNavigatorRole -> Role查查询某个用户所拥有的角色
/// </summary>
/// <returns></returns>
public override IEnumerable<string> RetrievesByUrl(string url)
{
var menu = DbManager.Menus.Find(md => md.Url.StartsWith(url)).FirstOrDefault();
var ret = RoleHelper.Retrieves().Cast<Role>().Where(md => md.Menus != null && md.Menus.Contains(menu.Id)).Select(m => m.RoleName).ToList();
if (!ret.Contains("Administrators")) ret.Add("Administrators");
return ret;
}
}
}

View File

@ -0,0 +1,55 @@
using Bootstrap.Security;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
namespace Bootstrap.Client.DataAccess.MongoDB
{
/// <summary>
/// 用户表实体类
/// </summary>
public class User : DataAccess.User
{
/// <summary>
/// 获得/设置 用户主键ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 获得/设置 用户被批复时间
/// </summary>
public DateTime? ApprovedTime { get; set; }
/// <summary>
///
/// </summary>
public IEnumerable<string> Roles { get; set; }
/// <summary>
///
/// </summary>
public IEnumerable<string> Groups { get; set; }
/// <summary>
///
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public override BootstrapUser RetrieveUserByUserName(string userName)
{
var project = Builders<User>.Projection.Include(u => u.Id)
.Include(u => u.UserName)
.Include(u => u.DisplayName)
.Include(u => u.Icon)
.Include(u => u.Css)
.Include(u => u.App);
var ret = DbManager.Users.Find(user => user.UserName.ToLowerInvariant() == userName.ToLowerInvariant()).Project<User>(project).FirstOrDefault();
if (ret != null)
{
if (string.IsNullOrEmpty(ret.Icon)) ret.Icon = "default.jpg";
if (string.IsNullOrEmpty(ret.App)) ret.App = "0";
}
return ret;
}
}
}

View File

@ -0,0 +1,18 @@
using Bootstrap.Security.DataAccess;
using System.Collections.Generic;
namespace Bootstrap.Client.DataAccess
{
/// <summary>
///
/// </summary>
public class App
{
/// <summary>
/// 根据指定用户名获得授权应用程序集合
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public virtual IEnumerable<string> RetrievesByUserName(string userName) => DbHelper.RetrieveAppsByUserName(userName);
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Longbow.Data" Version="2.3.4" />
<PackageReference Include="Longbow.Logging" Version="2.2.12" />
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.13" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,25 @@
using PetaPoco;
using System;
using System.Collections.Specialized;
namespace Bootstrap.Client.DataAccess
{
/// <summary>
/// 数据库连接操作类
/// </summary>
internal static class DbManager
{
/// <summary>
/// 创建 IDatabase 实例方法
/// </summary>
/// <param name="connectionName">配置文件中配置的数据库连接字符串名称</param>
/// <param name="keepAlive">是否保持连接,默认为 false</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;
}
}
}

View File

@ -0,0 +1,116 @@
using Bootstrap.Security;
using Bootstrap.Security.DataAccess;
using Longbow;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Bootstrap.Client.DataAccess
{
/// <summary>
///
/// </summary>
public class Dict : BootstrapDict
{
/// <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 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>
/// 通过数据库获得所有字典表配置信息缓存Key=DictHelper-RetrieveDicts
/// </summary>
/// <returns></returns>
public virtual IEnumerable<BootstrapDict> RetrieveDicts() => DbHelper.RetrieveDicts();
/// <summary>
/// 获得 IP地理位置
/// </summary>
/// <returns></returns>
public string RetrieveLocaleIPSvr() => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "IP地理位置接口" && d.Define == 0)?.Code;
/// <summary>
///
/// </summary>
/// <returns></returns>
public string RetrieveLocaleIPSvrCachePeriod() => 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>
/// 获得 是否为演示系统 默认为 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/";
/// <summary>
/// 获得 数据库标题是否显示
/// </summary>
/// <returns></returns>
public bool RetrieveCardTitleStatus() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "网站设置" && d.Name == "卡片标题状态" && d.Define == 0)?.Code ?? "1") == "1";
/// <summary>
/// 获得 是否显示侧边栏 为真时显示
/// </summary>
/// <returns></returns>
public bool RetrieveSidebarStatus() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "网站设置" && d.Name == "侧边栏状态" && d.Define == 0)?.Code ?? "1") == "1";
/// <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>
/// 获取头像路径
/// </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>
/// 获得系统设置地址
/// </summary>
/// <returns></returns>
public virtual string RetrieveSettingsUrl() => DbHelper.RetrieveSettingsUrl();
/// <summary>
/// 获得系统个人中心地址
/// </summary>
/// <returns></returns>
public virtual string RetrieveProfilesUrl() => DbHelper.RetrieveProfilesUrl();
/// <summary>
/// 获得系统通知地址地址
/// </summary>
/// <returns></returns>
public virtual string RetrieveNotisUrl() => DbHelper.RetrieveNotisUrl();
}
}

View File

@ -0,0 +1,20 @@
using Bootstrap.Security.DataAccess;
using Longbow.Cache;
using Longbow.Data;
using System.Collections.Generic;
namespace Bootstrap.Client.DataAccess
{
/// <summary>
///
/// </summary>
public static class AppHelper
{
/// <summary>
/// 根据指定用户名获得授权应用程序集合
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public static IEnumerable<string> RetrievesByUserName(string userName) => CacheManager.GetOrAdd($"{DbHelper.RetrieveAppsByUserNameDataKey}-{userName}", key => DbContextManager.Create<App>().RetrievesByUserName(userName), DbHelper.RetrieveAppsByUserNameDataKey);
}
}

View File

@ -0,0 +1,119 @@
using Bootstrap.Security;
using Bootstrap.Security.DataAccess;
using Longbow.Cache;
using Longbow.Data;
using System.Collections.Generic;
namespace Bootstrap.Client.DataAccess
{
/// <summary>
///
/// </summary>
public static class DictHelper
{
/// <summary>
///
/// </summary>
/// <summary>
/// 缓存索引BootstrapAdmin后台清理缓存时使用
/// </summary>
public const string RetrieveDictsDataKey = DbHelper.RetrieveDictsDataKey;
/// <summary>
///
/// </summary>
/// <returns></returns>
public static IEnumerable<BootstrapDict> RetrieveDicts() => CacheManager.GetOrAdd(RetrieveDictsDataKey, key => DbContextManager.Create<Dict>().RetrieveDicts());
/// <summary>
///
/// </summary>
/// <returns></returns>
public static IEnumerable<KeyValuePair<string, string>> RetrieveApps() => DbContextManager.Create<Dict>().RetrieveApps();
/// <summary>
///
/// </summary>
/// <returns></returns>
public static string RetrieveWebTitle() => DbContextManager.Create<Dict>().RetrieveWebTitle();
/// <summary>
///
/// </summary>
/// <returns></returns>
public static string RetrieveWebFooter() => DbContextManager.Create<Dict>().RetrieveWebFooter();
/// <summary>
/// 获得网站设置中的当前样式
/// </summary>
/// <returns></returns>
public static string RetrieveActiveTheme() => DbContextManager.Create<Dict>().RetrieveActiveTheme();
/// <summary>
///
/// </summary>
/// <returns></returns>
public static string RetrieveLocaleIPSvr() => DbContextManager.Create<Dict>().RetrieveLocaleIPSvr();
/// <summary>
///
/// </summary>
/// <param name="ipSvr">ip地址请求服务名称</param>
/// <returns></returns>
public static string RetrieveLocaleIPSvrUrl(string ipSvr) => DbContextManager.Create<Dict>().RetrieveLocaleIPSvrUrl(ipSvr);
/// <summary>
///
/// </summary>
/// <returns></returns>
public static string RetrieveLocaleIPSvrCachePeriod() => DbContextManager.Create<Dict>().RetrieveLocaleIPSvrCachePeriod();
/// <summary>
/// 获得 是否为演示系统 默认为 false 不是演示系统
/// </summary>
/// <returns></returns>
public static bool RetrieveSystemModel() => DbContextManager.Create<Dict>().RetrieveSystemModel();
/// <summary>
/// 获得验证码图床地址
/// </summary>
/// <returns></returns>
public static string RetrieveImagesLibUrl() => DbContextManager.Create<Dict>().RetrieveImagesLibUrl();
/// <summary>
/// 获取头像路径
/// </summary>
/// <returns></returns>
public static string RetrieveIconFolderPath() => DbContextManager.Create<Dict>().RetrieveIconFolderPath();
/// <summary>
/// 获得数据区卡片标题是否显示
/// </summary>
/// <returns></returns>
public static bool RetrieveCardTitleStatus() => DbContextManager.Create<Dict>().RetrieveCardTitleStatus();
/// <summary>
/// 获得侧边栏状态 未真时显示
/// </summary>
/// <returns></returns>
public static bool RetrieveSidebarStatus() => DbContextManager.Create<Dict>().RetrieveSidebarStatus();
/// <summary>
/// 获得系统设置地址
/// </summary>
/// <returns></returns>
public static string RetrieveSettingsUrl() => DbContextManager.Create<Dict>().RetrieveSettingsUrl();
/// <summary>
/// 获得系统个人中心地址
/// </summary>
/// <returns></returns>
public static string RetrieveProfilesUrl() => DbContextManager.Create<Dict>().RetrieveProfilesUrl();
/// <summary>
/// 获得系统通知地址地址
/// </summary>
/// <returns></returns>
public static string RetrieveNotisUrl() => DbContextManager.Create<Dict>().RetrieveNotisUrl();
}
}

View File

@ -0,0 +1,41 @@
using Bootstrap.Security;
using Bootstrap.Security.DataAccess;
using Longbow.Cache;
using Longbow.Configuration;
using Longbow.Data;
using System.Collections.Generic;
using System.Linq;
namespace Bootstrap.Client.DataAccess
{
/// <summary>
/// 菜单操作类
/// </summary>
public static class MenuHelper
{
/// <summary>
/// 通过当前用户获取所有菜单数据缓存键名称 "BootstrapMenu-RetrieveMenus"
/// </summary>
public const string RetrieveMenusAll = DbHelper.RetrieveMenusAll;
/// <summary>
/// 获取指定用户的应用程序菜单
/// </summary>
/// <param name="userName"></param>
/// <param name="activeUrl"></param>
/// <returns></returns>
public static IEnumerable<BootstrapMenu> RetrieveAppMenus(string userName, string activeUrl)
{
var appId = ConfigurationManager.GetValue("AppId", "");
var menus = RetrieveAllMenus(userName).Where(m => m.Category == "1" && m.IsResource == 0 && m.Application == appId);
return DbHelper.CascadeMenus(menus, activeUrl);
}
/// <summary>
/// 通过用户获得所有菜单
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public static IEnumerable<BootstrapMenu> RetrieveAllMenus(string userName) => CacheManager.GetOrAdd($"{RetrieveMenusAll}-{userName}", key => DbContextManager.Create<Menu>().RetrieveAllMenus(userName), RetrieveMenusAll);
}
}

View File

@ -0,0 +1,27 @@
using Bootstrap.Security.DataAccess;
using Longbow.Cache;
using Longbow.Data;
using System.Collections.Generic;
namespace Bootstrap.Client.DataAccess
{
/// <summary>
///
/// </summary>
public static class RoleHelper
{
/// <summary>
///
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public static IEnumerable<string> RetrievesByUserName(string userName) => CacheManager.GetOrAdd(string.Format("{0}-{1}", DbHelper.RetrieveRolesByUserNameDataKey, userName), key => DbContextManager.Create<Role>().RetrievesByUserName(userName), DbHelper.RetrieveRolesByUserNameDataKey);
/// <summary>
///
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static IEnumerable<string> RetrievesByUrl(string url) => CacheManager.GetOrAdd(string.Format("{0}-{1}", DbHelper.RetrieveRolesByUrlDataKey, url), key => DbContextManager.Create<Role>().RetrievesByUrl(url), DbHelper.RetrieveRolesByUrlDataKey);
}
}

View File

@ -0,0 +1,20 @@
using Bootstrap.Security;
using Bootstrap.Security.DataAccess;
using Longbow.Cache;
using Longbow.Data;
namespace Bootstrap.Client.DataAccess
{
/// <summary>
/// 用户表相关操作类
/// </summary>
public static class UserHelper
{
/// <summary>
/// 通过登录名获取登录用户方法
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public static BootstrapUser RetrieveUserByUserName(string userName) => CacheManager.GetOrAdd(string.Format("{0}-{1}", DbHelper.RetrieveUsersByNameDataKey, userName), k => DbContextManager.Create<User>().RetrieveUserByUserName(userName), DbHelper.RetrieveUsersByNameDataKey);
}
}

View File

@ -0,0 +1,19 @@
using Bootstrap.Security;
using Bootstrap.Security.DataAccess;
using System.Collections.Generic;
namespace Bootstrap.Client.DataAccess
{
/// <summary>
/// 菜单实体类
/// </summary>
public class Menu : BootstrapMenu
{
/// <summary>
/// 通过当前用户名获得所有菜单
/// </summary>
/// <param name="userName">当前登录的用户名</param>
/// <returns></returns>
public virtual IEnumerable<BootstrapMenu> RetrieveAllMenus(string userName) => DbHelper.RetrieveAllMenus(userName);
}
}

View File

@ -0,0 +1,26 @@
using Bootstrap.Security.DataAccess;
using System.Collections.Generic;
namespace Bootstrap.Client.DataAccess
{
/// <summary>
///
/// </summary>
public class Role
{
/// <summary>
///
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public virtual IEnumerable<string> RetrievesByUserName(string userName) => DbHelper.RetrieveRolesByUserName(userName);
/// <summary>
/// 根据菜单url查询某个所拥有的角色
/// 从NavigatorRole表查
/// 从Navigators -> GroupNavigatorRole -> Role查查询某个用户所拥有的角色
/// </summary>
/// <returns></returns>
public virtual IEnumerable<string> RetrievesByUrl(string url) => DbHelper.RetrieveRolesByUrl(url);
}
}

View File

@ -0,0 +1,18 @@
using Bootstrap.Security;
using Bootstrap.Security.DataAccess;
namespace Bootstrap.Client.DataAccess
{
/// <summary>
/// 用户表实体类
/// </summary>
public class User : BootstrapUser
{
/// <summary>
///
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public virtual BootstrapUser RetrieveUserByUserName(string userName) => DbHelper.RetrieveUserByUserName(userName);
}
}

View File

@ -15,4 +15,8 @@
<PackageReference Include="Longbow.Cache" Version="2.2.14" /> <PackageReference Include="Longbow.Cache" Version="2.2.14" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Bootstrap.Client.DataAccess\Bootstrap.Client.DataAccess.csproj" />
</ItemGroup>
</Project> </Project>

View File

@ -1,4 +1,5 @@
using Bootstrap.Security.DataAccess; using Bootstrap.Client.DataAccess;
using Bootstrap.Security.DataAccess;
using Longbow.Configuration; using Longbow.Configuration;
using Microsoft.AspNetCore; using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
@ -18,12 +19,12 @@ namespace Bootstrap.Client.Models
/// <param name="identity"></param> /// <param name="identity"></param>
public HeaderBarModel(IIdentity identity) public HeaderBarModel(IIdentity identity)
{ {
var user = DbHelper.RetrieveUserByUserNameWithCache(identity.Name); var user = UserHelper.RetrieveUserByUserName(identity.Name);
DisplayName = user.DisplayName; DisplayName = user.DisplayName;
UserName = user.UserName; UserName = user.UserName;
SettingsUrl = DbHelper.RetrieveSettingsUrl(); SettingsUrl = DictHelper.RetrieveSettingsUrl();
ProfilesUrl = DbHelper.RetrieveProfilesUrl(); ProfilesUrl = DictHelper.RetrieveProfilesUrl();
NotisUrl = DbHelper.RetrieveNotisUrl(); NotisUrl = DictHelper.RetrieveNotisUrl();
// set LogoutUrl // set LogoutUrl
var authHost = ConfigurationManager.Get<BootstrapAdminAuthenticationOptions>().AuthHost; var authHost = ConfigurationManager.Get<BootstrapAdminAuthenticationOptions>().AuthHost;
@ -32,7 +33,7 @@ namespace Bootstrap.Client.Models
LogoutUrl = uriBuilder.ToString(); LogoutUrl = uriBuilder.ToString();
// set Icon // set Icon
var icon = $"/{DbHelper.RetrieveIconFolderPath().Trim('~', '/')}/{user.Icon}"; var icon = $"/{DictHelper.RetrieveIconFolderPath().Trim('~', '/')}/{user.Icon}";
Icon = string.IsNullOrEmpty(ConfigurationManager.GetValue("SimulateUserName", string.Empty)) ? $"{authHost.TrimEnd('/')}{icon}" : "/images/admin.jpg"; Icon = string.IsNullOrEmpty(ConfigurationManager.GetValue("SimulateUserName", string.Empty)) ? $"{authHost.TrimEnd('/')}{icon}" : "/images/admin.jpg";
if (!string.IsNullOrEmpty(user.Css)) Theme = user.Css; if (!string.IsNullOrEmpty(user.Css)) Theme = user.Css;
} }

View File

@ -1,4 +1,4 @@
using Bootstrap.Security.DataAccess; using Bootstrap.Client.DataAccess;
namespace Bootstrap.Client.Models namespace Bootstrap.Client.Models
{ {
@ -12,9 +12,9 @@ namespace Bootstrap.Client.Models
/// </summary> /// </summary>
public ModelBase() public ModelBase()
{ {
Title = DbHelper.RetrieveTitle(); Title = DictHelper.RetrieveWebTitle();
Footer = DbHelper.RetrieveFooter(); Footer = DictHelper.RetrieveWebFooter();
Theme = DbHelper.RetrieveActiveTheme(); Theme = DictHelper.RetrieveActiveTheme();
} }
/// <summary> /// <summary>

View File

@ -1,5 +1,6 @@
using Bootstrap.Security; using Bootstrap.Client.DataAccess;
using Bootstrap.Security.DataAccess; using Bootstrap.Security;
using Longbow.Configuration;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; using System.Collections.Generic;
@ -16,8 +17,8 @@ namespace Bootstrap.Client.Models
/// <param name="controller"></param> /// <param name="controller"></param>
public NavigatorBarModel(ControllerBase controller) : base(controller.User.Identity) public NavigatorBarModel(ControllerBase controller) : base(controller.User.Identity)
{ {
Navigations = DbHelper.RetrieveAppCascadeMenus(UserName, $"~/{controller.ControllerContext.ActionDescriptor.ControllerName}/{controller.ControllerContext.ActionDescriptor.ActionName}"); Navigations = MenuHelper.RetrieveAppMenus(UserName, $"~/{controller.ControllerContext.ActionDescriptor.ControllerName}/{controller.ControllerContext.ActionDescriptor.ActionName}");
ImageLibUrl = DbHelper.RetrieveImagesLibUrl(); ImageLibUrl = DictHelper.RetrieveImagesLibUrl();
} }
/// <summary> /// <summary>

View File

@ -1,4 +1,5 @@
using Longbow.Web; using Bootstrap.Client.DataAccess;
using Longbow.Web;
using Longbow.Web.SignalR; using Longbow.Web.SignalR;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
@ -88,7 +89,7 @@ namespace Bootstrap.Client
app.UseResponseCompression(); app.UseResponseCompression();
app.UseStaticFiles(); app.UseStaticFiles();
app.UseCookiePolicy(); app.UseCookiePolicy();
app.UseBootstrapAdminAuthentication(); app.UseBootstrapAdminAuthentication(RoleHelper.RetrievesByUserName, RoleHelper.RetrievesByUrl, AppHelper.RetrievesByUserName);
app.UseCacheManager(); app.UseCacheManager();
app.UseSignalR(routes => { routes.MapHub<SignalRHub>("/NotiHub"); }); app.UseSignalR(routes => { routes.MapHub<SignalRHub>("/NotiHub"); });
app.UseMvc(routes => app.UseMvc(routes =>

View File

@ -16,7 +16,8 @@
} }
}, },
"ConnectionStrings": { "ConnectionStrings": {
"ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa" "ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa",
"client": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa"
}, },
"DB": [ "DB": [
{ {
@ -26,7 +27,17 @@
"Enabled": true, "Enabled": true,
"ProviderName": "Sqlite", "ProviderName": "Sqlite",
"ConnectionStrings": { "ConnectionStrings": {
"ba": "Data Source=..\\Bootstrap.Admin\\BootstrapAdmin.db;" "ba": "Data Source=..\\Bootstrap.Admin\\BootstrapAdmin.db;",
"client": "Data Source=Client.db;"
}
},
{
"Enabled": false,
"Widget": "Bootstrap.Client.DataAccess.MongoDB",
"ProviderName": "MongoDB",
"ConnectionStrings": {
"ba": "mongodb://localhost:27017;Database=BootstrapAdmin",
"client": "mongodb://localhost:27017;Database=BootstrapClient"
} }
} }
], ],

View File

@ -13,8 +13,8 @@
} }
}, },
"ConnectionStrings": { "ConnectionStrings": {
"sql": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa", "ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa",
"ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa" "client": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa"
}, },
"DB": [ "DB": [
{ {
@ -24,7 +24,16 @@
"Enabled": true, "Enabled": true,
"ProviderName": "Sqlite", "ProviderName": "Sqlite",
"ConnectionStrings": { "ConnectionStrings": {
"ba": "Data Source=..\\BA\\BootstrapAdmin.db;" "ba": "Data Source=..\\BA\\BootstrapAdmin.db;",
"client": "Data Source=Client.db;"
}
},
{
"Enabled": false,
"Widget": "Bootstrap.Client.DataAccess.MongoDB",
"ProviderName": "MongoDB",
"ConnectionStrings": {
"ba": "mongodb://localhost:27017;Database=BootstrapAdmin"
} }
} }
], ],
@ -78,6 +87,27 @@
"SlidingExpiration": true, "SlidingExpiration": true,
"Desc": "用户所有菜单数据缓存" "Desc": "用户所有菜单数据缓存"
}, },
{
"Enabled": true,
"Key": "RoleHelper-RetrieveRoles",
"Interval": 600000,
"SlidingExpiration": true,
"Desc": "所有角色数据"
},
{
"Enabled": true,
"Key": "GroupHelper-RetrieveGroups",
"Interval": 600000,
"SlidingExpiration": true,
"Desc": "所有部门数据"
},
{
"Enabled": true,
"Key": "UserHelper-RetrieveUsers",
"Interval": 600000,
"SlidingExpiration": true,
"Desc": "所有用户数据"
},
{ {
"Enabled": true, "Enabled": true,
"Key": "GroupHelper-RetrieveGroupsByUserName", "Key": "GroupHelper-RetrieveGroupsByUserName",
@ -87,4 +117,4 @@
} }
] ]
} }
} }

View File

@ -9,7 +9,7 @@ using MongoDB.Driver;
namespace Bootstrap.DataAccess.MongoDB namespace Bootstrap.DataAccess.MongoDB
{ {
/// <summary> /// <summary>
/// /// 数据库操作类
/// </summary> /// </summary>
internal static class DbManager internal static class DbManager
{ {
@ -18,7 +18,7 @@ namespace Bootstrap.DataAccess.MongoDB
private static readonly object _locker = new object(); private static readonly object _locker = new object();
/// <summary> /// <summary>
/// /// IMongoDatabase 实例
/// </summary> /// </summary>
private static IMongoDatabase DBAccess private static IMongoDatabase DBAccess
{ {
@ -34,7 +34,8 @@ namespace Bootstrap.DataAccess.MongoDB
ChangeToken.OnChange(() => ConfigurationManager.AppSettings.GetReloadToken(), () => _db = null); ChangeToken.OnChange(() => ConfigurationManager.AppSettings.GetReloadToken(), () => _db = null);
InitClassMap(); InitClassMap();
} }
InitDb(); if (_db == null)
InitDb();
} }
} }
return _db; return _db;
@ -43,7 +44,7 @@ namespace Bootstrap.DataAccess.MongoDB
#region Collections #region Collections
/// <summary> /// <summary>
/// /// Logs 集合
/// </summary> /// </summary>
public static IMongoCollection<DataAccess.Log> Logs public static IMongoCollection<DataAccess.Log> Logs
{ {
@ -54,7 +55,7 @@ namespace Bootstrap.DataAccess.MongoDB
} }
/// <summary> /// <summary>
/// /// Exceptions 集合
/// </summary> /// </summary>
public static IMongoCollection<DataAccess.Exceptions> Exceptions public static IMongoCollection<DataAccess.Exceptions> Exceptions
{ {
@ -64,7 +65,7 @@ namespace Bootstrap.DataAccess.MongoDB
} }
} }
/// <summary> /// <summary>
/// /// Dicts 集合
/// </summary> /// </summary>
public static IMongoCollection<BootstrapDict> Dicts public static IMongoCollection<BootstrapDict> Dicts
{ {
@ -75,7 +76,7 @@ namespace Bootstrap.DataAccess.MongoDB
} }
/// <summary> /// <summary>
/// /// Users 集合
/// </summary> /// </summary>
public static IMongoCollection<User> Users public static IMongoCollection<User> Users
{ {
@ -86,7 +87,7 @@ namespace Bootstrap.DataAccess.MongoDB
} }
/// <summary> /// <summary>
/// /// Groups 集合
/// </summary> /// </summary>
public static IMongoCollection<Group> Groups public static IMongoCollection<Group> Groups
{ {
@ -97,7 +98,7 @@ namespace Bootstrap.DataAccess.MongoDB
} }
/// <summary> /// <summary>
/// /// Roles 集合
/// </summary> /// </summary>
public static IMongoCollection<Role> Roles public static IMongoCollection<Role> Roles
{ {
@ -108,7 +109,7 @@ namespace Bootstrap.DataAccess.MongoDB
} }
/// <summary> /// <summary>
/// /// Menus 集合
/// </summary> /// </summary>
public static IMongoCollection<BootstrapMenu> Menus public static IMongoCollection<BootstrapMenu> Menus
{ {
@ -119,7 +120,7 @@ namespace Bootstrap.DataAccess.MongoDB
} }
/// <summary> /// <summary>
/// /// LoginUsers 集合
/// </summary> /// </summary>
public static IMongoCollection<DataAccess.LoginUser> LoginUsers public static IMongoCollection<DataAccess.LoginUser> LoginUsers
{ {
@ -130,7 +131,7 @@ namespace Bootstrap.DataAccess.MongoDB
} }
/// <summary> /// <summary>
/// /// ResetUsers 集合
/// </summary> /// </summary>
public static IMongoCollection<DataAccess.ResetUser> ResetUsers public static IMongoCollection<DataAccess.ResetUser> ResetUsers
{ {
@ -141,7 +142,7 @@ namespace Bootstrap.DataAccess.MongoDB
} }
/// <summary> /// <summary>
/// /// Traces 集合
/// </summary> /// </summary>
public static IMongoCollection<DataAccess.Trace> Traces public static IMongoCollection<DataAccess.Trace> Traces
{ {
@ -152,7 +153,7 @@ namespace Bootstrap.DataAccess.MongoDB
} }
/// <summary> /// <summary>
/// /// RejectUsers 集合
/// </summary> /// </summary>
public static IMongoCollection<RejectUser> RejectUsers public static IMongoCollection<RejectUser> RejectUsers
{ {
@ -163,7 +164,7 @@ namespace Bootstrap.DataAccess.MongoDB
} }
/// <summary> /// <summary>
/// /// Messages 集合
/// </summary> /// </summary>
public static IMongoCollection<DataAccess.Message> Messages public static IMongoCollection<DataAccess.Message> Messages
{ {
@ -174,7 +175,7 @@ namespace Bootstrap.DataAccess.MongoDB
} }
/// <summary> /// <summary>
/// /// Tasks 集合
/// </summary> /// </summary>
public static IMongoCollection<DataAccess.Task> Tasks public static IMongoCollection<DataAccess.Task> Tasks
{ {
@ -187,8 +188,9 @@ namespace Bootstrap.DataAccess.MongoDB
private static void InitDb() private static void InitDb()
{ {
var client = new MongoClient(Longbow.Data.DbManager.GetConnectionString()); var (connectString, databaseName) = Longbow.Data.DbManager.GetMongoDB();
_db = client.GetDatabase(ConfigurationManager.AppSettings["MongoDB"]); var client = new MongoClient(connectString);
_db = client.GetDatabase(databaseName);
} }
private static void InitClassMap() private static void InitClassMap()

View File

@ -21,21 +21,23 @@ namespace Bootstrap.DataAccess.MongoDB
var user = UserHelper.Retrieves().Cast<User>().FirstOrDefault(u => u.UserName.ToLowerInvariant() == userName.ToLowerInvariant()); var user = UserHelper.Retrieves().Cast<User>().FirstOrDefault(u => u.UserName.ToLowerInvariant() == userName.ToLowerInvariant());
if (user == null) return Enumerable.Empty<BootstrapMenu>(); if (user == null) return Enumerable.Empty<BootstrapMenu>();
var dicts = DictHelper.RetrieveDicts().Where(m => m.Category == "菜单"); var roles = RoleHelper.Retrieves().Cast<Role>();
var groups = GroupHelper.Retrieves().Cast<Group>();
// 通过用户获取 角色列表
var roles = RoleHelper.Retrieves().Cast<Role>().Where(r => user.Roles.Any(rl => rl == r.Id)).ToList();
// 通过用户获取 组列表相关联的角色列表 // 通过用户获取 组列表相关联的角色列表
roles = GroupHelper.RetrievesByUserName(userName).Aggregate(roles, (r, g) => var userRoles = user.Groups.Aggregate(user.Roles.ToList(), (r, g) =>
{ {
r.AddRange(RoleHelper.RetrievesByGroupId(g.Id).Cast<Role>()); var groupRoles = groups.Where(group => group.Id == g).FirstOrDefault()?.Roles;
if (groupRoles != null) r.AddRange(groupRoles);
return r; return r;
}).Distinct().ToList(); }).Distinct().ToList();
var allRoles = roles.Where(r => userRoles.Any(rl => rl == r.Id)).ToList();
var menus = DbManager.Menus.Find(FilterDefinition<BootstrapMenu>.Empty).ToList() var menus = DbManager.Menus.Find(FilterDefinition<BootstrapMenu>.Empty).ToList()
.Where(m => roles.Any(r => r.RoleName.Equals("Administrators", StringComparison.OrdinalIgnoreCase) || r.Menus.Any(rm => rm.Equals(m.Id, StringComparison.OrdinalIgnoreCase)))) .Where(m => allRoles.Any(r => r.RoleName.Equals("Administrators", StringComparison.OrdinalIgnoreCase) || r.Menus.Any(rm => rm.Equals(m.Id, StringComparison.OrdinalIgnoreCase))))
.ToList(); .ToList();
var dicts = DictHelper.RetrieveDicts().Where(m => m.Category == "菜单");
menus.ForEach(m => menus.ForEach(m =>
{ {
m.CategoryName = dicts.FirstOrDefault(d => d.Code == m.Category)?.Name; m.CategoryName = dicts.FirstOrDefault(d => d.Code == m.Category)?.Name;

View File

@ -6,7 +6,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.2.12" /> <PackageReference Include="Bootstrap.Security.DataAccess" Version="2.2.12" />
<PackageReference Include="Longbow.Data" Version="2.3.3" /> <PackageReference Include="Longbow.Data" Version="2.3.4" />
<PackageReference Include="Longbow.Logging" Version="2.2.12" /> <PackageReference Include="Longbow.Logging" Version="2.2.12" />
<PackageReference Include="Longbow.PetaPoco" Version="1.0.2" /> <PackageReference Include="Longbow.PetaPoco" Version="1.0.2" />
<PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" /> <PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" />

View File

@ -35,6 +35,8 @@ namespace Bootstrap.DataAccess
cacheKeys.Add(RoleHelper.RetrieveRolesDataKey + "*"); cacheKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*"); cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*");
cacheKeys.Add(RetrieveAllRolesDataKey + "*"); cacheKeys.Add(RetrieveAllRolesDataKey + "*");
corsKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
corsKeys.Add(GroupHelper.RetrieveGroupsDataKey + "*");
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*"); corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
} }
if (userIds != null) if (userIds != null)
@ -59,8 +61,10 @@ namespace Bootstrap.DataAccess
}); });
cacheKeys.Add(GroupHelper.RetrieveGroupsDataKey + "*"); cacheKeys.Add(GroupHelper.RetrieveGroupsDataKey + "*");
cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*"); cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*");
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
cacheKeys.Add(RetrieveAllRolesDataKey + "*"); cacheKeys.Add(RetrieveAllRolesDataKey + "*");
corsKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
corsKeys.Add(GroupHelper.RetrieveGroupsDataKey + "*");
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
} }
if (menuIds != null) if (menuIds != null)
{ {
@ -70,6 +74,8 @@ namespace Bootstrap.DataAccess
}); });
cacheKeys.Add(MenuHelper.RetrieveMenusByRoleIdDataKey + "*"); cacheKeys.Add(MenuHelper.RetrieveMenusByRoleIdDataKey + "*");
cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*"); cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*");
corsKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
corsKeys.Add(GroupHelper.RetrieveGroupsDataKey + "*");
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*"); corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
} }
if (appIds != null) if (appIds != null)

View File

@ -61,13 +61,13 @@ namespace Bootstrap.DataAccess
public virtual IEnumerable<string> RetrieveCategories() => DictHelper.RetrieveDicts().OrderBy(d => d.Category).Select(d => d.Category).Distinct(); public virtual IEnumerable<string> RetrieveCategories() => DictHelper.RetrieveDicts().OrderBy(d => d.Category).Select(d => d.Category).Distinct();
/// <summary> /// <summary>
/// /// 获取系统网站标题
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual string RetrieveWebTitle() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站标题" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "后台管理系统" }).Code; public virtual string RetrieveWebTitle() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站标题" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "后台管理系统" }).Code;
/// <summary> /// <summary>
/// /// 获取系统网站页脚
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual string RetrieveWebFooter() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站页脚" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "2016 © 通用后台管理系统" }).Code; public virtual string RetrieveWebFooter() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站页脚" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "2016 © 通用后台管理系统" }).Code;

View File

@ -28,6 +28,7 @@ namespace Bootstrap.DataAccess
/// ///
/// </summary> /// </summary>
public const string RetrieveRolesByGroupIdDataKey = "RoleHelper-RetrieveRolesByGroupId"; public const string RetrieveRolesByGroupIdDataKey = "RoleHelper-RetrieveRolesByGroupId";
/// <summary> /// <summary>
/// 查询所有角色 /// 查询所有角色
/// </summary> /// </summary>

View File

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15 # Visual Studio Version 16
VisualStudioVersion = 15.0.28307.705 VisualStudioVersion = 16.0.29215.179
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SQLServer", "SQLServer", "{87319AF5-7C40-4362-B67C-35F9DD737DB4}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SQLServer", "SQLServer", "{87319AF5-7C40-4362-B67C-35F9DD737DB4}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
@ -64,6 +64,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Postgresql", "Postgresql",
DatabaseScripts\Postgresql\install.sql = DatabaseScripts\Postgresql\install.sql DatabaseScripts\Postgresql\install.sql = DatabaseScripts\Postgresql\install.sql
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bootstrap.Client.DataAccess", "Bootstrap.Client.DataAccess\Bootstrap.Client.DataAccess.csproj", "{843811A2-FE49-410F-BF9F-9F1FB14A1DEE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bootstrap.Client.DataAccess.MongoDB", "Bootstrap.Client.DataAccess.MongoDB\Bootstrap.Client.DataAccess.MongoDB.csproj", "{BC1C6D63-ADA9-4C3B-89F0-CEB191A86BF5}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -90,6 +94,14 @@ Global
{CFE75C48-F9D5-403A-8419-D07939BBD769}.Debug|Any CPU.Build.0 = Debug|Any CPU {CFE75C48-F9D5-403A-8419-D07939BBD769}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CFE75C48-F9D5-403A-8419-D07939BBD769}.Release|Any CPU.ActiveCfg = Release|Any CPU {CFE75C48-F9D5-403A-8419-D07939BBD769}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CFE75C48-F9D5-403A-8419-D07939BBD769}.Release|Any CPU.Build.0 = Release|Any CPU {CFE75C48-F9D5-403A-8419-D07939BBD769}.Release|Any CPU.Build.0 = Release|Any CPU
{843811A2-FE49-410F-BF9F-9F1FB14A1DEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{843811A2-FE49-410F-BF9F-9F1FB14A1DEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{843811A2-FE49-410F-BF9F-9F1FB14A1DEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{843811A2-FE49-410F-BF9F-9F1FB14A1DEE}.Release|Any CPU.Build.0 = Release|Any CPU
{BC1C6D63-ADA9-4C3B-89F0-CEB191A86BF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC1C6D63-ADA9-4C3B-89F0-CEB191A86BF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC1C6D63-ADA9-4C3B-89F0-CEB191A86BF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC1C6D63-ADA9-4C3B-89F0-CEB191A86BF5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -101,6 +113,8 @@ Global
{A06A0AD8-A246-4329-B024-7174AE4A3EDE} = {586410F2-C1F0-47CD-AB28-2CF506DED2C8} {A06A0AD8-A246-4329-B024-7174AE4A3EDE} = {586410F2-C1F0-47CD-AB28-2CF506DED2C8}
{084E2E94-6B7D-4D3E-9BF1-6972427FBF80} = {586410F2-C1F0-47CD-AB28-2CF506DED2C8} {084E2E94-6B7D-4D3E-9BF1-6972427FBF80} = {586410F2-C1F0-47CD-AB28-2CF506DED2C8}
{6F61C2AC-84D4-48A9-8A48-680657CC8175} = {586410F2-C1F0-47CD-AB28-2CF506DED2C8} {6F61C2AC-84D4-48A9-8A48-680657CC8175} = {586410F2-C1F0-47CD-AB28-2CF506DED2C8}
{843811A2-FE49-410F-BF9F-9F1FB14A1DEE} = {C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0}
{BC1C6D63-ADA9-4C3B-89F0-CEB191A86BF5} = {C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {221EAE38-5F75-4391-9A48-E462A9F3B8FC} SolutionGuid = {221EAE38-5F75-4391-9A48-E462A9F3B8FC}