VzAuditingStore.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. using System.Reflection;
  2. using Abp.Auditing;
  3. using Abp.Dependency;
  4. using Abp.Domain.Repositories;
  5. using Abp.Runtime.Caching;
  6. using Castle.Core.Logging;
  7. using VberZero.BaseSystem;
  8. using VberZero.Configuration;
  9. using VberZero.Tools.StringModel;
  10. using ILogger = Castle.Core.Logging.ILogger;
  11. namespace VberZero.Auditing;
  12. /// <summary>
  13. /// 实现 <see cref="IAuditingStore"/> 将审计信息保存到数据库。
  14. /// </summary>
  15. public class VzAuditingStore : IAuditingStore, ITransientDependency
  16. {
  17. private readonly IRepository<AuditLog, long> _auditLogRepository;
  18. private readonly IRepository<SysFunction, int?> _funRepository;
  19. private readonly ICacheManager _cacheManager;
  20. private readonly IConfigurationRoot _appConfiguration;
  21. public ILogger Logger { get; set; }
  22. private SysFunction SysFunction { get; set; }
  23. private Type Type { get; set; }
  24. private string MethodNameSuffix { get; set; }
  25. public VzAuditingStore(IRepository<AuditLog, long> auditLogRepository, IRepository<SysFunction, int?> funRepository, ICacheManager cacheManager, IWebHostEnvironment env)
  26. {
  27. _auditLogRepository = auditLogRepository;
  28. _funRepository = funRepository;
  29. _cacheManager = cacheManager;
  30. _appConfiguration = env.GetAppConfiguration();
  31. Logger = NullLogger.Instance;
  32. }
  33. public virtual Task SaveAsync(AuditInfo auditInfo)
  34. {
  35. return _auditLogRepository.InsertAsync(CreateFromAuditInfo(auditInfo));
  36. }
  37. public virtual void Save(AuditInfo auditInfo)
  38. {
  39. _auditLogRepository.Insert(CreateFromAuditInfo(auditInfo));
  40. }
  41. protected virtual AuditLog CreateFromAuditInfo(AuditInfo auditInfo)
  42. {
  43. var log = AuditLog.CreateFromAuditInfo(auditInfo);
  44. SysFunction = null;
  45. Type = null;
  46. MethodNameSuffix = "";
  47. log = ConvertServiceName(log);
  48. int logType = auditInfo.ServiceName == log.ServiceName ? 0 : 1;
  49. if (logType != 0)
  50. {
  51. log = GetMethodName(log, auditInfo.ServiceName);
  52. logType = auditInfo.MethodName == log.MethodName ? 0 : 1;
  53. }
  54. log.LogType = logType;
  55. return log;
  56. }
  57. public AuditLog ConvertServiceName(AuditLog log)
  58. {
  59. if (log.ServiceName.NotEmpty())
  60. {
  61. try
  62. {
  63. var sName = log.ServiceName.Substring(log.ServiceName.LastIndexOf(".", StringComparison.Ordinal) + 1).Replace("sAppService", "").Replace("AppService", "").Replace("Controller", "");
  64. log.ServiceNameLang = $"Log_{sName}";
  65. log.ServiceName = _cacheManager.GetCache<string, string>(VzConsts.CacheAuditLogDesc).Get(log.ServiceName, () => GetServiceName(sName, log.ServiceName));
  66. }
  67. catch (Exception e)
  68. {
  69. Logger.Error(e.Message, e);
  70. }
  71. }
  72. return log;
  73. }
  74. private string GetServiceName(string funNo, string serviceName)
  75. {
  76. if (serviceName.Empty())
  77. {
  78. return serviceName;
  79. }
  80. SysFunction = _funRepository.FirstOrDefault(a => a.Name == funNo);
  81. return SysFunction == null ? GetServiceNameByAttr(serviceName) : SysFunction.DisplayName;
  82. }
  83. private string GetServiceNameByAttr(string serviceName)
  84. {
  85. Type = GetType(serviceName);
  86. if (Type != null)
  87. {
  88. var attr = GetSingleAttribute<AuditLogAttribute>(Type);
  89. if (attr != null)
  90. {
  91. serviceName = attr.Name;
  92. MethodNameSuffix = attr.MethodNameSuffix ?? "";
  93. }
  94. }
  95. return serviceName;
  96. }
  97. public AuditLog GetMethodName(AuditLog log, string serviceName)
  98. {
  99. if (log.MethodName.NotEmpty())
  100. {
  101. try
  102. {
  103. log.MethodNameLang = $"Log_{log.MethodName}";
  104. log.MethodName = _cacheManager.GetCache<string, string>(VzConsts.CacheAuditLogDesc).Get(
  105. serviceName + "_" + log.MethodName, () => GetMethodName(log.MethodName, log.MethodName, serviceName));
  106. }
  107. catch (Exception e)
  108. {
  109. Logger.Error(e.Message, e);
  110. }
  111. }
  112. return log;
  113. }
  114. private string GetMethodName(string funNo, string methodName, string serviceName)
  115. {
  116. if (methodName.Empty())
  117. {
  118. return methodName;
  119. }
  120. if (SysFunction == null)
  121. {
  122. return GetMethodNameByAttr(methodName, serviceName);
  123. }
  124. var fun = _funRepository.FirstOrDefault(a =>
  125. a.Name == funNo && a.ParentNo == SysFunction.Id);
  126. return fun == null ? GetMethodNameByAttr(methodName, serviceName) : fun.DisplayName;
  127. }
  128. private string GetMethodNameByAttr(string methodName, string serviceName)
  129. {
  130. Type ??= GetType(serviceName);
  131. var member = Type?.GetMember(methodName).FirstOrDefault();
  132. if (member != null)
  133. {
  134. var attr = GetMemberSingleAttribute<AuditLogAttribute>(member);
  135. if (attr != null)
  136. {
  137. methodName = attr.Name;
  138. }
  139. else
  140. {
  141. switch (methodName.ToLower())
  142. {
  143. case "get":
  144. methodName = "查询";
  145. break;
  146. case "getall":
  147. methodName = "查询";
  148. break;
  149. case "create":
  150. methodName = "创建";
  151. break;
  152. case "update":
  153. methodName = "修改";
  154. break;
  155. case "delete":
  156. methodName = "删除";
  157. break;
  158. case "auth":
  159. methodName = "授权";
  160. break;
  161. case "refresh":
  162. methodName = "刷新";
  163. break;
  164. case "moveup":
  165. methodName = "上移";
  166. break;
  167. case "movedown":
  168. methodName = "下移";
  169. break;
  170. }
  171. if (MethodNameSuffix.Empty())
  172. {
  173. MethodNameSuffix = GetMethodNameSuffixAttr(serviceName);
  174. }
  175. return methodName + MethodNameSuffix;
  176. }
  177. }
  178. return methodName;
  179. }
  180. private string GetMethodNameSuffixAttr(string serviceName)
  181. {
  182. Type = GetType(serviceName);
  183. var attr = GetSingleAttribute<AuditLogAttribute>(Type);
  184. if (attr != null)
  185. {
  186. return attr.MethodNameSuffix ?? "";
  187. }
  188. return "";
  189. }
  190. private Type GetType(string typeName)
  191. {
  192. string appAssemblyName = _appConfiguration["Auditing:AppAssembly"];
  193. var path = AppDomain.CurrentDomain.BaseDirectory;
  194. Assembly assembly = Assembly.LoadFrom(Path.Combine(path, appAssemblyName));
  195. var type = GetTypeFromAssembly(assembly, typeName);
  196. if (type == null)
  197. {
  198. string webAssemblyName = _appConfiguration["Auditing:WebAssembly"];
  199. assembly = Assembly.LoadFrom(Path.Combine(path, webAssemblyName));
  200. type = GetTypeFromAssembly(assembly, typeName);
  201. }
  202. return type;
  203. }
  204. public static TAttribute GetSingleAttribute<TAttribute>(Type type, TAttribute defaultValue = default(TAttribute), bool inherit = true)
  205. where TAttribute : Attribute
  206. {
  207. return type.GetCustomAttributes(inherit).OfType<TAttribute>().FirstOrDefault()
  208. ?? type.ReflectedType?.GetTypeInfo().GetCustomAttributes(inherit).OfType<TAttribute>().FirstOrDefault()
  209. ?? defaultValue;
  210. }
  211. public static TAttribute GetMemberSingleAttribute<TAttribute>(MemberInfo memberInfo, TAttribute defaultValue = default(TAttribute), bool inherit = true)
  212. where TAttribute : Attribute
  213. {
  214. if (memberInfo.IsDefined(typeof(TAttribute), inherit))
  215. {
  216. return memberInfo.GetCustomAttributes(typeof(TAttribute), inherit).Cast<TAttribute>().First();
  217. }
  218. return defaultValue;
  219. }
  220. public static Type GetTypeFromAssembly(Assembly assembly, string typeName)
  221. {
  222. Type[] typeArray = assembly.GetTypes();
  223. foreach (var type in typeArray)
  224. {
  225. if ((type.FullName != null && type.FullName.Equals(typeName)) || type.Name.Equals(typeName))
  226. {
  227. return type;
  228. }
  229. }
  230. return null;
  231. }
  232. }