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; } }