完善系统通知,增加系统通知日志记录已读和未读通知

This commit is contained in:
YUN-PC5\user 2023-09-28 14:49:16 +08:00
parent b932f6f6a0
commit 1c08c837e6
11 changed files with 237 additions and 36 deletions

View File

@ -0,0 +1,8 @@
namespace ZR.Infrastructure.Constant;
public class SysNoticeLogStatus
{
public const string Unread = "0";
public const string Read = "1";
}

View File

@ -80,18 +80,23 @@ namespace ZR.Admin.WebApi.Controllers.System
public IActionResult AddSysNotice([FromBody] SysNoticeDto parm) public IActionResult AddSysNotice([FromBody] SysNoticeDto parm)
{ {
var modal = parm.Adapt<SysNotice>().ToCreate(HttpContext); var modal = parm.Adapt<SysNotice>().ToCreate(HttpContext);
modal.Create_by = HttpContext.GetUId();
modal.Create_name = HttpContext.GetNickName();
modal.Create_time = DateTime.Now;
// int result = _SysNoticeService.Insert(modal, it => new
// {
// it.NoticeTitle,
// it.NoticeType,
// it.NoticeContent,
// it.Status,
// it.Remark,
// it.Create_by,
// it.Create_time
// });
var result = _SysNoticeService.Insertable(modal).ExecuteReturnSnowflakeId();
int result = _SysNoticeService.Insert(modal, it => new
{
it.NoticeTitle,
it.NoticeType,
it.NoticeContent,
it.Status,
it.Remark,
it.Create_by,
it.Create_time
});
return SUCCESS(result); return SUCCESS(result);
} }
@ -104,9 +109,11 @@ namespace ZR.Admin.WebApi.Controllers.System
[Log(Title = "修改公告", BusinessType = BusinessType.UPDATE)] [Log(Title = "修改公告", BusinessType = BusinessType.UPDATE)]
public IActionResult UpdateSysNotice([FromBody] SysNoticeDto parm) public IActionResult UpdateSysNotice([FromBody] SysNoticeDto parm)
{ {
var model = parm.Adapt<SysNotice>().ToUpdate(HttpContext); var config = new TypeAdapterConfig();
model.Update_by = HttpContext.GetUId(); config.ForType<SysNoticeDto, SysNotice>()
model.Update_name = HttpContext.GetNickName(); .Map(dest => dest.NoticeId, src => src.NoticeId.ParseToLong());
var model = parm.Adapt<SysNotice>(config).ToUpdate(HttpContext);
var response = _SysNoticeService.Update(w => w.NoticeId == model.NoticeId, it => new SysNotice() var response = _SysNoticeService.Update(w => w.NoticeId == model.NoticeId, it => new SysNotice()
{ {
NoticeTitle = model.NoticeTitle, NoticeTitle = model.NoticeTitle,
@ -128,7 +135,7 @@ namespace ZR.Admin.WebApi.Controllers.System
[HttpPut("send/{NoticeId}")] [HttpPut("send/{NoticeId}")]
[ActionPermissionFilter(Permission = "system:notice:update")] [ActionPermissionFilter(Permission = "system:notice:update")]
[Log(Title = "发送通知公告", BusinessType = BusinessType.OTHER)] [Log(Title = "发送通知公告", BusinessType = BusinessType.OTHER)]
public IActionResult SendNotice(int NoticeId = 0) public IActionResult SendNotice(long NoticeId = 0)
{ {
if (NoticeId <= 0) if (NoticeId <= 0)
{ {

View File

@ -101,9 +101,9 @@
}, },
//redis //redis
"RedisServer": { "RedisServer": {
"open": 0, //redis "open": 1, //redis
"Cache": "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=cache:", "Cache": "8.140.174.251:6379,password=Wyd210213,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=cache:",
"Session": "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=session:" "Session": "8.140.174.251:6379,password=Wyd210213,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=session:"
}, },
// //
"IpRateLimiting": { "IpRateLimiting": {
@ -135,6 +135,17 @@
}, },
// //
"CaptchaOptions": { "CaptchaOptions": {
"IgnoreCase": true // "CaptchaType": 10,
"IgnoreCase": true, //
"ImageOption": {
"FontSize": 36, //
"Animation": true, //
"TextBold": true, //
"InterferenceLineCount": 4, // 线
"BubbleMinRadius": 5, //
"BubbleMaxRadius": 10, //
"BubbleCount": 3, //
"BubbleThickness": 1.0 // 沿
}
} }
} }

View File

@ -8,13 +8,14 @@ namespace ZR.ServiceCore.Model.Dto
/// </summary> /// </summary>
public class SysNoticeDto public class SysNoticeDto
{ {
public int NoticeId { get; set; } public string NoticeId { get; set; }
[Required] [Required]
public string NoticeTitle { get; set; } public string NoticeTitle { get; set; }
public int NoticeType { get; set; } public int NoticeType { get; set; }
public string NoticeContent { get; set; } public string NoticeContent { get; set; }
public int Status { get; set; } public int Status { get; set; }
public string Remark { get; set; } public string Remark { get; set; }
public DateTime Create_time { get; set; }
} }
/// <summary> /// <summary>

View File

@ -15,8 +15,9 @@ namespace ZR.ServiceCore.Model
/// <summary> /// <summary>
/// 公告ID /// 公告ID
/// </summary> /// </summary>
[SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnName = "notice_id")] [SugarColumn(IsPrimaryKey = true, ColumnName = "notice_id")]
public int NoticeId { get; set; } [JsonConverter(typeof(ValueToStringConverter))]
public long NoticeId { get; set; }
/// <summary> /// <summary>
/// 公告标题 /// 公告标题
/// </summary> /// </summary>

View File

@ -0,0 +1,13 @@
namespace ZR.Model.System;
[SugarTable("sys_notice_log")]
public class SysNoticeLog
{
[JsonConverter(typeof(ValueToStringConverter))]
public long NoticeId { get; set; }
[JsonConverter(typeof(ValueToStringConverter))]
public long UserId { get; set; }
public string Status { get; set; }
}

View File

@ -0,0 +1,9 @@
using ZR.Model.System;
using ZR.Service;
namespace ZR.ServiceCore.Services.IService;
public interface ISysNoticeLogService : IBaseService<SysNoticeLog>
{
}

View File

@ -0,0 +1,6 @@
namespace ZR.ServiceCore.Services.IService;
public class ISysRoleFieldService
{
}

View File

@ -0,0 +1,12 @@
using Infrastructure.Attribute;
using ZR.Model.System;
using ZR.Service;
using ZR.ServiceCore.Services.IService;
namespace ZR.ServiceCore.Services;
[AppService(ServiceType = typeof(ISysNoticeLogService), ServiceLifetime = LifeTime.Transient)]
public class SysNoticeLogService : BaseService<SysNoticeLog>, ISysNoticeLogService
{
}

View File

@ -3,8 +3,14 @@ using Infrastructure.Model;
using IPTools.Core; using IPTools.Core;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using System.Web; using System.Web;
using Mapster;
using UAParser; using UAParser;
using ZR.Infrastructure.Constant;
using ZR.Model.System;
using ZR.Service.System.IService; using ZR.Service.System.IService;
using ZR.ServiceCore.Model;
using ZR.ServiceCore.Model.Dto;
using ZR.ServiceCore.Services.IService;
namespace ZR.ServiceCore.Signalr namespace ZR.ServiceCore.Signalr
{ {
@ -18,10 +24,12 @@ namespace ZR.ServiceCore.Signalr
public static List<OnlineUsers> users = new(); public static List<OnlineUsers> users = new();
//private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); //private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly ISysNoticeService SysNoticeService; private readonly ISysNoticeService SysNoticeService;
private readonly ISysNoticeLogService _sysNoticeLogService;
public MessageHub(ISysNoticeService noticeService) public MessageHub(ISysNoticeService noticeService, ISysNoticeLogService sysNoticeLogService)
{ {
SysNoticeService = noticeService; SysNoticeService = noticeService;
_sysNoticeLogService = sysNoticeLogService;
} }
private ApiResult SendNotice() private ApiResult SendNotice()
@ -68,7 +76,55 @@ namespace ZR.ServiceCore.Signalr
onlineClients.Add(onlineUser); onlineClients.Add(onlineUser);
Log.WriteLine(msg: $"{name},{Context.ConnectionId}连接服务端success当前已连接{onlineClients.Count}个"); Log.WriteLine(msg: $"{name},{Context.ConnectionId}连接服务端success当前已连接{onlineClients.Count}个");
//Clients.All.SendAsync("welcome", $"欢迎您:{name},当前时间:{DateTime.Now}"); //Clients.All.SendAsync("welcome", $"欢迎您:{name},当前时间:{DateTime.Now}");
Clients.Caller.SendAsync(HubsConstant.MoreNotice, SendNotice());
var noticeRes = (List<SysNotice>) SendNotice()[ApiResult.DATA_TAG];
var notifications = _sysNoticeLogService.Queryable()
.Where(it => it.UserId == userid)
.ToList();
var unreadNotificationIds = notifications
.Where(it => it.Status == SysNoticeLogStatus.Unread)
.Select(it => it.NoticeId)
.ToList();
var readNotificationIds = notifications
.Where(it => it.Status == SysNoticeLogStatus.Read)
.Select(it => it.NoticeId)
.ToList();
var unreadAndReadNoticeIds = unreadNotificationIds
.Union(readNotificationIds).ToList();
foreach (var notice in noticeRes.Select(it => it.NoticeId).ToList().Except(unreadAndReadNoticeIds))
{
_sysNoticeLogService.Insertable(new SysNoticeLog
{
NoticeId = notice,
UserId = userid,
Status = SysNoticeLogStatus.Unread
}).ExecuteCommand();
}
foreach (var notice in unreadAndReadNoticeIds.Except(noticeRes.Select(it => it.NoticeId).ToList()))
{
_sysNoticeLogService.Deleteable()
.Where(it => it.UserId == userid && it.NoticeId == notice)
.ExecuteCommand();
}
var newUnReadNotificationIds = _sysNoticeLogService
.Queryable().Where(it => it.Status == SysNoticeLogStatus.Unread && it.UserId == userid)
.Select(it => it.NoticeId)
.ToList();
var newReadNotificationIds = _sysNoticeLogService
.Queryable().Where(it => it.Status == SysNoticeLogStatus.Read && it.UserId == userid)
.Select(it => it.NoticeId)
.ToList();
var config = new TypeAdapterConfig();
config.ForType<SysNotice, SysNoticeDto>()
.Map(dest => dest.NoticeId, src => src.NoticeId.ToString());
var newUnReadNotifications = noticeRes.Where(it =>
newUnReadNotificationIds.Contains(it.NoticeId)).ToList().Adapt<List<SysNoticeDto>>(config);
var newReadNotifications = noticeRes.Where(it =>
newReadNotificationIds.Contains(it.NoticeId)).ToList().Adapt<List<SysNoticeDto>>(config);
Clients.Caller.SendAsync(HubsConstant.MoreNotice, newUnReadNotifications, newReadNotifications);
// Clients.Caller.SendAsync(HubsConstant.MoreNotice, SendNotice());
// Clients.Caller.SendAsync(HubsConstant.ConnId, onlineUser.ConnnectionId); // Clients.Caller.SendAsync(HubsConstant.ConnId, onlineUser.ConnnectionId);
} }
OnlineUsers userInfo = GetUserById(userid); OnlineUsers userInfo = GetUserById(userid);
@ -174,6 +230,82 @@ namespace ZR.ServiceCore.Signalr
Console.WriteLine($"用户{userName}对{toConnectId}-{toUserId}说:{message}"); Console.WriteLine($"用户{userName}对{toConnectId}-{toUserId}说:{message}");
} }
/// <summary>
/// 全部标为已读
/// </summary>
[HubMethodName("AllReadNotice")]
public async Task AllReadNotice()
{
var userId = HttpContextExtension.GetUId(App.HttpContext);
var unreadNotificationIds = await _sysNoticeLogService.Queryable()
.Where(it => it.Status == SysNoticeLogStatus.Unread && it.UserId == userId)
.Select(it => it.NoticeId)
.ToListAsync();
foreach (var notice in unreadNotificationIds)
{
await _sysNoticeLogService.Updateable(new SysNoticeLog
{
Status = SysNoticeLogStatus.Read
})
.IgnoreColumns(it => new { it.NoticeId, it.UserId })
.Where(it => it.UserId == userId && it.NoticeId == notice
&& it.Status == SysNoticeLogStatus.Unread)
.ExecuteCommandAsync();
}
var newNotifications = await _sysNoticeLogService.Queryable()
.Where(it => it.UserId == userId)
.ToListAsync();
var newUnReadNotificationIds = newNotifications
.Where(it => it.Status == SysNoticeLogStatus.Unread)
.Select(it => it.NoticeId)
.ToList();
var newReadNotificationIds = newNotifications
.Where(it => it.Status == SysNoticeLogStatus.Read)
.Select(it => it.NoticeId)
.ToList();
var noticeRes = (List<SysNotice>) SendNotice()[ApiResult.DATA_TAG];
var newUnReadNotifications = noticeRes.Where(it =>
newUnReadNotificationIds.Contains(it.NoticeId)).ToList();
var newReadNotifications = noticeRes.Where(it =>
newReadNotificationIds.Contains(it.NoticeId)).ToList();
await Clients.Caller.SendAsync(HubsConstant.MoreNotice, newUnReadNotifications, newReadNotifications);
}
/// <summary>
/// 标记已读
/// </summary>
/// <param name="noticeId"></param>
[HubMethodName("ReadNotice")]
public async Task ReadNotice(string noticeId)
{
var userid = HttpContextExtension.GetUId(App.HttpContext);
await _sysNoticeLogService.Updateable(new SysNoticeLog
{
Status = SysNoticeLogStatus.Read
})
.IgnoreColumns(it => new { it.NoticeId, it.UserId })
.Where(it => it.NoticeId == noticeId.ParseToLong() && it.UserId == userid
&& it.Status == SysNoticeLogStatus.Unread)
.ExecuteCommandAsync();
var newNotifications = await _sysNoticeLogService.Queryable()
.Where(it => it.UserId == userid)
.ToListAsync();
var newUnReadNotificationIds = newNotifications
.Where(it => it.Status == SysNoticeLogStatus.Unread)
.Select(it => it.NoticeId)
.ToList();
var newReadNotificationIds = newNotifications
.Where(it => it.Status == SysNoticeLogStatus.Read)
.Select(it => it.NoticeId)
.ToList();
var noticeRes = (List<SysNotice>) SendNotice()[ApiResult.DATA_TAG];
var newUnReadNotifications = noticeRes.Where(it =>
newUnReadNotificationIds.Contains(it.NoticeId)).ToList();
var newReadNotifications = noticeRes.Where(it =>
newReadNotificationIds.Contains(it.NoticeId)).ToList();
await Clients.Caller.SendAsync(HubsConstant.MoreNotice, newUnReadNotifications, newReadNotifications);
}
private OnlineUsers GetUserByConnId(string connId) private OnlineUsers GetUserByConnId(string connId)
{ {
return onlineClients.Where(p => p.ConnnectionId == connId).FirstOrDefault(); return onlineClients.Where(p => p.ConnnectionId == connId).FirstOrDefault();

View File

@ -1,4 +1,5 @@
using ZR.Common; using ZR.Common;
using ZR.Common.Cache;
namespace ZR.ServiceCore.SqlSugar namespace ZR.ServiceCore.SqlSugar
{ {
@ -6,32 +7,32 @@ namespace ZR.ServiceCore.SqlSugar
{ {
public void Add<V>(string key, V value) public void Add<V>(string key, V value)
{ {
//RedisServer.Cache.Set(key, value, 3600 + RedisHelper.RandomExpired(5, 30)); RedisServer.Cache.Set(key, value, 3600 + RedisHelper.RandomExpired(5, 30));
CacheHelper.SetCache(key, value); // CacheHelper.SetCache(key, value);
} }
public void Add<V>(string key, V value, int cacheDurationInSeconds) public void Add<V>(string key, V value, int cacheDurationInSeconds)
{ {
//RedisServer.Cache.Set(key, value, cacheDurationInSeconds); RedisServer.Cache.Set(key, value, cacheDurationInSeconds);
CacheHelper.SetCaches(key, value, cacheDurationInSeconds); // CacheHelper.SetCaches(key, value, cacheDurationInSeconds);
} }
public bool ContainsKey<V>(string key) public bool ContainsKey<V>(string key)
{ {
//return RedisServer.Cache.Exists(key); return RedisServer.Cache.Exists(key);
return CacheHelper.Exists(key); // return CacheHelper.Exists(key);
} }
public V Get<V>(string key) public V Get<V>(string key)
{ {
//return RedisServer.Cache.Get<V>(key); return RedisServer.Cache.Get<V>(key);
return (V)CacheHelper.Get(key); // return (V)CacheHelper.Get(key);
} }
public IEnumerable<string> GetAllKey<V>() public IEnumerable<string> GetAllKey<V>()
{ {
//return RedisServer.Cache.Keys("*"); return RedisServer.Cache.Keys("*");
return CacheHelper.GetCacheKeys(); // return CacheHelper.GetCacheKeys();
} }
public V GetOrCreate<V>(string cacheKey, Func<V> create, int cacheDurationInSeconds = int.MaxValue) public V GetOrCreate<V>(string cacheKey, Func<V> create, int cacheDurationInSeconds = int.MaxValue)
@ -59,8 +60,8 @@ namespace ZR.ServiceCore.SqlSugar
public void Remove<V>(string key) public void Remove<V>(string key)
{ {
//RedisServer.Cache.Del(key); RedisServer.Cache.Del(key);
CacheHelper.Remove(key); // CacheHelper.Remove(key);
} }
} }
} }