!27 增加功能:Bootstrap.Client 增加对 MongoDB 支持
Merge pull request !27 from Argo/dev-Mongo
This commit is contained in:
commit
5d083bcd7f
|
@ -12,7 +12,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.13" />
|
||||
<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.Mvc.Versioning" Version="3.1.6" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" PrivateAssets="All" />
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
"ConnectionStrings": {
|
||||
"ba": "Data Source=.;Initial Catalog=BootstrapAdmin;User ID=sa;Password=sa"
|
||||
},
|
||||
"MongoDB": "BootstrapAdmin",
|
||||
"DB": [
|
||||
{
|
||||
"Enabled": false
|
||||
|
@ -28,25 +27,25 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Enabled": false,
|
||||
"ProviderName": "MySql",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Server=localhost;Database=BA;Uid=argozhang;Pwd=argo@163.com;SslMode=none;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Enabled": false,
|
||||
"ProviderName": "Npgsql",
|
||||
"ConnectionStrings": {
|
||||
"ba": "Server=localhost;Database=BootstrapAdmin;User ID=argozhang;Password=argo@163.com;"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Enabled": false,
|
||||
"Widget": "Bootstrap.DataAccess.MongoDB",
|
||||
"ProviderName": "MongoDB",
|
||||
"ConnectionStrings": {
|
||||
"ba": "mongodb://localhost:27017"
|
||||
"ba": "mongodb://localhost:27017;Database=BootstrapAdmin"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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("系统通知地址");
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -15,4 +15,8 @@
|
|||
<PackageReference Include="Longbow.Cache" Version="2.2.14" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Bootstrap.Client.DataAccess\Bootstrap.Client.DataAccess.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Bootstrap.Security.DataAccess;
|
||||
using Bootstrap.Client.DataAccess;
|
||||
using Bootstrap.Security.DataAccess;
|
||||
using Longbow.Configuration;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
|
@ -18,12 +19,12 @@ namespace Bootstrap.Client.Models
|
|||
/// <param name="identity"></param>
|
||||
public HeaderBarModel(IIdentity identity)
|
||||
{
|
||||
var user = DbHelper.RetrieveUserByUserNameWithCache(identity.Name);
|
||||
var user = UserHelper.RetrieveUserByUserName(identity.Name);
|
||||
DisplayName = user.DisplayName;
|
||||
UserName = user.UserName;
|
||||
SettingsUrl = DbHelper.RetrieveSettingsUrl();
|
||||
ProfilesUrl = DbHelper.RetrieveProfilesUrl();
|
||||
NotisUrl = DbHelper.RetrieveNotisUrl();
|
||||
SettingsUrl = DictHelper.RetrieveSettingsUrl();
|
||||
ProfilesUrl = DictHelper.RetrieveProfilesUrl();
|
||||
NotisUrl = DictHelper.RetrieveNotisUrl();
|
||||
|
||||
// set LogoutUrl
|
||||
var authHost = ConfigurationManager.Get<BootstrapAdminAuthenticationOptions>().AuthHost;
|
||||
|
@ -32,7 +33,7 @@ namespace Bootstrap.Client.Models
|
|||
LogoutUrl = uriBuilder.ToString();
|
||||
|
||||
// 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";
|
||||
if (!string.IsNullOrEmpty(user.Css)) Theme = user.Css;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using Bootstrap.Security.DataAccess;
|
||||
using Bootstrap.Client.DataAccess;
|
||||
|
||||
namespace Bootstrap.Client.Models
|
||||
{
|
||||
|
@ -12,9 +12,9 @@ namespace Bootstrap.Client.Models
|
|||
/// </summary>
|
||||
public ModelBase()
|
||||
{
|
||||
Title = DbHelper.RetrieveTitle();
|
||||
Footer = DbHelper.RetrieveFooter();
|
||||
Theme = DbHelper.RetrieveActiveTheme();
|
||||
Title = DictHelper.RetrieveWebTitle();
|
||||
Footer = DictHelper.RetrieveWebFooter();
|
||||
Theme = DictHelper.RetrieveActiveTheme();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Bootstrap.Security;
|
||||
using Bootstrap.Security.DataAccess;
|
||||
using Bootstrap.Client.DataAccess;
|
||||
using Bootstrap.Security;
|
||||
using Longbow.Configuration;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
@ -16,8 +17,8 @@ namespace Bootstrap.Client.Models
|
|||
/// <param name="controller"></param>
|
||||
public NavigatorBarModel(ControllerBase controller) : base(controller.User.Identity)
|
||||
{
|
||||
Navigations = DbHelper.RetrieveAppCascadeMenus(UserName, $"~/{controller.ControllerContext.ActionDescriptor.ControllerName}/{controller.ControllerContext.ActionDescriptor.ActionName}");
|
||||
ImageLibUrl = DbHelper.RetrieveImagesLibUrl();
|
||||
Navigations = MenuHelper.RetrieveAppMenus(UserName, $"~/{controller.ControllerContext.ActionDescriptor.ControllerName}/{controller.ControllerContext.ActionDescriptor.ActionName}");
|
||||
ImageLibUrl = DictHelper.RetrieveImagesLibUrl();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Longbow.Web;
|
||||
using Bootstrap.Client.DataAccess;
|
||||
using Longbow.Web;
|
||||
using Longbow.Web.SignalR;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
@ -88,7 +89,7 @@ namespace Bootstrap.Client
|
|||
app.UseResponseCompression();
|
||||
app.UseStaticFiles();
|
||||
app.UseCookiePolicy();
|
||||
app.UseBootstrapAdminAuthentication();
|
||||
app.UseBootstrapAdminAuthentication(RoleHelper.RetrievesByUserName, RoleHelper.RetrievesByUrl, AppHelper.RetrievesByUserName);
|
||||
app.UseCacheManager();
|
||||
app.UseSignalR(routes => { routes.MapHub<SignalRHub>("/NotiHub"); });
|
||||
app.UseMvc(routes =>
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
}
|
||||
},
|
||||
"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": [
|
||||
{
|
||||
|
@ -26,7 +27,17 @@
|
|||
"Enabled": true,
|
||||
"ProviderName": "Sqlite",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
}
|
||||
},
|
||||
"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": [
|
||||
{
|
||||
|
@ -24,7 +24,16 @@
|
|||
"Enabled": true,
|
||||
"ProviderName": "Sqlite",
|
||||
"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,
|
||||
"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,
|
||||
"Key": "GroupHelper-RetrieveGroupsByUserName",
|
||||
|
|
|
@ -9,7 +9,7 @@ using MongoDB.Driver;
|
|||
namespace Bootstrap.DataAccess.MongoDB
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// 数据库操作类
|
||||
/// </summary>
|
||||
internal static class DbManager
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
private static readonly object _locker = new object();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// IMongoDatabase 实例
|
||||
/// </summary>
|
||||
private static IMongoDatabase DBAccess
|
||||
{
|
||||
|
@ -34,6 +34,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
ChangeToken.OnChange(() => ConfigurationManager.AppSettings.GetReloadToken(), () => _db = null);
|
||||
InitClassMap();
|
||||
}
|
||||
if (_db == null)
|
||||
InitDb();
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +44,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
|
||||
#region Collections
|
||||
/// <summary>
|
||||
///
|
||||
/// Logs 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<DataAccess.Log> Logs
|
||||
{
|
||||
|
@ -54,7 +55,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Exceptions 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<DataAccess.Exceptions> Exceptions
|
||||
{
|
||||
|
@ -64,7 +65,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// Dicts 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<BootstrapDict> Dicts
|
||||
{
|
||||
|
@ -75,7 +76,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Users 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<User> Users
|
||||
{
|
||||
|
@ -86,7 +87,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Groups 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<Group> Groups
|
||||
{
|
||||
|
@ -97,7 +98,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Roles 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<Role> Roles
|
||||
{
|
||||
|
@ -108,7 +109,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Menus 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<BootstrapMenu> Menus
|
||||
{
|
||||
|
@ -119,7 +120,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// LoginUsers 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<DataAccess.LoginUser> LoginUsers
|
||||
{
|
||||
|
@ -130,7 +131,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// ResetUsers 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<DataAccess.ResetUser> ResetUsers
|
||||
{
|
||||
|
@ -141,7 +142,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Traces 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<DataAccess.Trace> Traces
|
||||
{
|
||||
|
@ -152,7 +153,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// RejectUsers 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<RejectUser> RejectUsers
|
||||
{
|
||||
|
@ -163,7 +164,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Messages 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<DataAccess.Message> Messages
|
||||
{
|
||||
|
@ -174,7 +175,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Tasks 集合
|
||||
/// </summary>
|
||||
public static IMongoCollection<DataAccess.Task> Tasks
|
||||
{
|
||||
|
@ -187,8 +188,9 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
|
||||
private static void InitDb()
|
||||
{
|
||||
var client = new MongoClient(Longbow.Data.DbManager.GetConnectionString());
|
||||
_db = client.GetDatabase(ConfigurationManager.AppSettings["MongoDB"]);
|
||||
var (connectString, databaseName) = Longbow.Data.DbManager.GetMongoDB();
|
||||
var client = new MongoClient(connectString);
|
||||
_db = client.GetDatabase(databaseName);
|
||||
}
|
||||
|
||||
private static void InitClassMap()
|
||||
|
|
|
@ -21,21 +21,23 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
var user = UserHelper.Retrieves().Cast<User>().FirstOrDefault(u => u.UserName.ToLowerInvariant() == userName.ToLowerInvariant());
|
||||
if (user == null) return Enumerable.Empty<BootstrapMenu>();
|
||||
|
||||
var dicts = DictHelper.RetrieveDicts().Where(m => m.Category == "菜单");
|
||||
|
||||
// 通过用户获取 角色列表
|
||||
var roles = RoleHelper.Retrieves().Cast<Role>().Where(r => user.Roles.Any(rl => rl == r.Id)).ToList();
|
||||
var roles = RoleHelper.Retrieves().Cast<Role>();
|
||||
var groups = GroupHelper.Retrieves().Cast<Group>();
|
||||
|
||||
// 通过用户获取 组列表相关联的角色列表
|
||||
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;
|
||||
}).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 => 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();
|
||||
|
||||
var dicts = DictHelper.RetrieveDicts().Where(m => m.Category == "菜单");
|
||||
menus.ForEach(m =>
|
||||
{
|
||||
m.CategoryName = dicts.FirstOrDefault(d => d.Code == m.Category)?.Name;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<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.PetaPoco" Version="1.0.2" />
|
||||
<PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" />
|
||||
|
|
|
@ -35,6 +35,8 @@ namespace Bootstrap.DataAccess
|
|||
cacheKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
|
||||
cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*");
|
||||
cacheKeys.Add(RetrieveAllRolesDataKey + "*");
|
||||
corsKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
|
||||
corsKeys.Add(GroupHelper.RetrieveGroupsDataKey + "*");
|
||||
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
|
||||
}
|
||||
if (userIds != null)
|
||||
|
@ -59,8 +61,10 @@ namespace Bootstrap.DataAccess
|
|||
});
|
||||
cacheKeys.Add(GroupHelper.RetrieveGroupsDataKey + "*");
|
||||
cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*");
|
||||
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
|
||||
cacheKeys.Add(RetrieveAllRolesDataKey + "*");
|
||||
corsKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
|
||||
corsKeys.Add(GroupHelper.RetrieveGroupsDataKey + "*");
|
||||
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
|
||||
}
|
||||
if (menuIds != null)
|
||||
{
|
||||
|
@ -70,6 +74,8 @@ namespace Bootstrap.DataAccess
|
|||
});
|
||||
cacheKeys.Add(MenuHelper.RetrieveMenusByRoleIdDataKey + "*");
|
||||
cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*");
|
||||
corsKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
|
||||
corsKeys.Add(GroupHelper.RetrieveGroupsDataKey + "*");
|
||||
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
|
||||
}
|
||||
if (appIds != null)
|
||||
|
|
|
@ -61,13 +61,13 @@ namespace Bootstrap.DataAccess
|
|||
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;
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace Bootstrap.DataAccess
|
|||
///
|
||||
/// </summary>
|
||||
public const string RetrieveRolesByGroupIdDataKey = "RoleHelper-RetrieveRolesByGroupId";
|
||||
|
||||
/// <summary>
|
||||
/// 查询所有角色
|
||||
/// </summary>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.705
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29215.179
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SQLServer", "SQLServer", "{87319AF5-7C40-4362-B67C-35F9DD737DB4}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
|
@ -64,6 +64,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Postgresql", "Postgresql",
|
|||
DatabaseScripts\Postgresql\install.sql = DatabaseScripts\Postgresql\install.sql
|
||||
EndProjectSection
|
||||
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
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
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}.Release|Any CPU.ActiveCfg = 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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -101,6 +113,8 @@ Global
|
|||
{A06A0AD8-A246-4329-B024-7174AE4A3EDE} = {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}
|
||||
{843811A2-FE49-410F-BF9F-9F1FB14A1DEE} = {C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0}
|
||||
{BC1C6D63-ADA9-4C3B-89F0-CEB191A86BF5} = {C7F51A14-2D89-4D1F-AD78-C42B79AB0BF0}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {221EAE38-5F75-4391-9A48-E462A9F3B8FC}
|
||||
|
|
Loading…
Reference in New Issue