From f4078b75fe80f03e58af3217bf642d0de118d1c9 Mon Sep 17 00:00:00 2001 From: liuying <1427574514@qq.com> Date: 周四, 09 5月 2024 13:01:19 +0800 Subject: [PATCH] 流程图 --- iWare_RawMaterialWarehouse_Wms/Admin.NET.EntityFramework.Core/DbContexts/DefaultDbContext.cs | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 307 insertions(+), 0 deletions(-) diff --git a/iWare_RawMaterialWarehouse_Wms/Admin.NET.EntityFramework.Core/DbContexts/DefaultDbContext.cs b/iWare_RawMaterialWarehouse_Wms/Admin.NET.EntityFramework.Core/DbContexts/DefaultDbContext.cs new file mode 100644 index 0000000..71bd224 --- /dev/null +++ b/iWare_RawMaterialWarehouse_Wms/Admin.NET.EntityFramework.Core/DbContexts/DefaultDbContext.cs @@ -0,0 +1,307 @@ +using Admin.NET.Core; +using Admin.NET.Core.Entity; +using Furion; +using Furion.DatabaseAccessor; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using System.Linq.Expressions; +using Yitter.IdGenerator; + +namespace Admin.NET.EntityFramework.Core +{ + [AppDbContext("DefaultConnection", DbProvider.SqlServer)] + public class DefaultDbContext : AppDbContext<DefaultDbContext>, IModelBuilderFilter + { + public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options) + { + // 鍚敤瀹炰綋鏁版嵁鏇存敼鐩戝惉 + EnabledEntityChangedListener = true; + + // 蹇界暐绌哄�兼洿鏂� + InsertOrUpdateIgnoreNullValues = true; + } + + /// <summary> + /// 鑾峰彇绉熸埛Id + /// </summary> + /// <returns></returns> + //public object GetTenantId() + //{ + // // 娴佺▼涓病鏈夌敤鍒板绉熸埛 杩欓噷榛樿杩斿洖涓�涓鎴� + // if (App.User == null) return 142307070918780; + // return Convert.ToInt64(App.User.FindFirst(ClaimConst.TENANT_ID)?.Value); + //} + + protected override void OnModelCreating(ModelBuilder builder) + { + if (Database.ProviderName == DbProvider.Sqlite) + { + // SQLite does not have proper support for DateTimeOffset via Entity Framework Core, see the limitations + // here: https://docs.microsoft.com/en-us/ef/core/providers/sqlite/limitations#query-limitations + // To work around this, when the Sqlite database provider is used, all model properties of type DateTimeOffset + // use the DateTimeOffsetToBinaryConverter + // Based on: https://github.com/aspnet/EntityFrameworkCore/issues/10784#issuecomment-415769754 + // This only supports millisecond precision, but should be sufficient for most use cases. + foreach (var entityType in builder.Model.GetEntityTypes()) + { + var properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == typeof(DateTimeOffset) + || p.PropertyType == typeof(DateTimeOffset?)); + foreach (var property in properties) + { + builder + .Entity(entityType.Name) + .Property(property.Name) + .HasConversion(new DateTimeOffsetToBinaryConverter()); + } + } + } + // 澶勭悊mysql鏃跺尯闂 https://gitee.com/dotnetchina/Furion/issues/I3RSCO#note_5685893_link + else if (Database.ProviderName == DbProvider.MySql || Database.ProviderName == DbProvider.MySqlOfficial) + { + var converter = new ValueConverter<DateTimeOffset, DateTime>(v => v.LocalDateTime, v => v); + + // 鎵弿绋嬪簭闆嗭紝鑾峰彇鏁版嵁搴撳疄浣撶浉鍏崇被鍨� + var types = App.EffectiveTypes.Where(t => (typeof(IPrivateEntity).IsAssignableFrom(t) || typeof(IPrivateModelBuilder).IsAssignableFrom(t)) + && t.IsClass && !t.IsAbstract && !t.IsGenericType && !t.IsInterface && !t.IsDefined(typeof(ManualAttribute), true)); + + if (types.Any()) + { + foreach (var item in types) + { + if (item.IsSubclassOf(typeof(DEntityBase)) || item.IsSubclassOf(typeof(EntityBase))) + { + foreach (var property in item.GetProperties()) + { + if (property.PropertyType == typeof(DateTimeOffset?) || property.PropertyType == typeof(DateTimeOffset)) + { + builder.Entity(item).Property(property.Name).HasConversion(converter); + } + } + } + } + } + } + + base.OnModelCreating(builder); + } + + /// <summary> + /// 閰嶇疆绉熸埛Id杩囨护鍣� + /// </summary> + /// <param name="modelBuilder"></param> + /// <param name="entityBuilder"></param> + /// <param name="dbContext"></param> + /// <param name="dbContextLocator"></param> + public void OnCreating(ModelBuilder modelBuilder, EntityTypeBuilder entityBuilder, DbContext dbContext, Type dbContextLocator) + { + // 閰嶇疆鍋囧垹闄よ繃婊ゅ櫒 + LambdaExpression expression = FakeDeleteQueryFilterExpression(entityBuilder, dbContext); + if (expression != null) + entityBuilder.HasQueryFilter(expression); + // 閰嶇疆鏁版嵁鏉冮檺鍔ㄦ�佽〃杈惧紡 + LambdaExpression dataScopesExpression = DataScopesFilterExpression(entityBuilder, dbContext); + if (dataScopesExpression != null) + entityBuilder.HasQueryFilter(dataScopesExpression); + } + + protected override void SavingChangesEvent(DbContextEventData eventData, InterceptionResult<int> result) + { + // 鑾峰彇褰撳墠浜嬩欢瀵瑰簲涓婁笅鏂� + var dbContext = eventData.Context; + // 鑾峰彇鎵�鏈夋洿鏀癸紝鍒犻櫎锛屾柊澧炵殑瀹炰綋锛屼絾鎺掗櫎瀹¤瀹炰綋锛堥伩鍏嶆寰幆锛� + var entities = dbContext.ChangeTracker.Entries() + .Where(u => u.Entity.GetType() != typeof(SysLogAudit) && u.Entity.GetType() != typeof(SysLogOp) && + u.Entity.GetType() != typeof(SysLogVis) && u.Entity.GetType() != typeof(SysLogEx) && + (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added)).ToList(); + if (entities == null || entities.Count < 1) return; + + //// 鍒ゆ柇鏄惁鏄紨绀虹幆澧� + //var demoEnvFlag = App.GetService<ISysConfigService>().GetDemoEnvFlag().GetAwaiter().GetResult(); + //if (demoEnvFlag) + //{ + // var sysUser = entities.Find(u => u.Entity.GetType() == typeof(SysUser)); + // if (sysUser == null || string.IsNullOrEmpty((sysUser.Entity as SysUser).LastLoginTime.ToString())) // 鎺掗櫎鐧诲綍 + // throw Oops.Oh(ErrorCode.D1200); + //} + + // 褰撳墠鎿嶄綔鑰呬俊鎭� + var userId = App.User?.FindFirst(ClaimConst.CLAINM_USERID)?.Value; + //璇诲彇鐨勭敤鎴峰悕鏀逛负 鏄电О锛岃�屼笉鏄处鍙� 銆怑ditby shaocx,2024-04-20銆� + //var userName = App.User?.FindFirst(ClaimConst.CLAINM_ACCOUNT)?.Value; + var userName = App.User?.FindFirst(ClaimConst.CLAINM_NAME)?.Value; + // 褰撳墠鎿嶄綔鑰呮満鏋勪俊鎭� + var orgId = App.User?.FindFirst(ClaimConst.CLAINM_ORGID)?.Value; + var orgName = App.User?.FindFirst(ClaimConst.CLAINM_ORGNAME)?.Value; + + foreach (var entity in entities) + { + if (entity.Entity.GetType().IsSubclassOf(typeof(DEntityBase))) + { + var obj = entity.Entity as DEntityBase; + if (entity.State == EntityState.Added) + { + obj.Id = obj.Id == 0 ? YitIdHelper.NextId() : obj.Id; + obj.CreatedTime = DateTimeOffset.Now; + if (!string.IsNullOrEmpty(userId)) + { + obj.CreatedUserId = long.Parse(userId); + obj.CreatedUserName = userName; + if (entity.Entity.GetType().GetInterface(typeof(IDataPermissions).Name) != null) + { + ((IDataPermissions)obj).CreatedUserOrgId = long.Parse(orgId); + ((IDataPermissions)obj).CreatedUserOrgName = orgName; + } + } + } + else if (entity.State == EntityState.Modified) + { + // 鎺掗櫎鍒涘缓浜� + entity.Property(nameof(DEntityBase.CreatedUserId)).IsModified = false; + entity.Property(nameof(DEntityBase.CreatedUserName)).IsModified = false; + // 鎺掗櫎鍒涘缓鏃ユ湡 + entity.Property(nameof(DEntityBase.CreatedTime)).IsModified = false; + + obj.UpdatedTime = DateTimeOffset.Now; + if (!string.IsNullOrEmpty(userId)) + { + obj.UpdatedUserId = long.Parse(userId); + obj.UpdatedUserName = userName; + } + } + } + } + } + + /// <summary> + /// 鏋勫缓绉熸埛Id浠ュ強鍋囧垹闄よ繃婊ゅ櫒 + /// </summary> + /// <param name="entityBuilder"></param> + /// <param name="dbContext"></param> + /// <param name="isDeletedKey"></param> + /// <param name="filterValue"></param> + /// <returns></returns> + protected static LambdaExpression FakeDeleteQueryFilterExpression(EntityTypeBuilder entityBuilder, DbContext dbContext, string onTableTenantId = null, string isDeletedKey = null, object filterValue = null) + { + //onTableTenantId ??= "TenantId"; + isDeletedKey ??= "IsDeleted"; + IMutableEntityType metadata = entityBuilder.Metadata; + //if (metadata.FindProperty(onTableTenantId) == null && metadata.FindProperty(isDeletedKey) == null) + //{ + // return null; + //} + //瑙e喅瀹炰綋缁ф壙鎶ラ敊闂锛屽熀绫昏〃鎵嶆湁IsDeleted銆乀enantId瀛楁 + if (metadata.BaseType != null) + { + return null; + } + + Expression finialExpression = Expression.Constant(true); + ParameterExpression parameterExpression = Expression.Parameter(metadata.ClrType, "u"); + + + // 鍋囧垹闄よ繃婊ゅ櫒 + if (metadata.FindProperty(isDeletedKey) != null) + { + ConstantExpression constantExpression = Expression.Constant(isDeletedKey); + ConstantExpression right = Expression.Constant(filterValue ?? false); + var fakeDeleteQueryExpression = Expression.Equal(Expression.Call(typeof(EF), "Property", new Type[1] + { + typeof(bool) + }, parameterExpression, constantExpression), right); + finialExpression = Expression.AndAlso(finialExpression, fakeDeleteQueryExpression); + } + + return Expression.Lambda(finialExpression, parameterExpression); + } + + #region 鏁版嵁鏉冮檺 + + /// <summary> + /// 鑾峰彇鐢ㄦ埛Id + /// </summary> + /// <returns></returns> + public object GetUserId() + { + if (App.User == null) return null; + return App.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value; + } + + /// <summary> + /// 鑾峰彇鏁版嵁鑼冨洿 + /// </summary> + /// <returns></returns> + public List<object> GetDataScopes() + { + var userId = this.GetUserId(); + if (userId == null) + { + return new List<object>(); + } + + var dataScopes = JsonUtil.FromJson<List<object>>(App.User.FindFirst(ClaimConst.DATA_SCOPES)?.Value); + if (dataScopes != null) + { + return dataScopes; + } + return new List<object>(); + } + + /// <summary> + /// 鏋勫缓鏁版嵁鑼冨洿杩囨护鍣� + /// </summary> + /// <param name="entityBuilder"></param> + /// <param name="dbContext"></param> + /// <param name="onTableCreatedUserId"></param> + /// <param name="onTableCreatedUserOrgId"></param> + /// <param name="filterValue"></param> + /// <returns></returns> + protected LambdaExpression DataScopesFilterExpression(EntityTypeBuilder entityBuilder, DbContext dbContext, string onTableCreatedUserId = null, string onTableCreatedUserOrgId = null) + { + onTableCreatedUserId ??= nameof(IDataPermissions.CreatedUserId);//鐢ㄦ埛id瀛楁 + onTableCreatedUserOrgId ??= nameof(IDataPermissions.CreatedUserOrgId);//鐢ㄦ埛閮ㄩ棬瀛楁 + + IMutableEntityType metadata = entityBuilder.Metadata; + if (metadata.FindProperty(onTableCreatedUserId) == null || metadata.FindProperty(onTableCreatedUserOrgId) == null) + { + return null; + } + + Expression finialExpression = Expression.Constant(true); + ParameterExpression parameterExpression = Expression.Parameter(metadata.ClrType, "u"); + + // 涓汉鐢ㄦ埛鏁版嵁杩囨护鍣� + if (metadata.FindProperty(onTableCreatedUserId) != null) + { + ConstantExpression constantExpression = Expression.Constant(onTableCreatedUserId); + MethodCallExpression right = Expression.Call(Expression.Constant(dbContext), dbContext.GetType().GetMethod("GetUserId")); + finialExpression = Expression.AndAlso(finialExpression, Expression.Equal(Expression.Call(typeof(EF), "Property", new Type[1] + { + typeof(object) + }, parameterExpression, constantExpression), right)); + } + + //鏁版嵁鏉冮檺杩囨护鍣� + if (metadata.FindProperty(onTableCreatedUserOrgId) != null) + { + ConstantExpression constantExpression = Expression.Constant(onTableCreatedUserOrgId); + + MethodCallExpression dataScopesLeft = Expression.Call(Expression.Constant(dbContext), dbContext.GetType().GetMethod("GetDataScopes")); + var firstOrDefaultCall = Expression.Call(typeof(EF), "Property", new Type[1] + { + typeof(object) + }, parameterExpression, constantExpression); + + var createdUserOrgIdQueryExpression = Expression.Call(dataScopesLeft, typeof(List<object>).GetMethod("Contains"), firstOrDefaultCall); + + finialExpression = Expression.Or(finialExpression, createdUserOrgIdQueryExpression); + } + + return Expression.Lambda(finialExpression, parameterExpression); + } + + #endregion 鏁版嵁鏉冮檺 + } +} \ No newline at end of file -- Gitblit v1.9.3