NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Notice/NoticeManager.cs

364 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using PhxhSDK;
using Framework;
using UnityEngine;
using System.Linq;
using Gameplay.Net;
using cfg.RedPoint;
using Newtonsoft.Json;
using UnityEngine.Networking;
using Cysharp.Threading.Tasks;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Constants = Framework.Constants;
public class NoticeDataForDisplay
{
public int ID;
public string Title;
public E_NoticeType Type;
public int LinkType;
public Sprite Bannersprite;
public Sprite ContentSprite;
public string Content;
public bool Rotate;
public string UpdateTime;
public RedPointNodeNotice RedPointNodeNotice;
}
/// <summary>
/// 公告类型
/// </summary>
public enum E_NoticeType
{
None = 0,
/// <summary>
/// 系统
/// </summary>
System = 1,
/// <summary>
/// 活动
/// </summary>
Activity = 2,
/// <summary>
/// 通行证
/// </summary>
BattlePass = 3,
}
public class NoticeManager : Singlenton<NoticeManager>, IInitable
{
private const string NoticePost = "notices";
private const int NoticeRedNod = 100;
/// <summary>
/// 公告请求结果
/// </summary>
private class NoticeGetResult
{
public int code;
public string message;
public List<NoticeData> data;
}
/// <summary>
/// link_type: 1-内链, 2-外链(需点击跳转链接后红点才消失)
/// is_swiper: 1-需轮播, 2-否
/// </summary>
private class NoticeData
{
public int id;
public string title;
public int type;
public int link_type;
public int is_swiper;
public string url;
public string cover;
public string content;
public int application_id;
public string created_at;
public string update_at;
}
/// <summary>
/// 真是公告数据
/// </summary>
private List<NoticeData> curNoticeData;
/// <summary>
/// 公告数据 UI
/// </summary>
private Dictionary<int, NoticeDataForDisplay> activityNoticeDataForDisplays;
/// <summary>
/// 系统公告数据 UI
/// </summary>
private Dictionary<int, NoticeDataForDisplay> systemNoticeDataForDisplays;
/// <summary>
/// 轮播公告数据 UI
/// </summary>
private List<NoticeDataForDisplay> rotateNoticeDataForDisplays;
/// <summary>
/// 公告红点缓存数据
/// </summary>
private NoticeRedStorage noticeRedStorage;
/// <summary>
/// 公告页签红点字典
/// </summary>
private Dictionary<E_NoticeType, RedPointNodeNotice> redPointNodeNoticeTypes;
public Dictionary<int, NoticeDataForDisplay> ActivityNoticeDataForDisplays => activityNoticeDataForDisplays;
public Dictionary<int, NoticeDataForDisplay> SystemNoticeDataForDisplays => systemNoticeDataForDisplays;
public List<NoticeDataForDisplay> RotateNoticeDataForDisplays => rotateNoticeDataForDisplays;
public Dictionary<E_NoticeType, RedPointNodeNotice> RedPointNodeNoticeTypes => redPointNodeNoticeTypes;
public async void GetNotice()
{
var requestUrl = AppConfig.Instance.LoginURL + NoticePost;
DebugUtil.Log("拉起公告请求地址: " + requestUrl);
try
{
var headData = PostHeader.PostHeaderInfo(new Dictionary<string, string>
{
{ "timestamp", DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString() }
});
var request = new UnityWebRequest(requestUrl, UnityWebRequest.kHttpVerbGET)
{
downloadHandler = new DownloadHandlerBuffer(),
};
request.SetRequestHeader("Content-Type", "application/json;charset=utf-8"); //为了保证客户端发送的json格式在后端能解析
request.SetRequestHeader("signature", headData["signature"]);
request.SetRequestHeader("timestamp", headData["timestamp"]);
request.SetRequestHeader("accessKey", headData["accessKey"]);
// 异步等待请求完成
await request.SendWebRequest();
if (request.result != UnityWebRequest.Result.Success)
{
DebugUtil.LogError(request.downloadHandler.text);
}
else
{
Debug.Log("http消息请求成功返回内容\n" + request.downloadHandler.text);
var result = JsonConvert.DeserializeObject<NoticeGetResult>(request.downloadHandler.text);
if (result.code == 0)
{
curNoticeData = result.data;
ConvertNotice();
}
else
{
DebugUtil.LogError("获取公告失败");
}
}
}
catch (UnityWebRequestException e)
{
DebugUtil.LogError(e);
var pattern = @"\{.*\}";
var match = Regex.Match(e.Message, pattern);
if (match.Success)
{
var json = match.Value;
NoticeGetResult res = JsonConvert.DeserializeObject<NoticeGetResult>(json);
DebugUtil.LogError("请求失败, 服务器有错误响应: " + res.message);
}
else
{
DebugUtil.LogError("请求失败!");
}
}
}
private async void ConvertNotice()
{
var activityIndex = 0;
var systemIndex = 0;
foreach (var data in curNoticeData)
{
Debug.Log($"公告ID:{data.id}, Title:{data.title}");
Debug.Log($"公告内容:{data.content}");
var sprite = await DownLoadImg(data.cover);
var noticeDataForDisplay = new NoticeDataForDisplay
{
ID = data.id,
Content = data.content,
Bannersprite = sprite,
ContentSprite = sprite,
Title = data.title,
LinkType = data.link_type,
UpdateTime = data.update_at,
};
noticeDataForDisplay.Type = (E_NoticeType)data.type;
// 红点
var param = new ValueTuple<NoticeRedType, int>(NoticeRedType.Notice, data.id);
noticeDataForDisplay.RedPointNodeNotice =
RedPointManager.Instance.AddDynamicNode(NodeType.Notice, NoticeRedNod, param) as RedPointNodeNotice;
if (data.type == 1)
{
systemNoticeDataForDisplays[systemIndex] = noticeDataForDisplay;
systemIndex++;
}
else
{
activityNoticeDataForDisplays[activityIndex] = noticeDataForDisplay;
activityIndex++;
}
if (data.is_swiper == 1)
rotateNoticeDataForDisplays.Add(noticeDataForDisplay);
}
SortRotateNotice();
EventManager.Instance.Send(EventManager.EventName.RefreshNotice);
}
private async UniTask<Sprite> DownLoadImg(string url)
{
if (string.IsNullOrEmpty(url)) return null;
Sprite sprite = null;
try
{
using var request = UnityWebRequestTexture.GetTexture(url);
var operation = request.SendWebRequest();
await operation.ToUniTask();
if (request.result == UnityWebRequest.Result.Success)
{
var texture = DownloadHandlerTexture.GetContent(request);
if (texture != null)
{
sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height),
new Vector2(0.5f, 0.5f));
}
}
else
{
Debug.LogError($"公告图片下载失败: {request.error}");
}
return sprite;
}
catch (Exception e)
{
DebugUtil.LogError("NoticeManager.DownLoadImg error: {0}", e);
return sprite;
}
}
private void SortRotateNotice()
{
// 如果解析失败,返回一个最小值,这样无效时间会排在最后
rotateNoticeDataForDisplays = rotateNoticeDataForDisplays
.OrderByDescending(notice => DateTime.TryParse(notice.UpdateTime, out var time) ? time : DateTime.MinValue)
.ToList();
}
#region 红点
public bool GetNoticeTypeRedNode(int type)
{
switch (type)
{
case 1:
{
foreach (var notice in systemNoticeDataForDisplays.Values)
{
if (noticeRedStorage.CheckNotice(notice.ID))
return true;
}
break;
}
case 2:
{
foreach (var notice in activityNoticeDataForDisplays.Values)
{
if (noticeRedStorage.CheckNotice(notice.ID))
return true;
}
break;
}
}
return false;
}
public bool GetNoticeRedNode(int id)
{
return noticeRedStorage.CheckNotice(id);
}
public void CloseRedNode(int id)
{
if (!noticeRedStorage.NoticeList.Contains(id))
noticeRedStorage.NoticeList.Add(id);
StorageMgr.Instance.SyncForce = true;
EventManager.Instance.Send(EventManager.EventName.RefreshNotice);
}
#endregion
#region 初始化与释放
public void Init()
{
activityNoticeDataForDisplays = new Dictionary<int, NoticeDataForDisplay>();
systemNoticeDataForDisplays = new Dictionary<int, NoticeDataForDisplay>();
rotateNoticeDataForDisplays = new List<NoticeDataForDisplay>();
redPointNodeNoticeTypes = new Dictionary<E_NoticeType, RedPointNodeNotice>();
noticeRedStorage = StorageMgr.Instance.GetStorage<NoticeRedStorage>(Constants.Storage.NoticeRed);
noticeRedStorage ??= new NoticeRedStorage();
// 公告类型红点
var systemParam = new ValueTuple<NoticeRedType, int>(NoticeRedType.NoticeType, (int)E_NoticeType.System);
var systemNode =
RedPointManager.Instance.AddDynamicNode(NodeType.Notice, NoticeRedNod, systemParam) as RedPointNodeNotice;
var activityParam = new ValueTuple<NoticeRedType, int>(NoticeRedType.NoticeType, (int)E_NoticeType.Activity);
var activityNode =
RedPointManager.Instance.AddDynamicNode(NodeType.Notice, NoticeRedNod, activityParam) as RedPointNodeNotice;
redPointNodeNoticeTypes.Add(E_NoticeType.System, systemNode);
redPointNodeNoticeTypes.Add(E_NoticeType.Activity, activityNode);
}
public void Release()
{
foreach (var noticeData in activityNoticeDataForDisplays)
{
noticeData.Value.ContentSprite = null;
noticeData.Value.Bannersprite = null;
}
foreach (var noticeData in activityNoticeDataForDisplays)
{
noticeData.Value.ContentSprite = null;
noticeData.Value.Bannersprite = null;
}
foreach (var redPointNodeNotice in redPointNodeNoticeTypes)
{
if (redPointNodeNotice.Value != null)
RedPointManager.Instance.RemoveDynamicNode(redPointNodeNotice.Value);
}
activityNoticeDataForDisplays = null;
systemNoticeDataForDisplays = null;
}
#endregion
}