NotificationStore.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. using System.Data.Entity;
  2. using IwbZero.ToolCommon.Lambda;
  3. namespace IwbZero.Notifications
  4. {
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Linq.Expressions;
  9. using System.Threading.Tasks;
  10. using Abp;
  11. using Abp.Dependency;
  12. using Abp.Domain.Repositories;
  13. using Abp.Domain.Uow;
  14. using Abp.Linq.Extensions;
  15. using Abp.Notifications;
  16. namespace IwbZero.Notifications
  17. {
  18. /// <summary>
  19. /// Implements <see cref="INotificationStore"/> using repositories.
  20. /// </summary>
  21. public class NotificationStore : INotificationStore, ITransientDependency
  22. {
  23. private readonly IRepository<NotificationInfo, Guid> _notificationRepository;
  24. private readonly IRepository<TenantNotificationInfo, Guid> _tenantNotificationRepository;
  25. private readonly IRepository<UserNotificationInfo, Guid> _userNotificationRepository;
  26. private readonly IRepository<NotificationSubscriptionInfo, Guid> _notificationSubscriptionRepository;
  27. private readonly IUnitOfWorkManager _unitOfWorkManager;
  28. /// <summary>
  29. /// Initializes a new instance of the <see cref="NotificationStore"/> class.
  30. /// </summary>
  31. public NotificationStore(
  32. IRepository<NotificationInfo, Guid> notificationRepository,
  33. IRepository<TenantNotificationInfo, Guid> tenantNotificationRepository,
  34. IRepository<UserNotificationInfo, Guid> userNotificationRepository,
  35. IRepository<NotificationSubscriptionInfo, Guid> notificationSubscriptionRepository,
  36. IUnitOfWorkManager unitOfWorkManager)
  37. {
  38. _notificationRepository = notificationRepository;
  39. _tenantNotificationRepository = tenantNotificationRepository;
  40. _userNotificationRepository = userNotificationRepository;
  41. _notificationSubscriptionRepository = notificationSubscriptionRepository;
  42. _unitOfWorkManager = unitOfWorkManager;
  43. }
  44. [UnitOfWork]
  45. public virtual async Task InsertSubscriptionAsync(NotificationSubscriptionInfo subscription)
  46. {
  47. using (_unitOfWorkManager.Current.SetTenantId(subscription.TenantId))
  48. {
  49. await _notificationSubscriptionRepository.InsertAsync(subscription);
  50. await _unitOfWorkManager.Current.SaveChangesAsync();
  51. }
  52. }
  53. [UnitOfWork]
  54. public virtual async Task DeleteSubscriptionAsync(UserIdentifier user, string notificationName, string entityTypeName, string entityId)
  55. {
  56. using (_unitOfWorkManager.Current.SetTenantId(user.TenantId))
  57. {
  58. await _notificationSubscriptionRepository.DeleteAsync(s =>
  59. s.UserId == user.UserId &&
  60. s.NotificationName == notificationName &&
  61. s.EntityTypeName == entityTypeName &&
  62. s.EntityId == entityId
  63. );
  64. await _unitOfWorkManager.Current.SaveChangesAsync();
  65. }
  66. }
  67. [UnitOfWork]
  68. public virtual async Task InsertNotificationAsync(NotificationInfo notification)
  69. {
  70. using (_unitOfWorkManager.Current.SetTenantId(null))
  71. {
  72. await _notificationRepository.InsertAsync(notification);
  73. await _unitOfWorkManager.Current.SaveChangesAsync();
  74. }
  75. }
  76. [UnitOfWork]
  77. public virtual async Task<NotificationInfo> GetNotificationOrNullAsync(Guid notificationId)
  78. {
  79. using (_unitOfWorkManager.Current.SetTenantId(null))
  80. {
  81. return await _notificationRepository.FirstOrDefaultAsync(a => a.Id == notificationId);
  82. }
  83. }
  84. [UnitOfWork]
  85. public virtual async Task InsertUserNotificationAsync(UserNotificationInfo userNotification)
  86. {
  87. using (_unitOfWorkManager.Current.SetTenantId(userNotification.TenantId))
  88. {
  89. await _userNotificationRepository.InsertAsync(userNotification);
  90. await _unitOfWorkManager.Current.SaveChangesAsync();
  91. }
  92. }
  93. [UnitOfWork]
  94. public virtual Task<List<NotificationSubscriptionInfo>> GetSubscriptionsAsync(string notificationName, string entityTypeName, string entityId)
  95. {
  96. using (_unitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant))
  97. {
  98. return _notificationSubscriptionRepository.GetAllListAsync(s =>
  99. s.NotificationName == notificationName &&
  100. s.EntityTypeName == entityTypeName &&
  101. s.EntityId == entityId
  102. );
  103. }
  104. }
  105. [UnitOfWork]
  106. public virtual async Task<List<NotificationSubscriptionInfo>> GetSubscriptionsAsync(int?[] tenantIds, string notificationName, string entityTypeName, string entityId)
  107. {
  108. var subscriptions = new List<NotificationSubscriptionInfo>();
  109. foreach (var tenantId in tenantIds)
  110. {
  111. subscriptions.AddRange(await GetSubscriptionsAsync(tenantId, notificationName, entityTypeName, entityId));
  112. }
  113. return subscriptions;
  114. }
  115. [UnitOfWork]
  116. public virtual async Task<List<NotificationSubscriptionInfo>> GetSubscriptionsAsync(UserIdentifier user)
  117. {
  118. using (_unitOfWorkManager.Current.SetTenantId(user.TenantId))
  119. {
  120. return await _notificationSubscriptionRepository.GetAllListAsync(s => s.UserId == user.UserId);
  121. }
  122. }
  123. [UnitOfWork]
  124. protected virtual async Task<List<NotificationSubscriptionInfo>> GetSubscriptionsAsync(int? tenantId, string notificationName, string entityTypeName, string entityId)
  125. {
  126. using (_unitOfWorkManager.Current.SetTenantId(tenantId))
  127. {
  128. return await _notificationSubscriptionRepository.GetAllListAsync(s =>
  129. s.NotificationName == notificationName &&
  130. s.EntityTypeName == entityTypeName &&
  131. s.EntityId == entityId
  132. );
  133. }
  134. }
  135. [UnitOfWork]
  136. public virtual async Task<bool> IsSubscribedAsync(UserIdentifier user, string notificationName, string entityTypeName, string entityId)
  137. {
  138. using (_unitOfWorkManager.Current.SetTenantId(user.TenantId))
  139. {
  140. return await _notificationSubscriptionRepository.CountAsync(s =>
  141. s.UserId == user.UserId &&
  142. s.NotificationName == notificationName &&
  143. s.EntityTypeName == entityTypeName &&
  144. s.EntityId == entityId
  145. ) > 0;
  146. }
  147. }
  148. [UnitOfWork]
  149. public virtual async Task UpdateUserNotificationStateAsync(int? tenantId, Guid userNotificationId, UserNotificationState state)
  150. {
  151. using (_unitOfWorkManager.Current.SetTenantId(tenantId))
  152. {
  153. var userNotification =
  154. await _userNotificationRepository.FirstOrDefaultAsync(a => a.Id == userNotificationId);
  155. if (userNotification == null)
  156. {
  157. return;
  158. }
  159. userNotification.State = state;
  160. await _unitOfWorkManager.Current.SaveChangesAsync();
  161. }
  162. }
  163. [UnitOfWork]
  164. public virtual async Task UpdateAllUserNotificationStatesAsync(UserIdentifier user, UserNotificationState state)
  165. {
  166. using (_unitOfWorkManager.Current.SetTenantId(user.TenantId))
  167. {
  168. var userNotifications = await _userNotificationRepository.GetAllListAsync(un => un.UserId == user.UserId);
  169. foreach (var userNotification in userNotifications)
  170. {
  171. userNotification.State = state;
  172. }
  173. await _unitOfWorkManager.Current.SaveChangesAsync();
  174. }
  175. }
  176. [UnitOfWork]
  177. public virtual async Task DeleteUserNotificationAsync(int? tenantId, Guid userNotificationId)
  178. {
  179. using (_unitOfWorkManager.Current.SetTenantId(tenantId))
  180. {
  181. await _userNotificationRepository.DeleteAsync(userNotificationId);
  182. await _unitOfWorkManager.Current.SaveChangesAsync();
  183. }
  184. }
  185. [UnitOfWork]
  186. public virtual async Task DeleteAllUserNotificationsAsync(UserIdentifier user, UserNotificationState? state = null, DateTime? startDate = null, DateTime? endDate = null)
  187. {
  188. using (_unitOfWorkManager.Current.SetTenantId(user.TenantId))
  189. {
  190. var predicate = CreateNotificationFilterPredicate(user, state, startDate, endDate);
  191. await _userNotificationRepository.DeleteAsync(predicate);
  192. await _unitOfWorkManager.Current.SaveChangesAsync();
  193. }
  194. }
  195. private Expression<Func<UserNotificationInfo, bool>> CreateNotificationFilterPredicate(UserIdentifier user, UserNotificationState? state = null, DateTime? startDate = null, DateTime? endDate = null)
  196. {
  197. var predicate = LambdaBuilder.New<UserNotificationInfo>();
  198. predicate = predicate.And(p => p.UserId == user.UserId);
  199. if (startDate.HasValue)
  200. {
  201. predicate = predicate.And(p => p.CreationTime >= startDate);
  202. }
  203. if (endDate.HasValue)
  204. {
  205. predicate = predicate.And(p => p.CreationTime <= endDate);
  206. }
  207. if (state.HasValue)
  208. {
  209. predicate = predicate.And(p => p.State == state);
  210. }
  211. return predicate;
  212. }
  213. [UnitOfWork]
  214. public virtual Task<List<UserNotificationInfoWithNotificationInfo>> GetUserNotificationsWithNotificationsAsync(UserIdentifier user, UserNotificationState? state = null, int skipCount = 0, int maxResultCount = int.MaxValue, DateTime? startDate = null, DateTime? endDate = null)
  215. {
  216. using (_unitOfWorkManager.Current.SetTenantId(user.TenantId))
  217. {
  218. var query = from userNotificationInfo in _userNotificationRepository.GetAll()
  219. join tenantNotificationInfo in _tenantNotificationRepository.GetAll().Where(a => a.NotificationName != IwbZeroConsts.IwbNotificationWelcomeMsg) on userNotificationInfo.TenantNotificationId equals tenantNotificationInfo.Id
  220. where userNotificationInfo.UserId == user.UserId
  221. orderby tenantNotificationInfo.CreationTime descending
  222. select new { userNotificationInfo, tenantNotificationInfo };
  223. if (state.HasValue)
  224. {
  225. query = query.Where(x => x.userNotificationInfo.State == state.Value);
  226. }
  227. if (startDate.HasValue)
  228. {
  229. query = query.Where(x => x.tenantNotificationInfo.CreationTime >= startDate);
  230. }
  231. if (endDate.HasValue)
  232. {
  233. query = query.Where(x => x.tenantNotificationInfo.CreationTime <= endDate);
  234. }
  235. query = query.PageBy(skipCount, maxResultCount);
  236. var list = query.ToList();
  237. return Task.FromResult(list.Select(
  238. a => new UserNotificationInfoWithNotificationInfo(a.userNotificationInfo, a.tenantNotificationInfo)
  239. ).ToList());
  240. }
  241. }
  242. [UnitOfWork]
  243. public virtual async Task<int> GetUserNotificationCountAsync(UserIdentifier user, UserNotificationState? state = null, DateTime? startDate = null, DateTime? endDate = null)
  244. {
  245. using (_unitOfWorkManager.Current.SetTenantId(user.TenantId))
  246. {
  247. var predicate = CreateNotificationFilterPredicate(user, state, startDate, endDate);
  248. var query = from userNotificationInfo in _userNotificationRepository.GetAll().Where(predicate)
  249. join tenantNotificationInfo in _tenantNotificationRepository.GetAll().Where(a => a.NotificationName != IwbZeroConsts.IwbNotificationWelcomeMsg) on userNotificationInfo.TenantNotificationId equals tenantNotificationInfo.Id
  250. select userNotificationInfo;
  251. return await query.CountAsync();
  252. }
  253. }
  254. [UnitOfWork]
  255. public virtual Task<UserNotificationInfoWithNotificationInfo> GetUserNotificationWithNotificationOrNullAsync(int? tenantId, Guid userNotificationId)
  256. {
  257. using (_unitOfWorkManager.Current.SetTenantId(tenantId))
  258. {
  259. var query = from userNotificationInfo in _userNotificationRepository.GetAll()
  260. join tenantNotificationInfo in _tenantNotificationRepository.GetAll() on userNotificationInfo.TenantNotificationId equals tenantNotificationInfo.Id
  261. where userNotificationInfo.Id == userNotificationId
  262. select new { userNotificationInfo, tenantNotificationInfo };
  263. var item = query.FirstOrDefault();
  264. if (item == null)
  265. {
  266. return Task.FromResult((UserNotificationInfoWithNotificationInfo)null);
  267. }
  268. return Task.FromResult(new UserNotificationInfoWithNotificationInfo(item.userNotificationInfo, item.tenantNotificationInfo));
  269. }
  270. }
  271. [UnitOfWork]
  272. public virtual async Task InsertTenantNotificationAsync(TenantNotificationInfo tenantNotificationInfo)
  273. {
  274. using (_unitOfWorkManager.Current.SetTenantId(tenantNotificationInfo.TenantId))
  275. {
  276. await _tenantNotificationRepository.InsertAsync(tenantNotificationInfo);
  277. }
  278. }
  279. public virtual Task DeleteNotificationAsync(NotificationInfo notification)
  280. {
  281. return _notificationRepository.DeleteAsync(notification);
  282. }
  283. }
  284. }
  285. }