143 lines
5.3 KiB
C#
143 lines
5.3 KiB
C#
using CloudBuilder.Core.DatabaseAccessor.Entity;
|
|
using CloudBuilder.Core.DependencyInjection.EFCore;
|
|
using CloudBuilder.Core.Policy;
|
|
using CloudBuilder.Core.Service;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.IdentityModel.JsonWebTokens;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace CloudBuilder.Core.DatabaseAccessor
|
|
{
|
|
public class SecondaryDbContext : DbContext
|
|
{
|
|
public const string SECONDARY_DB_CONTEXT = "SecondaryDbContext";
|
|
|
|
public IEnumerable<IMasterRegistEntityType<ModelBuilder>> _entityManagers;
|
|
private readonly IServiceProvider _serviceProvider;
|
|
private readonly IHttpContextAccessor httpContextAccessor;
|
|
|
|
public SecondaryDbContext(DbContextOptions<SecondaryDbContext> options,
|
|
IEnumerable<IMasterRegistEntityType<ModelBuilder>> entityManagers,
|
|
IServiceProvider serviceProvider,
|
|
IHttpContextAccessor httpContextAccessor) : base(options)
|
|
{
|
|
_entityManagers = entityManagers;
|
|
_serviceProvider = serviceProvider;
|
|
this.httpContextAccessor = httpContextAccessor;
|
|
}
|
|
|
|
public override int SaveChanges(bool acceptAllChangesOnSuccess)
|
|
{
|
|
try
|
|
{
|
|
SavingChangesEvent();
|
|
return base.SaveChanges(acceptAllChangesOnSuccess);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (ex.Message.Contains("data may have been modified or deleted since entities were loaded."))
|
|
{
|
|
throw new ValidatedException(CoreMessagePolicy.GetInstance().ComposeMessage(CoreMessagePolicy.THE_DATA_HAS_BEEN_MODIFIED));
|
|
}
|
|
throw new ValidatedException(ex.InnerException?.Message ?? ex.Message);
|
|
}
|
|
}
|
|
|
|
public void SavingChangesEvent()
|
|
{
|
|
var entities = this.ChangeTracker.Entries()
|
|
.Where(u => (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added)).ToList();
|
|
if (entities == null || entities.Count < 1) return;
|
|
|
|
string uid = this.httpContextAccessor.HttpContext?.User?.Identity?.Name;
|
|
|
|
if (string.IsNullOrEmpty(uid))
|
|
{
|
|
uid = string.Empty;
|
|
string token = GetJwtBearerToken(httpContextAccessor.HttpContext!);
|
|
if (!string.IsNullOrEmpty(token))
|
|
{
|
|
try
|
|
{
|
|
JsonWebToken json = new JsonWebTokenHandler().ReadJsonWebToken(token);
|
|
uid = json.GetClaim(ClaimPolicy.CLAINM_USERID).Value;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
foreach (var entity in entities)
|
|
{
|
|
if (!(entity.State == EntityState.Added || entity.State == EntityState.Modified)) continue;
|
|
|
|
// 获取所有实体有效属性,排除 [NotMapper] 属性
|
|
var props = entity.OriginalValues.Properties;
|
|
|
|
// 获取实体当前(现在)的值
|
|
var currentValues = entity.CurrentValues;
|
|
|
|
// 遍历所有属性
|
|
foreach (var prop in props)
|
|
{
|
|
// 获取属性名
|
|
var propName = prop.Name;
|
|
if (propName == IEntityAudited.CREATED_BY && entity.State == EntityState.Added)
|
|
{
|
|
currentValues[propName] = uid;
|
|
continue;
|
|
}
|
|
|
|
if (propName == IEntityAudited.CREATED_DATETIME && entity.State == EntityState.Added)
|
|
{
|
|
currentValues[propName] = DateTime.Now;
|
|
continue;
|
|
}
|
|
|
|
if (propName == IEntityAudited.UPDATED_BY)
|
|
{
|
|
currentValues[propName] = uid;
|
|
continue;
|
|
}
|
|
|
|
if (propName == IEntityAudited.UPDATED_DATETIME)
|
|
{
|
|
currentValues[propName] = DateTime.Now;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void OnModelCreating(ModelBuilder builder)
|
|
{
|
|
foreach (IMasterRegistEntityType<ModelBuilder> entityManager in _entityManagers)
|
|
{
|
|
entityManager.RegistEntity(builder);
|
|
}
|
|
|
|
base.OnModelCreating(builder);
|
|
}
|
|
|
|
public string GetJwtBearerToken(HttpContext httpContext, string headerKey = "Authorization", string tokenPrefix = "Bearer ")
|
|
{
|
|
if (httpContext == null) return null;
|
|
// 判断请求报文头中是否有 "Authorization" 报文头
|
|
var bearerToken = httpContext.Request.Headers[headerKey].ToString();
|
|
if (string.IsNullOrWhiteSpace(bearerToken)) return default;
|
|
|
|
var prefixLenght = tokenPrefix.Length;
|
|
return bearerToken.StartsWith(tokenPrefix, true, null) && bearerToken.Length > prefixLenght ? bearerToken[prefixLenght..] : default;
|
|
}
|
|
|
|
}
|
|
}
|