using Dm; using Microsoft.Data.SqlClient; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.Logging; using MySqlConnector; using Npgsql; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Threading; using System.Threading.Tasks; using WalkingTec.Mvvm.Core.Extensions; using WalkingTec.Mvvm.Core.Support.Json; namespace WalkingTec.Mvvm.Core { /// /// FrameworkContext /// public partial class FrameworkContext : EmptyContext, IDataContext { public DbSet BaseFrameworkMenus { get; set; } public DbSet BaseFunctionPrivileges { get; set; } public DbSet BaseDataPrivileges { get; set; } public DbSet BaseFileAttachments { get; set; } public DbSet BaseFrameworkRoles { get; set; } public DbSet BaseFrameworkUserRoles { get; set; } public DbSet BaseFrameworkUserGroups { get; set; } public DbSet BaseFrameworkGroups { get; set; } public DbSet BaseActionLogs { get; set; } //public DbSet BaseFrameworkAreas { get; set; } public DbSet PersistedGrants { get; set; } /// /// FrameworkContext /// public FrameworkContext() : base() { } /// /// FrameworkContext /// /// public FrameworkContext(string cs) : base(cs) { } public FrameworkContext(string cs, DBTypeEnum dbtype, string version = null) : base(cs, dbtype, version) { } public FrameworkContext(CS cs) : base(cs) { } public FrameworkContext(DbContextOptions options) : base(options) { } /// /// OnModelCreating /// /// protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); //菜单和菜单权限的级联删除 modelBuilder.Entity().HasOne(x => x.MenuItem).WithMany(x => x.Privileges).HasForeignKey(x => x.MenuItemId).OnDelete(DeleteBehavior.Cascade); var modelAsms = Utils.GetAllAssembly(); var allTypes = new List();// 所有 DbSet<> 的泛型类型 #region 获取所有 DbSet 的泛型类型 T 及其 List 类型属性对应的类型 T // 获取所有 DbSet 的泛型类型 T foreach (var asm in modelAsms) { try { var dcModule = asm.GetExportedTypes().Where(x => typeof(DbContext).IsAssignableFrom(x)).ToList(); if (dcModule != null && dcModule.Count > 0) { foreach (var module in dcModule) { foreach (var pro in module.GetProperties()) { if (pro.PropertyType.IsGeneric(typeof(DbSet<>))) { if (!allTypes.Contains(pro.PropertyType.GenericTypeArguments[0], new TypeComparer())) { allTypes.Add(pro.PropertyType.GenericTypeArguments[0]); } } } } } } catch { } } // 获取类型 T 下 List 类型的属性对应的类型 S,且S 必须是 TopBasePoco 的子类,只有这些类会生成库 for (int i = 0; i < allTypes.Count; i++) // { var item = allTypes[i]; var pros = item.GetProperties(); foreach (var pro in pros) { if (typeof(TopBasePoco).IsAssignableFrom(pro.PropertyType)) { if (allTypes.Contains(pro.PropertyType) == false) { allTypes.Add(pro.PropertyType); } } else { if (pro.PropertyType.IsGenericType && pro.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) { var inner = pro.PropertyType.GetGenericArguments()[0]; if (typeof(TopBasePoco).IsAssignableFrom(inner)) { if (allTypes.Contains(inner) == false) { allTypes.Add(inner); } } } } } } #endregion foreach (var item in allTypes) { if (typeof(TopBasePoco).IsAssignableFrom(item) && typeof(ISubFile).IsAssignableFrom(item) == false) { //将所有关联附件的外键设为不可级联删除 var pros = item.GetProperties().Where(x => x.PropertyType == typeof(FileAttachment)).ToList(); foreach (var filepro in pros) { var builder = typeof(ModelBuilder).GetMethod("Entity", Type.EmptyTypes).MakeGenericMethod(item).Invoke(modelBuilder, null) as EntityTypeBuilder; builder.HasOne(filepro.Name).WithMany().OnDelete(DeleteBehavior.Restrict); } } } } /// /// 数据初始化 /// /// /// /// 返回true表示需要进行初始化数据操作,返回false即数据库已经存在或不需要初始化数据 public async override Task DataInit(object allModules, bool IsSpa) { bool rv = await Database.EnsureCreatedAsync(); //判断是否存在初始数据 bool emptydb = false; try { emptydb = Set().Count() == 0 && Set().Count() == 0; } catch { } if (emptydb == true) { var AllModules = allModules as List; var roles = new FrameworkRole[] { new FrameworkRole{ ID = Guid.NewGuid(), RoleCode = "001", CreateBy="Admin" , RoleName = CoreProgram._localizer?["Sys.Admin"]}, new FrameworkRole{ ID = Guid.NewGuid(), RoleCode = "002", RoleName = CoreProgram._localizer?["_Admin.User"]}, }; var adminRole = roles[0]; if (Set().Any() == false) { var systemManagement = GetFolderMenu("SystemManagement", new List { adminRole }); var logList = IsSpa ? GetMenu2(AllModules, "ActionLog", "MenuKey.ActionLog", new List { adminRole }, 1) : GetMenu(AllModules, "_Admin", "ActionLog", "Index", "MenuKey.ActionLog", new List { adminRole }, 1); var userList = IsSpa ? GetMenu2(AllModules, "FrameworkUser", "MenuKey.UserManagement", new List { adminRole }, 2) : GetMenu(AllModules, "_Admin", "FrameworkUser", "Index", "MenuKey.UserManagement", new List { adminRole }, 2); var roleList = IsSpa ? GetMenu2(AllModules, "FrameworkRole", "MenuKey.RoleManagement", new List { adminRole }, 3) : GetMenu(AllModules, "_Admin", "FrameworkRole", "Index", "MenuKey.RoleManagement", new List { adminRole }, 3); var groupList = IsSpa ? GetMenu2(AllModules, "FrameworkGroup", "MenuKey.GroupManagement", new List { adminRole }, 4) : GetMenu(AllModules, "_Admin", "FrameworkGroup", "Index", "MenuKey.GroupManagement", new List { adminRole }, 4); var menuList = IsSpa ? GetMenu2(AllModules, "FrameworkMenu", "MenuKey.MenuMangement", new List { adminRole }, 5) : GetMenu(AllModules, "_Admin", "FrameworkMenu", "Index", "MenuKey.MenuMangement", new List { adminRole }, 5); var dpList = IsSpa ? GetMenu2(AllModules, "DataPrivilege", "MenuKey.DataPrivilege", new List { adminRole }, 6) : GetMenu(AllModules, "_Admin", "DataPrivilege", "Index", "MenuKey.DataPrivilege", new List { adminRole }, 6); if (logList != null) { var menus = new FrameworkMenu[] { logList, userList, roleList, groupList, menuList, dpList }; foreach (var item in menus) { if (item != null) { systemManagement.Children.Add(item); } } Set().Add(systemManagement); if (IsSpa == false) { systemManagement.Icon = "layui-icon layui-icon-set"; logList?.SetPropertyValue("Icon", "layui-icon layui-icon-form"); userList?.SetPropertyValue("Icon", "layui-icon layui-icon-friends"); roleList?.SetPropertyValue("Icon", "layui-icon layui-icon-user"); groupList?.SetPropertyValue("Icon", "layui-icon layui-icon-group"); menuList?.SetPropertyValue("Icon", "layui-icon layui-icon-menu-fill"); dpList?.SetPropertyValue("Icon", "layui-icon layui-icon-auz"); var apifolder = GetFolderMenu("Api", new List { adminRole }); apifolder.ShowOnMenu = false; apifolder.DisplayOrder = 100; var logList2 = GetMenu2(AllModules, "ActionLog", "MenuKey.ActionLog", new List { adminRole }, 1); var userList2 = GetMenu2(AllModules, "FrameworkUser", "MenuKey.UserManagement", new List { adminRole }, 2); var roleList2 = GetMenu2(AllModules, "FrameworkRole", "MenuKey.RoleManagement", new List { adminRole }, 3); var groupList2 = GetMenu2(AllModules, "FrameworkGroup", "MenuKey.GroupManagement", new List { adminRole }, 4); var menuList2 = GetMenu2(AllModules, "FrameworkMenu", "MenuKey.MenuMangement", new List { adminRole }, 5); var dpList2 = GetMenu2(AllModules, "DataPrivilege", "MenuKey.DataPrivilege", new List { adminRole }, 6); var apis = new FrameworkMenu[] { logList2, userList2, roleList2, groupList2, menuList2, dpList2 }; //apis.ToList().ForEach(x => { x.ShowOnMenu = false;x.PageName += $"({Program._localizer["BuildinApi"]})"; }); foreach (var item in apis) { if (item != null) { apifolder.Children.Add(item); } } Set().Add(apifolder); } else { systemManagement.Icon = " _wtmicon _wtmicon-icon_shezhi"; logList?.SetPropertyValue("Icon", " _wtmicon _wtmicon-chaxun"); userList?.SetPropertyValue("Icon", " _wtmicon _wtmicon-zhanghaoquanxianguanli"); roleList?.SetPropertyValue("Icon", " _wtmicon _wtmicon-quanxianshenpi"); groupList?.SetPropertyValue("Icon", " _wtmicon _wtmicon-zuzhiqunzu"); menuList?.SetPropertyValue("Icon", " _wtmicon _wtmicon--lumingpai"); dpList?.SetPropertyValue("Icon", " _wtmicon _wtmicon-anquan"); } } } Set().AddRange(roles); await SaveChangesAsync(); } return rv; } private FrameworkMenu GetFolderMenu(string FolderText, List allowedRoles, bool isShowOnMenu = true, bool isInherite = false) { FrameworkMenu menu = new FrameworkMenu { PageName = "MenuKey." + FolderText, Children = new List(), Privileges = new List(), ShowOnMenu = isShowOnMenu, IsInside = true, FolderOnly = true, IsPublic = false, DisplayOrder = 1 }; if (allowedRoles != null) { foreach (var role in allowedRoles) { menu.Privileges.Add(new FunctionPrivilege { RoleCode = role.RoleCode, Allowed = true }); } } return menu; } private FrameworkMenu GetMenu(List allModules, string areaName, string controllerName, string actionName, string pageKey, List allowedRoles, int displayOrder) { var acts = allModules.Where(x => x.ClassName == controllerName && (areaName == null || x.Area?.Prefix?.ToLower() == areaName.ToLower())).SelectMany(x => x.Actions).ToList(); var act = acts.Where(x => x.MethodName == actionName).SingleOrDefault(); var rest = acts.Where(x => x.MethodName != actionName && x.IgnorePrivillege == false).ToList(); FrameworkMenu menu = GetMenuFromAction(act, true, allowedRoles, displayOrder); if (menu != null) { menu.PageName = pageKey; for (int i = 0; i < rest.Count; i++) { if (rest[i] != null) { var sub = GetMenuFromAction(rest[i], false, allowedRoles, (i + 1)); sub.PageName = pageKey; menu.Children.Add(sub); } } } return menu; } private FrameworkMenu GetMenu2(List allModules, string controllerName, string pageKey, List allowedRoles, int displayOrder) { var acts = allModules.Where(x => (x.FullName == $"WalkingTec.Mvvm.Admin.Api,{controllerName}")&& x.IsApi == true).SelectMany(x => x.Actions).ToList(); var rest = acts.Where(x => x.IgnorePrivillege == false).ToList(); SimpleAction act = null; if (acts.Count > 0) { act = acts[0]; } FrameworkMenu menu = GetMenuFromAction(act, true, allowedRoles, displayOrder); if (menu != null) { menu.PageName = pageKey; menu.Url = "/" + acts[0].Module.ClassName.ToLower(); menu.ActionName = "MainPage"; menu.ClassName = acts[0].Module.FullName; menu.MethodName = null; for (int i = 0; i < rest.Count; i++) { if (rest[i] != null) { var sub = GetMenuFromAction(rest[i], false, allowedRoles, (i + 1)); sub.PageName = pageKey; menu.Children.Add(sub); } } } return menu; } private FrameworkMenu GetMenuFromAction(SimpleAction act, bool isMainLink, List allowedRoles, int displayOrder = 1) { if (act == null) { return null; } FrameworkMenu menu = new FrameworkMenu { //ActionId = act.ID, //ModuleId = act.ModuleId, ClassName = act.Module.FullName, MethodName = act.MethodName, Url = act.Url, Privileges = new List(), ShowOnMenu = isMainLink, FolderOnly = false, Children = new List(), IsPublic = false, IsInside = true, DisplayOrder = displayOrder, }; if (isMainLink) { menu.ModuleName = act.Module.ModuleName; menu.ActionName = act.ActionDes?.Description ?? act.ActionName; menu.MethodName = null; } else { menu.ModuleName = act.Module.ModuleName; menu.ActionName = act.ActionDes?.Description ?? act.ActionName; } if (allowedRoles != null) { foreach (var role in allowedRoles) { menu.Privileges.Add(new FunctionPrivilege { RoleCode = role.RoleCode, Allowed = true }); } } return menu; } } public partial class EmptyContext : DbContext, IDataContext { private ILoggerFactory _loggerFactory; /// /// Commited /// public bool Commited { get; set; } /// /// IsFake /// public bool IsFake { get; set; } public bool IsDebug { get; set; } /// /// CSName /// public string CSName { get; set; } public DBTypeEnum DBType { get; set; } public string Version { get; set; } public CS ConnectionString { get; set; } /// /// FrameworkContext /// public EmptyContext() { CSName = "default"; DBType = DBTypeEnum.SqlServer; } /// /// FrameworkContext /// /// public EmptyContext(string cs) { CSName = cs; DBType = DBTypeEnum.SqlServer; } public EmptyContext(string cs, DBTypeEnum dbtype, string version = null) { CSName = cs; DBType = dbtype; Version = version; } public EmptyContext(CS cs) { CSName = cs.Value; DBType = cs.DbType ?? DBTypeEnum.SqlServer; Version = cs.Version; ConnectionString = cs; } public EmptyContext(DbContextOptions options) : base(options) { } public IDataContext CreateNew() { if (ConnectionString != null) { return (IDataContext)this.GetType().GetConstructor(new Type[] { typeof(CS) }).Invoke(new object[] { ConnectionString }); ; } else { return (IDataContext)this.GetType().GetConstructor(new Type[] { typeof(string), typeof(DBTypeEnum), typeof(string) }).Invoke(new object[] { CSName, DBType, Version }); } } public IDataContext ReCreate() { if (this?.Database?.CurrentTransaction != null) { return this; } else { if (ConnectionString != null) { return (IDataContext)this.GetType().GetConstructor(new Type[] { typeof(CS) }).Invoke(new object[] { ConnectionString }); ; } else { return (IDataContext)this.GetType().GetConstructor(new Type[] { typeof(string), typeof(DBTypeEnum) }).Invoke(new object[] { CSName, DBType }); } } } /// /// 将一个实体设为填加状态 /// /// 实体 public void AddEntity(T entity) where T : TopBasePoco { this.Entry(entity).State = EntityState.Added; } /// /// 将一个实体设为修改状态 /// /// 实体 public void UpdateEntity(T entity) where T : TopBasePoco { this.Entry(entity).State = EntityState.Modified; } /// /// 将一个实体的某个字段设为修改状态,用于只更新个别字段的情况 /// /// 实体类 /// 实体 /// 要设定为修改状态的字段 public void UpdateProperty(T entity, Expression> fieldExp) where T : TopBasePoco { var set = this.Set(); if (set.Local.AsQueryable().CheckID(entity.GetID()).FirstOrDefault() == null) { set.Attach(entity); } this.Entry(entity).Property(fieldExp).IsModified = true; } /// /// UpdateProperty /// /// /// /// public void UpdateProperty(T entity, string fieldName) where T : TopBasePoco { var set = this.Set(); if (set.Local.AsQueryable().CheckID(entity.GetID()).FirstOrDefault() == null) { set.Attach(entity); } this.Entry(entity).Property(fieldName).IsModified = true; } /// /// 将一个实体设定为删除状态 /// /// 实体 public void DeleteEntity(T entity) where T : TopBasePoco { var set = this.Set(); var exist = set.Local.AsQueryable().CheckID(entity.GetID()).FirstOrDefault(); if (exist == null) { set.Attach(entity); set.Remove(entity); } else { set.Remove(exist); } } /// /// CascadeDelete /// /// /// public void CascadeDelete(T entity) where T : TreePoco { if (entity != null && entity.ID != Guid.Empty) { var set = this.Set(); var entities = set.Where(x => x.ParentId == entity.ID).ToList(); if (entities.Count > 0) { foreach (var item in entities) { CascadeDelete(item); } } DeleteEntity(entity); } } /// /// GetCoreType /// /// /// public Type GetCoreType(Type t) { if (t != null && t.IsNullable()) { if (!t.GetTypeInfo().IsValueType) { return t; } else { if ("DateTime".Equals(t.GenericTypeArguments[0].Name)) { return typeof(string); } return Nullable.GetUnderlyingType(t); } } else { if ("DateTime".Equals(t.Name)) { return typeof(string); } return t; } } /// /// OnModelCreating /// /// protected override void OnModelCreating(ModelBuilder modelBuilder) { if (DBType == DBTypeEnum.Oracle) { modelBuilder.Model.SetMaxIdentifierLength(30); } } /// /// OnConfiguring /// /// protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { switch (DBType) { case DBTypeEnum.SqlServer: optionsBuilder.UseSqlServer(CSName); break; case DBTypeEnum.MySql: ServerVersion sv = null; if (string.IsNullOrEmpty(Version) == false) { ServerVersion.TryParse(Version, out sv); } if (sv == null) { sv = ServerVersion.AutoDetect(CSName); } optionsBuilder.UseMySql(CSName, sv); break; case DBTypeEnum.PgSql: optionsBuilder.UseNpgsql(CSName); break; case DBTypeEnum.Memory: optionsBuilder.UseInMemoryDatabase(CSName); break; case DBTypeEnum.SQLite: optionsBuilder.UseSqlite(CSName); break; case DBTypeEnum.Oracle: optionsBuilder.UseOracle(CSName, option => { if (string.IsNullOrEmpty(Version) == false) { option.UseOracleSQLCompatibility(Version); } else { option.UseOracleSQLCompatibility("11"); } }); break; case DBTypeEnum.DaMeng: optionsBuilder.UseDm(CSName); break; default: break; } if (IsDebug == true) { optionsBuilder.EnableDetailedErrors(); optionsBuilder.EnableSensitiveDataLogging(); if (_loggerFactory != null) { optionsBuilder.UseLoggerFactory(_loggerFactory); } } base.OnConfiguring(optionsBuilder); } public void SetLoggerFactory(ILoggerFactory factory) { this._loggerFactory = factory; } /// /// 数据初始化 /// /// /// /// 返回true表示需要进行初始化数据操作,返回false即数据库已经存在或不需要初始化数据 public async virtual Task DataInit(object allModules, bool IsSpa) { bool rv = await Database.EnsureCreatedAsync(); return rv; } #region 执行存储过程返回datatable /// /// 执行存储过程,返回datatable结果集 /// /// 存储过程名称 /// 存储过程参数 /// public DataTable RunSP(string command, params object[] paras) { return Run(command, CommandType.StoredProcedure, paras); } #endregion public IEnumerable RunSP(string command, params object[] paras) { return Run(command, CommandType.StoredProcedure, paras); } #region 执行Sql语句,返回datatable public DataTable RunSQL(string sql, params object[] paras) { return Run(sql, CommandType.Text, paras); } #endregion public IEnumerable RunSQL(string sql, params object[] paras) { return Run(sql, CommandType.Text, paras); } #region 执行存储过程或Sql语句返回DataTable /// /// 执行存储过程或Sql语句返回DataTable /// /// 存储过程名称或Sql语句 /// 命令类型 /// 参数 /// public DataTable Run(string sql, CommandType commandType, params object[] paras) { DataTable table = new DataTable(); var connection = this.Database.GetDbConnection(); var isClosed = connection.State == ConnectionState.Closed; if (isClosed) { connection.Open(); } using (var command = connection.CreateCommand()) { command.CommandText = sql; command.CommandTimeout = 2400; command.CommandType = commandType; if (this.Database.CurrentTransaction != null) { command.Transaction = this.Database.CurrentTransaction.GetDbTransaction(); } if (paras != null) { foreach (var param in paras) command.Parameters.Add(param); } using (var reader = command.ExecuteReader()) { table.Load(reader); } } if (isClosed) { connection.Close(); } return table; } #endregion public IEnumerable Run(string sql, CommandType commandType, params object[] paras) { IEnumerable entityList = new List(); DataTable dt = Run(sql, commandType, paras); entityList = EntityHelper.GetEntityList(dt); return entityList; } public object CreateCommandParameter(string name, object value, ParameterDirection dir) { object rv = null; switch (this.DBType) { case DBTypeEnum.SqlServer: rv = new SqlParameter(name, value) { Direction = dir }; break; case DBTypeEnum.MySql: rv = new MySqlParameter(name, value) { Direction = dir }; break; case DBTypeEnum.PgSql: rv = new NpgsqlParameter(name, value) { Direction = dir }; break; case DBTypeEnum.SQLite: rv = new SqliteParameter(name, value) { Direction = dir }; break; case DBTypeEnum.Oracle: //rv = new OracleParameter(name, value) { Direction = dir }; break; case DBTypeEnum.DaMeng: rv = new DmParameter(name, value) { Direction = dir }; break; } return rv; } } public class NullContext : IDataContext { public bool IsFake { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public IModel Model => throw new NotImplementedException(); public DatabaseFacade Database => throw new NotImplementedException(); public string CSName { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public DBTypeEnum DBType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public bool IsDebug { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public void AddEntity(T entity) where T : TopBasePoco { throw new NotImplementedException(); } public void CascadeDelete(T entity) where T : TreePoco { throw new NotImplementedException(); } public object CreateCommandParameter(string name, object value, ParameterDirection dir) { throw new NotImplementedException(); } public IDataContext CreateNew() { throw new NotImplementedException(); } public Task DataInit(object AllModel, bool IsSpa) { throw new NotImplementedException(); } public void DeleteEntity(T entity) where T : TopBasePoco { throw new NotImplementedException(); } public void Dispose() { } public IDataContext ReCreate() { throw new NotImplementedException(); } public DataTable Run(string sql, CommandType commandType, params object[] paras) { throw new NotImplementedException(); } public IEnumerable Run(string sql, CommandType commandType, params object[] paras) { throw new NotImplementedException(); } public DataTable RunSP(string command, params object[] paras) { throw new NotImplementedException(); } public IEnumerable RunSP(string command, params object[] paras) { throw new NotImplementedException(); } public DataTable RunSQL(string command, params object[] paras) { throw new NotImplementedException(); } public IEnumerable RunSQL(string sql, params object[] paras) { throw new NotImplementedException(); } public int SaveChanges() { throw new NotImplementedException(); } public int SaveChanges(bool acceptAllChangesOnSuccess) { throw new NotImplementedException(); } public Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) { throw new NotImplementedException(); } public Task SaveChangesAsync(CancellationToken cancellationToken = default) { throw new NotImplementedException(); } public DbSet Set() where T : class { throw new NotImplementedException(); } public void SetLoggerFactory(ILoggerFactory factory) { throw new NotImplementedException(); } public void UpdateEntity(T entity) where T : TopBasePoco { throw new NotImplementedException(); } public void UpdateProperty(T entity, Expression> fieldExp) where T : TopBasePoco { throw new NotImplementedException(); } public void UpdateProperty(T entity, string fieldName) where T : TopBasePoco { throw new NotImplementedException(); } } public partial class PlusContext : EmptyContext, IDataContext { public DbSet BaseFrameworkMenus { get; set; } public DbSet BaseFunctionPrivileges { get; set; } public DbSet BaseDataPrivileges { get; set; } public DbSet BaseFileAttachments { get; set; } public DbSet BaseFrameworkRoles { get; set; } public DbSet BaseFrameworkGroups { get; set; } public DbSet BaseActionLogs { get; set; } //public DbSet BaseFrameworkAreas { get; set; } public DbSet PersistedGrants { get; set; } /// /// FrameworkContext /// public PlusContext() : base() { } /// /// FrameworkContext /// /// public PlusContext(string cs) : base(cs) { } public PlusContext(string cs, DBTypeEnum dbtype, string version = null) : base(cs, dbtype, version) { } public PlusContext(CS cs) : base(cs) { } public PlusContext(DbContextOptions options) : base(options) { } /// /// OnModelCreating /// /// protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); //菜单和菜单权限的级联删除 modelBuilder.Entity().HasOne(x => x.MenuItem).WithMany(x => x.Privileges).HasForeignKey(x => x.MenuItemId).OnDelete(DeleteBehavior.Cascade); var modelAsms = Utils.GetAllAssembly(); var allTypes = new List();// 所有 DbSet<> 的泛型类型 #region 获取所有 DbSet 的泛型类型 T 及其 List 类型属性对应的类型 T // 获取所有 DbSet 的泛型类型 T foreach (var asm in modelAsms) { try { var dcModule = asm.GetExportedTypes().Where(x => typeof(DbContext).IsAssignableFrom(x)).ToList(); if (dcModule != null && dcModule.Count > 0) { foreach (var module in dcModule) { foreach (var pro in module.GetProperties()) { if (pro.PropertyType.IsGeneric(typeof(DbSet<>))) { if (!allTypes.Contains(pro.PropertyType.GenericTypeArguments[0], new TypeComparer())) { allTypes.Add(pro.PropertyType.GenericTypeArguments[0]); } } } } } } catch { } } // 获取类型 T 下 List 类型的属性对应的类型 S,且S 必须是 TopBasePoco 的子类,只有这些类会生成库 for (int i = 0; i < allTypes.Count; i++) // { var item = allTypes[i]; var pros = item.GetProperties(); foreach (var pro in pros) { if (typeof(TopBasePoco).IsAssignableFrom(pro.PropertyType)) { if (allTypes.Contains(pro.PropertyType) == false) { allTypes.Add(pro.PropertyType); } } else { if (pro.PropertyType.IsGenericType && pro.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) { var inner = pro.PropertyType.GetGenericArguments()[0]; if (typeof(TopBasePoco).IsAssignableFrom(inner)) { if (allTypes.Contains(inner) == false) { allTypes.Add(inner); } } } } } } #endregion foreach (var item in allTypes) { if (typeof(TopBasePoco).IsAssignableFrom(item) && typeof(ISubFile).IsAssignableFrom(item) == false) { //将所有关联附件的外键设为不可级联删除 var pros = item.GetProperties().Where(x => x.PropertyType == typeof(FileAttachment)).ToList(); foreach (var filepro in pros) { var builder = typeof(ModelBuilder).GetMethod("Entity", Type.EmptyTypes).MakeGenericMethod(item).Invoke(modelBuilder, null) as EntityTypeBuilder; builder.HasOne(filepro.Name).WithMany().OnDelete(DeleteBehavior.Restrict); } } } } /// /// 数据初始化 /// /// /// /// 返回true表示需要进行初始化数据操作,返回false即数据库已经存在或不需要初始化数据 public async override Task DataInit(object allModules, bool IsSpa) { bool rv = await Database.EnsureCreatedAsync(); //判断是否存在初始数据 bool emptydb = false; try { emptydb = Set().Count() == 0 && Set().Count() == 0; } catch { } if (emptydb == true) { var AllModules = allModules as List; var roles = new FrameworkRole[] { new FrameworkRole{ ID = Guid.NewGuid(), RoleCode = "001", RoleName = CoreProgram._localizer?["Sys.Admin"]}, new FrameworkRole{ ID = Guid.NewGuid(), RoleCode = "002", RoleName = CoreProgram._localizer?["_Admin.User"]}, }; var adminRole = roles[0]; if (Set().Any() == false) { var systemManagement = GetFolderMenu("SystemManagement", new List { adminRole }); var logList = IsSpa ? GetMenu2(AllModules, "ActionLog", "MenuKey.ActionLog", new List { adminRole }, 1) : GetMenu(AllModules, "_Admin", "ActionLog", "Index", "MenuKey.ActionLog", new List { adminRole }, 1); var userList = IsSpa ? GetMenu2(AllModules, "FrameworkUser", "MenuKey.UserManagement", new List { adminRole }, 2) : GetMenu(AllModules, "_Admin", "FrameworkUser", "Index", "MenuKey.UserManagement", new List { adminRole }, 2); var roleList = IsSpa ? GetMenu2(AllModules, "FrameworkRole", "MenuKey.RoleManagement", new List { adminRole }, 3) : GetMenu(AllModules, "_Admin", "FrameworkRole", "Index", "MenuKey.RoleManagement", new List { adminRole }, 3); var groupList = IsSpa ? GetMenu2(AllModules, "FrameworkGroup", "MenuKey.GroupManagement", new List { adminRole }, 4) : GetMenu(AllModules, "_Admin", "FrameworkGroup", "Index", "MenuKey.GroupManagement", new List { adminRole }, 4); var menuList = IsSpa ? GetMenu2(AllModules, "FrameworkMenu", "MenuKey.MenuMangement", new List { adminRole }, 5) : GetMenu(AllModules, "_Admin", "FrameworkMenu", "Index", "MenuKey.MenuMangement", new List { adminRole }, 5); var dpList = IsSpa ? GetMenu2(AllModules, "DataPrivilege", "MenuKey.DataPrivilege", new List { adminRole }, 6) : GetMenu(AllModules, "_Admin", "DataPrivilege", "Index", "MenuKey.DataPrivilege", new List { adminRole }, 6); if (logList != null) { var menus = new FrameworkMenu[] { logList, userList, roleList, groupList, menuList, dpList }; foreach (var item in menus) { if (item != null) { systemManagement.Children.Add(item); } } Set().Add(systemManagement); if (IsSpa == false) { systemManagement.Icon = "layui-icon layui-icon-set"; logList?.SetPropertyValue("Icon", "layui-icon layui-icon-form"); userList?.SetPropertyValue("Icon", "layui-icon layui-icon-friends"); roleList?.SetPropertyValue("Icon", "layui-icon layui-icon-user"); groupList?.SetPropertyValue("Icon", "layui-icon layui-icon-group"); menuList?.SetPropertyValue("Icon", "layui-icon layui-icon-menu-fill"); dpList?.SetPropertyValue("Icon", "layui-icon layui-icon-auz"); var apifolder = GetFolderMenu("Api", new List { adminRole }); apifolder.ShowOnMenu = false; apifolder.DisplayOrder = 100; var logList2 = GetMenu2(AllModules, "ActionLog", "MenuKey.ActionLog", new List { adminRole }, 1); var userList2 = GetMenu2(AllModules, "FrameworkUser", "MenuKey.UserManagement", new List { adminRole }, 2); var roleList2 = GetMenu2(AllModules, "FrameworkRole", "MenuKey.RoleManagement", new List { adminRole }, 3); var groupList2 = GetMenu2(AllModules, "FrameworkGroup", "MenuKey.GroupManagement", new List { adminRole }, 4); var menuList2 = GetMenu2(AllModules, "FrameworkMenu", "MenuKey.MenuMangement", new List { adminRole }, 5); var dpList2 = GetMenu2(AllModules, "DataPrivilege", "MenuKey.DataPrivilege", new List { adminRole }, 6); var apis = new FrameworkMenu[] { logList2, userList2, roleList2, groupList2, menuList2, dpList2 }; //apis.ToList().ForEach(x => { x.ShowOnMenu = false;x.PageName += $"({Program._localizer["BuildinApi"]})"; }); foreach (var item in apis) { if (item != null) { apifolder.Children.Add(item); } } Set().Add(apifolder); } else { systemManagement.Icon = " _wtmicon _wtmicon-icon_shezhi"; logList?.SetPropertyValue("Icon", " _wtmicon _wtmicon-chaxun"); userList?.SetPropertyValue("Icon", " _wtmicon _wtmicon-zhanghaoquanxianguanli"); roleList?.SetPropertyValue("Icon", " _wtmicon _wtmicon-quanxianshenpi"); groupList?.SetPropertyValue("Icon", " _wtmicon _wtmicon-zuzhiqunzu"); menuList?.SetPropertyValue("Icon", " _wtmicon _wtmicon--lumingpai"); dpList?.SetPropertyValue("Icon", " _wtmicon _wtmicon-anquan"); } } } Set().AddRange(roles); await SaveChangesAsync(); } return rv; } private FrameworkMenu GetFolderMenu(string FolderText, List allowedRoles, bool isShowOnMenu = true, bool isInherite = false) { FrameworkMenu menu = new FrameworkMenu { PageName = "MenuKey." + FolderText, Children = new List(), Privileges = new List(), ShowOnMenu = isShowOnMenu, IsInside = true, FolderOnly = true, IsPublic = false, DisplayOrder = 1 }; if (allowedRoles != null) { foreach (var role in allowedRoles) { menu.Privileges.Add(new FunctionPrivilege { RoleCode = role.RoleCode, Allowed = true }); } } return menu; } private FrameworkMenu GetMenu(List allModules, string areaName, string controllerName, string actionName, string pageKey, List allowedRoles, int displayOrder) { var acts = allModules.Where(x => x.ClassName == controllerName && (areaName == null || x.Area?.Prefix?.ToLower() == areaName.ToLower())).SelectMany(x => x.Actions).ToList(); var act = acts.Where(x => x.MethodName == actionName).SingleOrDefault(); var rest = acts.Where(x => x.MethodName != actionName && x.IgnorePrivillege == false).ToList(); FrameworkMenu menu = GetMenuFromAction(act, true, allowedRoles, displayOrder); if (menu != null) { menu.PageName = pageKey; for (int i = 0; i < rest.Count; i++) { if (rest[i] != null) { var sub = GetMenuFromAction(rest[i], false, allowedRoles, (i + 1)); sub.PageName = pageKey; menu.Children.Add(sub); } } } return menu; } private FrameworkMenu GetMenu2(List allModules, string controllerName, string pageKey, List allowedRoles, int displayOrder) { var acts = allModules.Where(x => x.FullName == $"WalkingTec.Mvvm.Admin.Api,{controllerName}" && x.IsApi == true).SelectMany(x => x.Actions).ToList(); var rest = acts.Where(x => x.IgnorePrivillege == false).ToList(); SimpleAction act = null; if (acts.Count > 0) { act = acts[0]; } FrameworkMenu menu = GetMenuFromAction(act, true, allowedRoles, displayOrder); if (menu != null) { menu.PageName = pageKey; menu.Url = "/" + acts[0].Module.ClassName.ToLower(); menu.ActionName = "MainPage"; menu.ClassName = acts[0].Module.FullName; menu.MethodName = null; for (int i = 0; i < rest.Count; i++) { if (rest[i] != null) { var sub = GetMenuFromAction(rest[i], false, allowedRoles, (i + 1)); sub.PageName = pageKey; menu.Children.Add(sub); } } } return menu; } private FrameworkMenu GetMenuFromAction(SimpleAction act, bool isMainLink, List allowedRoles, int displayOrder = 1) { if (act == null) { return null; } FrameworkMenu menu = new FrameworkMenu { //ActionId = act.ID, //ModuleId = act.ModuleId, ClassName = act.Module.FullName, MethodName = act.MethodName, Url = act.Url, Privileges = new List(), ShowOnMenu = isMainLink, FolderOnly = false, Children = new List(), IsPublic = false, IsInside = true, DisplayOrder = displayOrder, }; if (isMainLink) { menu.ModuleName = act.Module.ModuleName; menu.ActionName = act.ActionDes?.Description ?? act.ActionName; menu.MethodName = null; } else { menu.ModuleName = act.Module.ModuleName; menu.ActionName = act.ActionDes?.Description ?? act.ActionName; } if (allowedRoles != null) { foreach (var role in allowedRoles) { menu.Privileges.Add(new FunctionPrivilege { RoleCode = role.RoleCode, Allowed = true }); } } return menu; } } }