using System.Reflection;
using Abp.Auditing;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.Runtime.Caching;
using Castle.Core.Logging;
using VberZero.BaseSystem;
using VberZero.Configuration;
using VberZero.Tools.StringModel;
using ILogger = Castle.Core.Logging.ILogger;
namespace VberZero.Auditing;
///
/// 实现 将审计信息保存到数据库。
///
public class VzAuditingStore : IAuditingStore, ITransientDependency
{
private readonly IRepository _auditLogRepository;
private readonly IRepository _funRepository;
private readonly ICacheManager _cacheManager;
private readonly IConfigurationRoot _appConfiguration;
public ILogger Logger { get; set; }
private SysFunction SysFunction { get; set; }
private Type Type { get; set; }
private string MethodNameSuffix { get; set; }
public VzAuditingStore(IRepository auditLogRepository, IRepository funRepository, ICacheManager cacheManager, IWebHostEnvironment env)
{
_auditLogRepository = auditLogRepository;
_funRepository = funRepository;
_cacheManager = cacheManager;
_appConfiguration = env.GetAppConfiguration();
Logger = NullLogger.Instance;
}
public virtual Task SaveAsync(AuditInfo auditInfo)
{
return _auditLogRepository.InsertAsync(CreateFromAuditInfo(auditInfo));
}
public virtual void Save(AuditInfo auditInfo)
{
_auditLogRepository.Insert(CreateFromAuditInfo(auditInfo));
}
protected virtual AuditLog CreateFromAuditInfo(AuditInfo auditInfo)
{
var log = AuditLog.CreateFromAuditInfo(auditInfo);
SysFunction = null;
Type = null;
MethodNameSuffix = "";
log = ConvertServiceName(log);
int logType = auditInfo.ServiceName == log.ServiceName ? 0 : 1;
if (logType != 0)
{
log = GetMethodName(log, auditInfo.ServiceName);
logType = auditInfo.MethodName == log.MethodName ? 0 : 1;
}
log.LogType = logType;
return log;
}
public AuditLog ConvertServiceName(AuditLog log)
{
if (log.ServiceName.NotEmpty())
{
try
{
var sName = log.ServiceName.Substring(log.ServiceName.LastIndexOf(".", StringComparison.Ordinal) + 1).Replace("sAppService", "").Replace("AppService", "").Replace("Controller", "");
log.ServiceNameLang = $"Log_{sName}";
log.ServiceName = _cacheManager.GetCache(VzConsts.CacheAuditLogDesc).Get(log.ServiceName, () => GetServiceName(sName, log.ServiceName));
}
catch (Exception e)
{
Logger.Error(e.Message, e);
}
}
return log;
}
private string GetServiceName(string funNo, string serviceName)
{
if (serviceName.Empty())
{
return serviceName;
}
SysFunction = _funRepository.FirstOrDefault(a => a.Name == funNo);
return SysFunction == null ? GetServiceNameByAttr(serviceName) : SysFunction.DisplayName;
}
private string GetServiceNameByAttr(string serviceName)
{
Type = GetType(serviceName);
if (Type != null)
{
var attr = GetSingleAttribute(Type);
if (attr != null)
{
serviceName = attr.Name;
MethodNameSuffix = attr.MethodNameSuffix ?? "";
}
}
return serviceName;
}
public AuditLog GetMethodName(AuditLog log, string serviceName)
{
if (log.MethodName.NotEmpty())
{
try
{
log.MethodNameLang = $"Log_{log.MethodName}";
log.MethodName = _cacheManager.GetCache(VzConsts.CacheAuditLogDesc).Get(
serviceName + "_" + log.MethodName, () => GetMethodName(log.MethodName, log.MethodName, serviceName));
}
catch (Exception e)
{
Logger.Error(e.Message, e);
}
}
return log;
}
private string GetMethodName(string funNo, string methodName, string serviceName)
{
if (methodName.Empty())
{
return methodName;
}
if (SysFunction == null)
{
return GetMethodNameByAttr(methodName, serviceName);
}
var fun = _funRepository.FirstOrDefault(a =>
a.Name == funNo && a.ParentNo == SysFunction.Id);
return fun == null ? GetMethodNameByAttr(methodName, serviceName) : fun.DisplayName;
}
private string GetMethodNameByAttr(string methodName, string serviceName)
{
Type ??= GetType(serviceName);
var member = Type?.GetMember(methodName).FirstOrDefault();
if (member != null)
{
var attr = GetMemberSingleAttribute(member);
if (attr != null)
{
methodName = attr.Name;
}
else
{
switch (methodName.ToLower())
{
case "get":
methodName = "查询";
break;
case "getall":
methodName = "查询";
break;
case "create":
methodName = "创建";
break;
case "update":
methodName = "修改";
break;
case "delete":
methodName = "删除";
break;
case "auth":
methodName = "授权";
break;
case "refresh":
methodName = "刷新";
break;
case "moveup":
methodName = "上移";
break;
case "movedown":
methodName = "下移";
break;
}
if (MethodNameSuffix.Empty())
{
MethodNameSuffix = GetMethodNameSuffixAttr(serviceName);
}
return methodName + MethodNameSuffix;
}
}
return methodName;
}
private string GetMethodNameSuffixAttr(string serviceName)
{
Type = GetType(serviceName);
var attr = GetSingleAttribute(Type);
if (attr != null)
{
return attr.MethodNameSuffix ?? "";
}
return "";
}
private Type GetType(string typeName)
{
string appAssemblyName = _appConfiguration["Auditing:AppAssembly"];
var path = AppDomain.CurrentDomain.BaseDirectory;
Assembly assembly = Assembly.LoadFrom(Path.Combine(path, appAssemblyName));
var type = GetTypeFromAssembly(assembly, typeName);
if (type == null)
{
string webAssemblyName = _appConfiguration["Auditing:WebAssembly"];
assembly = Assembly.LoadFrom(Path.Combine(path, webAssemblyName));
type = GetTypeFromAssembly(assembly, typeName);
}
return type;
}
public static TAttribute GetSingleAttribute(Type type, TAttribute defaultValue = default(TAttribute), bool inherit = true)
where TAttribute : Attribute
{
return type.GetCustomAttributes(inherit).OfType().FirstOrDefault()
?? type.ReflectedType?.GetTypeInfo().GetCustomAttributes(inherit).OfType().FirstOrDefault()
?? defaultValue;
}
public static TAttribute GetMemberSingleAttribute(MemberInfo memberInfo, TAttribute defaultValue = default(TAttribute), bool inherit = true)
where TAttribute : Attribute
{
if (memberInfo.IsDefined(typeof(TAttribute), inherit))
{
return memberInfo.GetCustomAttributes(typeof(TAttribute), inherit).Cast().First();
}
return defaultValue;
}
public static Type GetTypeFromAssembly(Assembly assembly, string typeName)
{
Type[] typeArray = assembly.GetTypes();
foreach (var type in typeArray)
{
if ((type.FullName != null && type.FullName.Equals(typeName)) || type.Name.Equals(typeName))
{
return type;
}
}
return null;
}
}