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;
}
///
/// 公告类型
///
public enum E_NoticeType
{
None = 0,
///
/// 系统
///
System = 1,
///
/// 活动
///
Activity = 2,
///
/// 通行证
///
BattlePass = 3,
}
public class NoticeManager : Singlenton, IInitable
{
private const string NoticePost = "notices";
private const int NoticeRedNod = 100;
///
/// 公告请求结果
///
private class NoticeGetResult
{
public int code;
public string message;
public List data;
}
///
/// link_type: 1-内链, 2-外链(需点击跳转链接后红点才消失)
/// is_swiper: 1-需轮播, 2-否
///
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;
}
///
/// 真是公告数据
///
private List curNoticeData;
///
/// 公告数据 UI
///
private Dictionary activityNoticeDataForDisplays;
///
/// 系统公告数据 UI
///
private Dictionary systemNoticeDataForDisplays;
///
/// 轮播公告数据 UI
///
private List rotateNoticeDataForDisplays;
///
/// 公告红点缓存数据
///
private NoticeRedStorage noticeRedStorage;
///
/// 公告页签红点字典
///
private Dictionary redPointNodeNoticeTypes;
public Dictionary ActivityNoticeDataForDisplays => activityNoticeDataForDisplays;
public Dictionary SystemNoticeDataForDisplays => systemNoticeDataForDisplays;
public List RotateNoticeDataForDisplays => rotateNoticeDataForDisplays;
public Dictionary RedPointNodeNoticeTypes => redPointNodeNoticeTypes;
public async void GetNotice()
{
var requestUrl = AppConfig.Instance.LoginURL + NoticePost;
DebugUtil.Log("拉起公告请求地址: " + requestUrl);
try
{
var headData = PostHeader.PostHeaderInfo(new Dictionary
{
{ "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(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(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.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 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();
systemNoticeDataForDisplays = new Dictionary();
rotateNoticeDataForDisplays = new List();
redPointNodeNoticeTypes = new Dictionary();
noticeRedStorage = StorageMgr.Instance.GetStorage(Constants.Storage.NoticeRed);
noticeRedStorage ??= new NoticeRedStorage();
// 公告类型红点
var systemParam = new ValueTuple(NoticeRedType.NoticeType, (int)E_NoticeType.System);
var systemNode =
RedPointManager.Instance.AddDynamicNode(NodeType.Notice, NoticeRedNod, systemParam) as RedPointNodeNotice;
var activityParam = new ValueTuple(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
}