diff --git a/src/ST.Client/Services/INotificationService.cs b/src/ST.Client/Services/INotificationService.cs index e86fb5c99..fc43abcc4 100644 --- a/src/ST.Client/Services/INotificationService.cs +++ b/src/ST.Client/Services/INotificationService.cs @@ -66,14 +66,7 @@ namespace System.Application.Services }; Notify(builder); } - - /// - /// 显示从服务端获取到通知纪录 - /// - /// - [Obsolete("use NoticeDTO")] - void Notify(NotificationRecordDTO notification) - => Notify(notification.Content, notification.Type, title: notification.Title); + /// /// 取消通知 @@ -101,45 +94,20 @@ namespace System.Application.Services /// /// 显示从服务端获取到通知纪录 - /// - /// - /// - [Obsolete("use NoticeDTO")] - static async void Notify(IApiResponse rsp, ActiveUserType type) + /// + static async void Notify(ActiveUserType type) { - if (rsp.IsSuccess && rsp.Content != null) - { - if (type == ActiveUserType.OnStartup) - { - await ISecureStorage.Instance.SetAsync(ON_LAST_STARTUP_NOTIFICATION_RECORD_ID, rsp.Content.Id); - } + if (type == ActiveUserType.OnStartup) + await NotificationService.Current.GetNews(); - if (!rsp.Content.Type.IsDefined()) - { - // 新增通知类型不能兼容旧版本 - return; - } - - if (rsp.Content.Type == NotificationType.Announcement) - { - var announcementService = DI.Get_Nullable(); - if (announcementService != null) - { - var isShow = announcementService.Show(rsp.Content); - if (isShow) return; - } - } - - Instance.Notify(rsp.Content); - } } /// - /// 获取最后一次收到的通知ID + /// 获取最后一次收到的通知启用时间 只提示大于此时间的通知 /// /// - static Task GetLastNotificationRecordId() => ISecureStorage.Instance.GetAsync(ON_LAST_STARTUP_NOTIFICATION_RECORD_ID); - + static Task GetLastNotificationTime() => ISecureStorage.Instance.GetAsync(ON_LAST_STARTUP_NOTIFICATION_RECORD_ID); + static Task SetLastNotificationTime(DateTimeOffset time) => ISecureStorage.Instance.SetAsync(ON_LAST_STARTUP_NOTIFICATION_RECORD_ID,time); /// /// NotifyIcon / TrayIcon 右下角托盘菜单助手类 /// diff --git a/src/ST.Client/Services/Mvvm/NotificationService.cs b/src/ST.Client/Services/Mvvm/NotificationService.cs index 848ab5e55..4da409a12 100644 --- a/src/ST.Client/Services/Mvvm/NotificationService.cs +++ b/src/ST.Client/Services/Mvvm/NotificationService.cs @@ -15,6 +15,7 @@ using System.Net; using System.Net.Sockets; using System.Properties; using System.Reactive.Linq; +using System.Security; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -54,9 +55,53 @@ namespace System.Application.Services get => _SelectGroup; set => this.RaiseAndSetIfChanged(ref _SelectGroup, value); } - public async Task InitializeNotice() + public async Task GetNews(int trycount = 0) + { + if (NoticeTypes.Count > 0) + { + var lastTime = await INotificationService.GetLastNotificationTime(); + var basics = NoticeTypes.Items.FirstOrDefault(); + var client = ICloudServiceClient.Instance.Notice; + var result = await client.NewMsg(basics.Id, null); + if (result.IsSuccess && result.Content != null) + { + var noticeList = result.Content.Where(x => lastTime.HasValue ? x.EnableTime > lastTime : true); + if (noticeList.Count() > 1) + { + await INotificationService.SetLastNotificationTime(noticeList.Max(x => x.EnableTime)); + INotificationService.Instance.Notify(new NotificationBuilder() + { + Title = AppResources.NotificationChannelType_Description_Announcement, + Content = AppResources.Notice_Tray.Format(result.Content.Length, basics.Name), + AutoCancel = NotificationBuilder.DefaultAutoCancel, + Type = NotificationType.Announcement, + Click = new NotificationBuilder.ClickAction(() => + { + IWindowManager.Instance.Show(CustomWindow.Notice); + }) + }); + } + else + { + var notice = noticeList.FirstOrDefault(); + if (notice != null && notice.EnableTime > lastTime) + { + await INotificationService.SetLastNotificationTime(notice.EnableTime); + INotificationService.Instance.Notify(notice); + } + + } + + } + } + else if (trycount <= 2) + { + await GetTypes(); + await GetNews(trycount++); + } + } + public async Task GetTypes() { - IsLoading = true; var client = ICloudServiceClient.Instance.Notice; var result = await client.Types(); if (result.IsSuccess) @@ -64,7 +109,21 @@ namespace System.Application.Services NoticeTypes.Clear(); NoticeTypes.AddRange(result.Content!.OrderBy(x => x.Index)); } - } + } + public async Task InitializeNotice() + { + using (var tk = CancellationTokenSource.CreateLinkedTokenSource(new CancellationToken())) + { + new Task(() => + { + Thread.Sleep(500); + if (!tk.IsCancellationRequested) + IsLoading = true; + }, tk.Token).Start(); + await GetTypes(); + tk.Cancel(); + } + } public async Task GetTable(NoticeTypeDTO selectGroup) { if (selectGroup != null) @@ -94,9 +153,19 @@ namespace System.Application.Services { if (x != null) { - IsLoading = true; - await GetTable(x); - IsLoading = false; + //延迟500ms显示加载 + using (var tk = CancellationTokenSource.CreateLinkedTokenSource(new CancellationToken())) + { + new Task(() => + { + Thread.Sleep(500); + if (!tk.IsCancellationRequested) + IsLoading = true; + }, tk.Token).Start(); + await GetTable(x); + tk.Cancel(); + IsLoading = false; + } } }); NoticeTypes diff --git a/src/ST.Client/UI/Resx/AppResources.Designer.cs b/src/ST.Client/UI/Resx/AppResources.Designer.cs index 0ae726983..6e450ad6f 100644 --- a/src/ST.Client/UI/Resx/AppResources.Designer.cs +++ b/src/ST.Client/UI/Resx/AppResources.Designer.cs @@ -3870,6 +3870,15 @@ namespace System.Application.UI.Resx { } } + /// + /// 查找类似 当前有 {0} 条{1}通知,详情请在程序内通知公告处查看。 的本地化字符串。 + /// + public static string Notice_Tray { + get { + return ResourceManager.GetString("Notice_Tray", resourceCulture); + } + } + /// /// 查找类似 当有新公告时的提示通知。 的本地化字符串。 /// diff --git a/src/ST.Client/UI/Resx/AppResources.resx b/src/ST.Client/UI/Resx/AppResources.resx index 2664361e2..a281f73d9 100644 --- a/src/ST.Client/UI/Resx/AppResources.resx +++ b/src/ST.Client/UI/Resx/AppResources.resx @@ -2251,4 +2251,7 @@ AAAAA-BBBBB-CCCC3 请正确选择一张要应用的图片 + + 当前有 {0} 条{1}通知,详情请在程序内通知公告处查看。 + \ No newline at end of file diff --git a/src/ST.Services.CloudService.Models/Models/Notice/NoticeDTO.NotificationBuilder.cs b/src/ST.Services.CloudService.Models/Models/Notice/NoticeDTO.NotificationBuilder.cs index 85b16c3b2..945af6bc6 100644 --- a/src/ST.Services.CloudService.Models/Models/Notice/NoticeDTO.NotificationBuilder.cs +++ b/src/ST.Services.CloudService.Models/Models/Notice/NoticeDTO.NotificationBuilder.cs @@ -8,7 +8,7 @@ namespace System.Application.Models string NotificationBuilder.IInterface.Content => Introduction; - NotificationType NotificationBuilder.IInterface.Type => throw new NotImplementedException(); + NotificationType NotificationBuilder.IInterface.Type => Type; bool NotificationBuilder.IInterface.AutoCancel => NotificationBuilder.DefaultAutoCancel; @@ -22,7 +22,7 @@ namespace System.Application.Models Entrance NotificationBuilder.ClickAction.IInterface.Entrance => IsOpenBrowser ? Entrance.Browser : Entrance.Main; - string? NotificationBuilder.ClickAction.IInterface.RequestUri => string.Format(Constants.Urls.OfficialWebsite_Notice, Id); + string? NotificationBuilder.ClickAction.IInterface.RequestUri =>Url; Action? NotificationBuilder.ClickAction.IInterface.Action => null; } diff --git a/src/ST.Services.CloudService.Models/Models/Notice/NoticeDTO.cs b/src/ST.Services.CloudService.Models/Models/Notice/NoticeDTO.cs index 31fddeae5..946160eb8 100644 --- a/src/ST.Services.CloudService.Models/Models/Notice/NoticeDTO.cs +++ b/src/ST.Services.CloudService.Models/Models/Notice/NoticeDTO.cs @@ -23,7 +23,9 @@ namespace System.Application.Models [MPKey(0)] [N_JsonProperty("0")] [S_JsonProperty("0")] - public Guid Id { get; set; } + public Guid Id { get; set; } + + [MPKey(1)] [N_JsonProperty("1")] @@ -66,7 +68,7 @@ namespace System.Application.Models public string Author { get; set; } = string.Empty; /// - /// 标题 + /// 简介 /// [MPKey(5)] [N_JsonProperty("5")] @@ -106,12 +108,27 @@ namespace System.Application.Models public DateTimeOffset OverdueTime { get; set; } #if MVVM_VM /// - /// 当前组中所有的加速项目集合 + /// 是否过期 /// [MPIgnore] [N_JsonIgnore] [S_JsonIgnore] public bool Overdue => DateTimeOffset.Now > OverdueTime; #endif + /// + /// 通知渠道 + /// + [MPKey(10)] + [N_JsonProperty("10")] + [S_JsonProperty("10")] + public NotificationType Type { get; set; } = NotificationType.Announcement; + + /// + /// Url + /// + [MPKey(11)] + [N_JsonProperty("11")] + [S_JsonProperty("11")] + public string Url { get; set; } = string.Empty; } } diff --git a/src/ST.Services.CloudService/Services/CloudService/Clients/Abstractions/IActiveUserClient.cs b/src/ST.Services.CloudService/Services/CloudService/Clients/Abstractions/IActiveUserClient.cs index ad59c69a9..698d80a3c 100644 --- a/src/ST.Services.CloudService/Services/CloudService/Clients/Abstractions/IActiveUserClient.cs +++ b/src/ST.Services.CloudService/Services/CloudService/Clients/Abstractions/IActiveUserClient.cs @@ -1,4 +1,4 @@ -using System.Application.Models; +using System.Application.Models; using System.Threading.Tasks; namespace System.Application.Services.CloudService.Clients.Abstractions @@ -14,8 +14,6 @@ namespace System.Application.Services.CloudService.Clients.Abstractions /// 匿名收集数据 /// 最后一次收到的通知ID /// - Task> Post( - ActiveUserRecordDTO request, - Guid? lastNotificationRecordId); + Task Post(ActiveUserRecordDTO request); } } \ No newline at end of file diff --git a/src/ST.Services.CloudService/Services/CloudService/Clients/ActiveUserClient.cs b/src/ST.Services.CloudService/Services/CloudService/Clients/ActiveUserClient.cs index 581e03295..fd6c48cef 100644 --- a/src/ST.Services.CloudService/Services/CloudService/Clients/ActiveUserClient.cs +++ b/src/ST.Services.CloudService/Services/CloudService/Clients/ActiveUserClient.cs @@ -1,4 +1,4 @@ -using System.Application.Models; +using System.Application.Models; using System.Application.Services.CloudService.Clients.Abstractions; using System.Net.Http; using System.Threading.Tasks; @@ -11,16 +11,13 @@ namespace System.Application.Services.CloudService.Clients { } - public Task> Post( - ActiveUserRecordDTO request, - Guid? lastNotificationRecordId) - => conn.SendAsync( + public Task Post(ActiveUserRecordDTO request) + => conn.SendAsync( isAnonymous: true, // 仅匿名收集 isSecurity: true, method: HttpMethod.Post, - requestUri: $"api/ActiveUser/{lastNotificationRecordId}", + requestUri: $"api/ActiveUser/", request: request, - responseContentMaybeNull: true, cancellationToken: default); } } \ No newline at end of file diff --git a/src/ST.Services.CloudService/Services/CloudService/MockCloudServiceClient.cs b/src/ST.Services.CloudService/Services/CloudService/MockCloudServiceClient.cs index 960523cef..37de86465 100644 --- a/src/ST.Services.CloudService/Services/CloudService/MockCloudServiceClient.cs +++ b/src/ST.Services.CloudService/Services/CloudService/MockCloudServiceClient.cs @@ -191,9 +191,9 @@ namespace System.Application.Services.CloudService } } - public Task> Post(ActiveUserRecordDTO record, Guid? lastNotificationRecordId) + public Task Post(ActiveUserRecordDTO record) { - return Task.FromResult(ApiResponse.Ok(null)); + return Task.FromResult(ApiResponse.Ok()); } public Task> RefreshToken(string refresh_token) diff --git a/src/Startup2.cs b/src/Startup2.cs index f9f4c523b..3dad942b3 100644 --- a/src/Startup2.cs +++ b/src/Startup2.cs @@ -516,16 +516,11 @@ namespace System.Application SumScreenHeight = screens.All.Sum(x => x.Bounds.Height), #endif IsAuthenticated = isAuthenticated, - }; - Guid? lastNotificationRecordId = default; - if (type == ActiveUserType.OnStartup) - { - lastNotificationRecordId = await INotificationService.GetLastNotificationRecordId(); - } + }; req.SetDeviceId(); // 匿名统计与通知公告 - var rsp = await csc.ActiveUser.Post(req, lastNotificationRecordId); - INotificationService.Notify(rsp, type); + await csc.ActiveUser.Post(req); + INotificationService.Notify(type); } catch (Exception e) {