From e19bcaa7ced9d17f7dae4672ae0c41710e178a60 Mon Sep 17 00:00:00 2001
From: lcy <1459594991@qq.com>
Date: 星期四, 09 十月 2025 09:53:15 +0800
Subject: [PATCH] 218 子 【付费内容】首充 / 【付费内容】首充-客户端

---
 Main/Config/Configs/FirstChargeConfig.cs.meta                                                     |    2 
 Main/System/FirstCharge/FirstChargeWin.cs.meta                                                    |    2 
 Main/Config/ConfigManager.cs                                                                      |    3 
 Main/System/FirstCharge/FirstChargeHeroInfoWin.cs                                                 |   75 ++
 Main/Config/PartialConfigs/FirstChargeConfig.cs.meta                                              |    2 
 Main/System/FirstCharge/FirstChargeDayAward.cs                                                    |  224 +++++++
 Main/System/Redpoint/MainRedDot.cs                                                                |    2 
 Main/Component/UI/Common/PopupWindowsProcessor.cs                                                 |  161 +++++
 Main/System/Equip/EquipTipWin.cs                                                                  |  112 +++
 Main/System/FirstCharge/FirstChargeManager.cs.meta                                                |    2 
 Main/System/FirstCharge/FirstChargeWin.cs                                                         |  308 ++++++++++
 Main/Config/PartialConfigs/FirstChargeConfig.cs                                                   |   23 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagSCFirstChargeInfo.cs      |   13 
 Main/System/Main/HomeWin.cs                                                                       |   54 +
 Main/Main.cs                                                                                      |    1 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA02_tagSCFirstChargeInfo.cs                |   31 +
 Main/System/FirstCharge.meta                                                                      |    8 
 Main/System/FirstCharge/FirstChargeHeroInfoWin.cs.meta                                            |    2 
 Main/System/FirstCharge/FirstChargeManager.cs                                                     |  522 +++++++++++++++++
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA02_tagSCFirstChargeInfo.cs.meta           |    2 
 Main/Component/UI/Common/PopupWindowsProcessor.cs.meta                                            |    2 
 Main/Config/Configs/FirstChargeConfig.cs                                                          |   56 +
 Main/Config/Configs/AppointItemConfig.cs                                                          |   50 +
 Main/System/ItemTip/ItemTipUtility.cs                                                             |   75 +-
 /dev/null                                                                                         |   13 
 Main/System/Recharge/RechargeManager.cs                                                           |   14 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagSCFirstChargeInfo.cs.meta |    2 
 Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs                                              |    2 
 Main/System/FirstCharge/FirstChargeDayAward.cs.meta                                               |    2 
 29 files changed, 1,687 insertions(+), 78 deletions(-)

diff --git a/Main/Component/UI/Common/PopupWindowsProcessor.cs b/Main/Component/UI/Common/PopupWindowsProcessor.cs
new file mode 100644
index 0000000..32e8c29
--- /dev/null
+++ b/Main/Component/UI/Common/PopupWindowsProcessor.cs
@@ -0,0 +1,161 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+/// <summary>
+/// 寮圭獥澶勭悊鍣� - 璐熻矗绠$悊娓告垙涓殑寮圭獥闃熷垪锛屾寜椤哄簭鏄剧ず寮圭獥绐楀彛
+/// 閬垮厤澶氫釜绐楀彛鍚屾椂寮瑰嚭閫犳垚鐣岄潰娣蜂贡
+/// </summary>
+public class PopupWindowsProcessor : SingletonMonobehaviour<PopupWindowsProcessor>
+{
+    // 寮圭獥闃熷垪锛屽瓨鍌ㄥ緟澶勭悊鐨勫脊绐楄姹�
+    List<PopupWindow> popupWindowQueue = new List<PopupWindow>();
+    
+    // 褰撳墠姝e湪鏄剧ず鐨勫脊绐�
+    PopupWindow currentWindow;
+
+    // 涓婃寮圭獥鏃堕棿锛岀敤浜庢帶鍒跺脊绐椾箣闂寸殑闂撮殧
+    float lastTime = 0; //涓婃寮圭獥鏃堕棿
+    
+    /// <summary>
+    /// 娣诲姞涓�涓脊绐楀埌澶勭悊闃熷垪
+    /// </summary>
+    /// <param name="name">绐楀彛鍚嶇О</param>
+    /// <param name="functionId">鍔熻兘ID锛岀敤浜庢寚瀹氱獥鍙g殑鍏蜂綋鍔熻兘鎴栨樉绀烘ā寮�</param>
+    public void Add(string name, int functionId = 0)
+    {
+        var popupWindow = new PopupWindow()
+        {
+            window = name,
+            functionId = functionId,
+        };
+
+        if (popupWindowQueue.Contains(popupWindow))
+        {
+            popupWindowQueue.Remove(popupWindow);
+        }
+
+        popupWindowQueue.Add(popupWindow);
+    }
+
+    /// <summary>
+    /// 浠庡鐞嗛槦鍒椾腑绉婚櫎鎸囧畾鐨勫脊绐�
+    /// </summary>
+    /// <param name="name">绐楀彛鍚嶇О</param>
+    /// <param name="functionId">鍔熻兘ID</param>
+    public void Remove(string name, int functionId = 0)
+    {
+        var popupWindow = new PopupWindow()
+        {
+            window = name,
+            functionId = functionId,
+        };
+
+        if (popupWindowQueue.Contains(popupWindow))
+        {
+            popupWindowQueue.Remove(popupWindow);
+        }
+    }
+
+    /// <summary>
+    /// LateUpdate涓鐞嗗脊绐楅槦鍒楋紝纭繚鍦ㄦ墍鏈夊叾浠栭�昏緫澶勭悊瀹屾瘯鍚庢墠鏄剧ず寮圭獥
+    /// </summary>
+    private void LateUpdate()
+    {
+        //鎵撳紑绐楀彛闇�瑕佹椂闂达紝涓嶇劧浼氬鑷撮槦鍒椾腑鐨勭獥鍙e叏閮ㄥ悓鏃舵墦寮�
+        if (Time.realtimeSinceStartup - lastTime < 1)
+            return;
+
+        // 妫�鏌ョ帺瀹舵槸鍚﹀畬鎴愮櫥褰曞姞杞�
+        if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin)
+            return;
+
+        // 妫�鏌ユ槸鍚﹁繘鍏ユ父鎴忎富鍦烘櫙
+        if (StageManager.Instance.currentStage != StageName.Game)
+        {
+            return;
+        }
+
+        // 妫�鏌ユ槸鍚﹀湪鏂版墜寮曞涓�
+        // 娉ㄦ剰锛歂ewBieCenter鍦ㄥ綋鍓嶄唬鐮佸簱涓笉瀛樺湪锛屾殏鏃舵敞閲婃帀鐩稿叧妫�鏌�
+        // if (NewBieCenter.Instance.inGuiding)
+        // {
+        //     return;
+        // }
+
+        if (popupWindowQueue.Count == 0)
+        {
+            return;
+        }
+
+        // 妫�鏌ユ槸鍚︽鍦ㄦ樉绀篖oading绐楀彛
+        if (UIManager.Instance.IsOpened<LoadingWin>())
+            return;
+
+        // 妫�鏌ユ槸鍚﹀瓨鍦ㄥ叏灞忔垨閬僵绐楀彛
+        // 娉ㄦ剰锛欵xistAnyFullScreenOrMaskWin鏂规硶鍦ㄥ綋鍓峌IManager涓笉瀛樺湪锛屾殏鏃舵敞閲婃帀鐩稿叧妫�鏌�
+        // if (UIManager.Instance.ExistAnyFullScreenOrMaskWin())
+        //     return;
+
+        if (currentWindow.window != null)
+        {
+            //鍒ゆ柇涓婁竴涓帹閫佹槸鍚﹀叧闂�
+            UIBase ui = UIManager.Instance.GetUI(currentWindow.window);
+            if (ui != null && ui.IsActive())
+                return;
+
+            currentWindow = popupWindowQueue[0];
+            popupWindowQueue.RemoveAt(0);
+            UIManager.Instance.OpenWindow(currentWindow.window, currentWindow.functionId);
+            Debug.LogFormat("鎺ㄩ�佺獥鍙� " + currentWindow.window);
+        }
+        else
+        {
+            currentWindow = popupWindowQueue[0];
+            popupWindowQueue.RemoveAt(0);
+            UIManager.Instance.OpenWindow(currentWindow.window, currentWindow.functionId);
+            Debug.LogFormat("鎺ㄩ�佺獥鍙� " + currentWindow.window);
+        }
+        lastTime = Time.realtimeSinceStartup;
+    }
+
+    /// <summary>
+    /// 寮圭獥缁撴瀯浣擄紝鐢ㄤ簬琛ㄧず涓�涓緟澶勭悊鐨勫脊绐楄姹�
+    /// 鍖呭惈绐楀彛鍚嶇О鍜屽姛鑳絀D锛岄�氳繃杩欎袱涓瓧娈靛彲浠ュ敮涓�鏍囪瘑涓�涓脊绐楄姹�
+    /// </summary>
+    public struct PopupWindow
+    {
+        // 绐楀彛鍚嶇О
+        public string window;
+        
+        // 鍔熻兘ID锛岀敤浜庢寚瀹氱獥鍙g殑鍏蜂綋鍔熻兘鎴栨樉绀烘ā寮�
+        public int functionId;
+
+        public static bool operator ==(PopupWindow lhs, PopupWindow rhs)
+        {
+            return lhs.window == rhs.window && lhs.functionId == rhs.functionId;
+        }
+
+        public static bool operator !=(PopupWindow lhs, PopupWindow rhs)
+        {
+            return lhs.window != rhs.window || lhs.functionId != rhs.functionId;
+        }
+
+        // 娣诲姞GetHashCode鍜孍quals鏂规硶浠ョ‘淇濈粨鏋勪綋鍙互姝g‘姣旇緝
+        public override bool Equals(object obj)
+        {
+            if (obj is PopupWindow)
+            {
+                PopupWindow other = (PopupWindow)obj;
+                return this.window == other.window && this.functionId == other.functionId;
+            }
+            return false;
+        }
+
+        public override int GetHashCode()
+        {
+            return window.GetHashCode() ^ functionId.GetHashCode();
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta b/Main/Component/UI/Common/PopupWindowsProcessor.cs.meta
similarity index 83%
copy from Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
copy to Main/Component/UI/Common/PopupWindowsProcessor.cs.meta
index 6477a20..0e995d7 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
+++ b/Main/Component/UI/Common/PopupWindowsProcessor.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 56da7e3109f052e46860b1ed27323ab4
+guid: 63a256d5f4c621d4c9d01ad4d1771d13
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/Config/ConfigManager.cs b/Main/Config/ConfigManager.cs
index 26bfb54..96b0275 100644
--- a/Main/Config/ConfigManager.cs
+++ b/Main/Config/ConfigManager.cs
@@ -44,6 +44,7 @@
             typeof(DirtyWordConfig),
             typeof(FaceConfig),
             typeof(FightPowerRatioConfig),
+            typeof(FirstChargeConfig),
             typeof(GoldRushCampConfig),
             typeof(GoldRushItemConfig),
             typeof(GoldRushWorkerConfig),
@@ -229,6 +230,8 @@
         ClearConfigDictionary<FaceConfig>();
         // 娓呯┖ FightPowerRatioConfig 瀛楀吀
         ClearConfigDictionary<FightPowerRatioConfig>();
+        // 娓呯┖ FirstChargeConfig 瀛楀吀
+        ClearConfigDictionary<FirstChargeConfig>();
         // 娓呯┖ GoldRushCampConfig 瀛楀吀
         ClearConfigDictionary<GoldRushCampConfig>();
         // 娓呯┖ GoldRushItemConfig 瀛楀吀
diff --git a/Main/Config/Configs/AppointItemConfig.cs b/Main/Config/Configs/AppointItemConfig.cs
index 9457147..8bb7150 100644
--- a/Main/Config/Configs/AppointItemConfig.cs
+++ b/Main/Config/Configs/AppointItemConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           2025骞�8鏈�5鏃�
+//    [  Date ]:           Tuesday, October 7, 2025
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -17,6 +17,10 @@
     }
 
     public int ID;
+	public int CancelUseLimit;
+	public int ItemLV;
+	public int[] BaseAttrID;
+	public int[] BaseAttrValue;
 	public int[] LegendAttrID;
 	public int[] LegendAttrValue;
 
@@ -32,13 +36,45 @@
         string[] tables = input.Split('\t');
         int.TryParse(tables[0],out ID); 
 
-			if (tables[1].Contains("["))
+			int.TryParse(tables[1],out CancelUseLimit); 
+
+			int.TryParse(tables[2],out ItemLV); 
+
+			if (tables[3].Contains("["))
 			{
-				LegendAttrID = JsonMapper.ToObject<int[]>(tables[1]);
+				BaseAttrID = JsonMapper.ToObject<int[]>(tables[3]);
 			}
 			else
 			{
-				string[] LegendAttrIDStringArray = tables[1].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				string[] BaseAttrIDStringArray = tables[3].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				BaseAttrID = new int[BaseAttrIDStringArray.Length];
+				for (int i=0;i<BaseAttrIDStringArray.Length;i++)
+				{
+					 int.TryParse(BaseAttrIDStringArray[i],out BaseAttrID[i]);
+				}
+			}
+
+			if (tables[4].Contains("["))
+			{
+				BaseAttrValue = JsonMapper.ToObject<int[]>(tables[4]);
+			}
+			else
+			{
+				string[] BaseAttrValueStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				BaseAttrValue = new int[BaseAttrValueStringArray.Length];
+				for (int i=0;i<BaseAttrValueStringArray.Length;i++)
+				{
+					 int.TryParse(BaseAttrValueStringArray[i],out BaseAttrValue[i]);
+				}
+			}
+
+			if (tables[5].Contains("["))
+			{
+				LegendAttrID = JsonMapper.ToObject<int[]>(tables[5]);
+			}
+			else
+			{
+				string[] LegendAttrIDStringArray = tables[5].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
 				LegendAttrID = new int[LegendAttrIDStringArray.Length];
 				for (int i=0;i<LegendAttrIDStringArray.Length;i++)
 				{
@@ -46,13 +82,13 @@
 				}
 			}
 
-			if (tables[2].Contains("["))
+			if (tables[6].Contains("["))
 			{
-				LegendAttrValue = JsonMapper.ToObject<int[]>(tables[2]);
+				LegendAttrValue = JsonMapper.ToObject<int[]>(tables[6]);
 			}
 			else
 			{
-				string[] LegendAttrValueStringArray = tables[2].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				string[] LegendAttrValueStringArray = tables[6].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
 				LegendAttrValue = new int[LegendAttrValueStringArray.Length];
 				for (int i=0;i<LegendAttrValueStringArray.Length;i++)
 				{
diff --git a/Main/Config/Configs/FirstChargeConfig.cs b/Main/Config/Configs/FirstChargeConfig.cs
new file mode 100644
index 0000000..8836907
--- /dev/null
+++ b/Main/Config/Configs/FirstChargeConfig.cs
@@ -0,0 +1,56 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           Friday, October 3, 2025
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class FirstChargeConfig : ConfigBase<int, FirstChargeConfig>
+{
+    static FirstChargeConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int FirstID;
+	public int CTGID;
+	public int[][] AwardListDay1;
+	public int[][] AwardListDay2;
+	public int[][] AwardListDay3;
+	public int ExtraRewardTextType;
+	public string ExtraRewardTextInfo;
+
+    public override int LoadKey(string _key)
+    {
+        int key = GetKey(_key);
+        return key;
+    }
+
+    public override void LoadConfig(string input)
+    {
+        try {
+        string[] tables = input.Split('\t');
+        int.TryParse(tables[0],out FirstID); 
+
+			int.TryParse(tables[1],out CTGID); 
+
+			AwardListDay1 = JsonMapper.ToObject<int[][]>(tables[2].Replace("(", "[").Replace(")", "]")); 
+
+			AwardListDay2 = JsonMapper.ToObject<int[][]>(tables[3].Replace("(", "[").Replace(")", "]")); 
+
+			AwardListDay3 = JsonMapper.ToObject<int[][]>(tables[4].Replace("(", "[").Replace(")", "]")); 
+
+			int.TryParse(tables[5],out ExtraRewardTextType); 
+
+			ExtraRewardTextInfo = tables[6];
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta b/Main/Config/Configs/FirstChargeConfig.cs.meta
similarity index 83%
rename from Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
rename to Main/Config/Configs/FirstChargeConfig.cs.meta
index 6477a20..aadf863 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
+++ b/Main/Config/Configs/FirstChargeConfig.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 56da7e3109f052e46860b1ed27323ab4
+guid: e32927c96cf6d0240940a74853e29c60
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/Config/PartialConfigs/FirstChargeConfig.cs b/Main/Config/PartialConfigs/FirstChargeConfig.cs
new file mode 100644
index 0000000..9468bfa
--- /dev/null
+++ b/Main/Config/PartialConfigs/FirstChargeConfig.cs
@@ -0,0 +1,23 @@
+
+
+using System.Collections.Generic;
+using System.Linq;
+
+public partial class FirstChargeConfig : ConfigBase<int, FirstChargeConfig>
+{
+    private static Dictionary<int, int> ctgIdTofirstIdDict = new Dictionary<int, int>();
+    protected override void OnConfigParseCompleted()
+    {
+        ctgIdTofirstIdDict[CTGID] = FirstID;
+    }
+
+    public static List<int> GetCtgIDList()
+    {
+        return ctgIdTofirstIdDict.Keys.ToList();
+    }
+
+    public static bool TryGetFirstIdByCtgID(int ctgID, out int firstID)
+    {
+        return ctgIdTofirstIdDict.TryGetValue(ctgID, out firstID);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta b/Main/Config/PartialConfigs/FirstChargeConfig.cs.meta
similarity index 83%
copy from Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
copy to Main/Config/PartialConfigs/FirstChargeConfig.cs.meta
index 6477a20..9e68cb2 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
+++ b/Main/Config/PartialConfigs/FirstChargeConfig.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 56da7e3109f052e46860b1ed27323ab4
+guid: ca3bcf278fca3e84da1115d44c2a6067
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs
deleted file mode 100644
index 7ac6f48..0000000
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using UnityEngine;
-using System.Collections;
-
-// AA 02 棣栧厖淇℃伅 #tagMCFirstGoldInfo
-
-public class DTCAA02_tagMCFirstGoldInfo : DtcBasic {
-    public override void Done(GameNetPackBasic vNetPack)
-    {
-        base.Done(vNetPack);
-        HAA02_tagMCFirstGoldInfo vNetData = vNetPack as HAA02_tagMCFirstGoldInfo;
-        RechargeManager.Instance.UpdateFirstChargeReward(vNetData);
-    }
-}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagSCFirstChargeInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagSCFirstChargeInfo.cs
new file mode 100644
index 0000000..e048598
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagSCFirstChargeInfo.cs
@@ -0,0 +1,13 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 02 棣栧厖淇℃伅 #tagSCFirstChargeInfo
+
+public class DTCAA02_tagSCFirstChargeInfo : DtcBasic {
+    public override void Done(GameNetPackBasic vNetPack)
+    {
+        base.Done(vNetPack);
+        HAA02_tagSCFirstChargeInfo vNetData = vNetPack as HAA02_tagSCFirstChargeInfo;
+        FirstChargeManager.Instance.UpdateFirstChargeInfo(vNetData);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagSCFirstChargeInfo.cs.meta
similarity index 83%
copy from Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
copy to Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagSCFirstChargeInfo.cs.meta
index 6477a20..413e01b 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagSCFirstChargeInfo.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 56da7e3109f052e46860b1ed27323ab4
+guid: 3d6b7a163391b194397c23e92c7b5114
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs b/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
index 5c63f60..a853f2c 100644
--- a/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
+++ b/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
@@ -54,7 +54,7 @@
         Register(typeof(HA3A1_tagMCModuleFightPowerInfo), typeof(DTCA3A1_tagMCModuleFightPowerInfo));
         Register(typeof(HA110_tagMCCoinToGoldCountInfo), typeof(DTCA110_tagMCCoinToGoldCountInfo));
         Register(typeof(HA008_tagGCPlayerRecInfo), typeof(DTCA008_tagGCPlayerRecInfo));
-        Register(typeof(HAA02_tagMCFirstGoldInfo), typeof(DTCAA02_tagMCFirstGoldInfo));
+        Register(typeof(HAA02_tagSCFirstChargeInfo), typeof(DTCAA02_tagSCFirstChargeInfo));
         Register(typeof(HAA03_tagMCDailyPackBuyGiftInfo), typeof(DTCAA03_tagMCDailyPackBuyGiftInfo));
         Register(typeof(HA302_tagMCFuncOpenStateList), typeof(DTCA302_tagMCFuncOpenStateList));
         Register(typeof(HA320_tagMCPlayerFBInfoData), typeof(DTCA320_tagMCPlayerFBInfoData));
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA02_tagSCFirstChargeInfo.cs b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA02_tagSCFirstChargeInfo.cs
new file mode 100644
index 0000000..0566e10
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA02_tagSCFirstChargeInfo.cs
@@ -0,0 +1,31 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 02 棣栧厖淇℃伅 #tagSCFirstChargeInfo
+
+public class HAA02_tagSCFirstChargeInfo : GameNetPackBasic {
+    public byte Count;
+    public  tagSCFirstCharge[] FirstChargeList;
+
+    public HAA02_tagSCFirstChargeInfo () {
+        _cmd = (ushort)0xAA02;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out Count, vBytes, NetDataType.BYTE);
+        FirstChargeList = new tagSCFirstCharge[Count];
+        for (int i = 0; i < Count; i ++) {
+            FirstChargeList[i] = new tagSCFirstCharge();
+            TransBytes (out FirstChargeList[i].FirstID, vBytes, NetDataType.BYTE);
+            TransBytes (out FirstChargeList[i].ChargeTime, vBytes, NetDataType.DWORD);
+            TransBytes (out FirstChargeList[i].AwardRecord, vBytes, NetDataType.WORD);
+        }
+    }
+
+    public class tagSCFirstCharge {
+        public byte FirstID;        //棣栧厖ID
+        public uint ChargeTime;        //鍏呭�艰棣栧厖鐨勬椂闂存埑
+        public ushort AwardRecord;        //棣栧厖濂栧姳棰嗗璁板綍锛屾寜浜岃繘鍒朵綅璁板綍棣栧厖绗琗澶╂槸鍚﹀凡棰嗗彇
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA02_tagSCFirstChargeInfo.cs.meta
similarity index 83%
copy from Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
copy to Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA02_tagSCFirstChargeInfo.cs.meta
index 6477a20..ba99829 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA02_tagSCFirstChargeInfo.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 56da7e3109f052e46860b1ed27323ab4
+guid: 08d11e1da03650e48a3721f84f7b8d9f
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/Main.cs b/Main/Main.cs
index cfe5581..b25dd49 100644
--- a/Main/Main.cs
+++ b/Main/Main.cs
@@ -82,6 +82,7 @@
         managers.Add(BattleSettlementManager.Instance);
         managers.Add(GoldRushManager.Instance);
         managers.Add(MailManager.Instance);
+        managers.Add(FirstChargeManager.Instance);
         
         foreach (var manager in managers)
         {
diff --git a/Main/System/Equip/EquipTipWin.cs b/Main/System/Equip/EquipTipWin.cs
index 5c0f74a..e6826cb 100644
--- a/Main/System/Equip/EquipTipWin.cs
+++ b/Main/System/Equip/EquipTipWin.cs
@@ -1,5 +1,6 @@
 锘縰sing System;
 using System.Collections.Generic;
+using System.Linq;
 using Cysharp.Threading.Tasks;
 using UnityEngine;
 using UnityEngine.UI;
@@ -26,18 +27,46 @@
     [SerializeField] RectTransform bgRect;
 
     ItemModel equip;
+    ItemConfig customEquipItemConfig;
+    AppointItemConfig customEquipAppointItemConfig;
     protected override void OnPreOpen()
     {
-        equip = PackManager.Instance.GetItemByGuid(ItemTipUtility.mainTipData.guid);
-        Display(equip);
+        bool isShowCustomEquip = ItemTipUtility.isShowCustomEquip;
+        if (isShowCustomEquip)
+        {
+            int customEquipItemId = ItemTipUtility.customEquipItemId;
+            int customEquipAppointItemId = ItemTipUtility.customEquipAppointItemId;
+            if (!ItemConfig.HasKey(customEquipItemId))
+                return;
+            if (!AppointItemConfig.HasKey(customEquipAppointItemId))
+                return;
+            customEquipItemConfig = ItemConfig.Get(customEquipItemId);
+            customEquipAppointItemConfig = AppointItemConfig.Get(customEquipAppointItemId);
+            Display(customEquipItemConfig, customEquipAppointItemConfig);
+        }
+        else
+        {
+            equip = PackManager.Instance.GetItemByGuid(ItemTipUtility.mainTipData.guid);
+            Display(equip);
+        }
     }
 
     protected override void OnOpen()
     {
         //鍏堢缉灏忥紝杩欐牱涓嶄細鍥犱负闂撮殧甯т骇鐢熸槑鏄剧殑闂儊
         uieffect.transform.localScale = Vector3.zero;
-        //鐗规晥鏄剧ず渚濊禆rect鐨勬帓鐗堬紝鏀惧湪涓嬩竴甯�
-        RefreshEffect(equip).Forget();
+
+        bool isShowCustomEquip = ItemTipUtility.isShowCustomEquip;
+        if (isShowCustomEquip)
+        {
+            RefreshEffect(customEquipItemConfig).Forget();
+        }
+        else
+        {
+            //鐗规晥鏄剧ず渚濊禆rect鐨勬帓鐗堬紝鏀惧湪涓嬩竴甯�
+            RefreshEffect(equip).Forget();
+        }
+
     }
 
     protected override void OnPreClose()
@@ -101,9 +130,64 @@
 
     }
 
+    public void Display(ItemConfig itemConfig, AppointItemConfig appointItemConfig)
+    {
+
+        equipImage.SetOrgSprite(itemConfig.IconKey);
+        itemName.text = UIHelper.AppendColor(itemConfig.ItemColor, itemConfig.ItemName, true, 1);
+        itemNameOutline.OutlineColor = UIHelper.GetUIOutlineColor(itemConfig.ItemColor);
+        qualityName.text = UIHelper.GetQualityNameWithColor(itemConfig.ItemColor, Language.Get("equipQualityFormat"));
+        qualityNameOutline.OutlineColor = UIHelper.GetUIOutlineColor(itemConfig.ItemColor);
+        placeName.text = EquipModel.Instance.GetEquipPlaceName(itemConfig.EquipPlace);
+        lvText.text = Language.Get("EquipExchangeWin7", appointItemConfig.ItemLV);
+        bgFlower.color = UIHelper.GetUIColor(itemConfig.ItemColor);
+
+
+        var baseAttrs = appointItemConfig.BaseAttrID.ToList();
+        var baseValues = appointItemConfig.BaseAttrValue.ToList();
+        var fightAttrs = appointItemConfig.LegendAttrID.ToList();
+        var fightValues = appointItemConfig.LegendAttrValue.ToList();
+
+        for (var i = 0; i < baseAttrNames.Count; i++)
+        {
+            if (i >= baseAttrs.Count)
+            {
+                baseAttrNames[i].text = "";
+                baseAttrValues[i].text = "";
+            }
+            else
+            {
+                baseAttrNames[i].text = PlayerPropertyConfig.Get(baseAttrs[i]).Name;
+                baseAttrValues[i].text = PlayerPropertyConfig.GetValueDescription(baseAttrs[i], baseValues[i]);
+            }
+        }
+
+        if (fightAttrs.IsNullOrEmpty())
+        {
+            fightAttrGameObj.SetActive(false);
+        }
+        else
+        {
+            fightAttrGameObj.SetActive(true);
+            for (var i = 0; i < fightAttrNames.Count; i++)
+            {
+                if (i >= fightAttrs.Count)
+                {
+                    fightAttrNames[i].SetActive(false);
+                }
+                else
+                {
+                    fightAttrNames[i].SetActive(true);
+                    fightAttrNames[i].text = PlayerPropertyConfig.Get(fightAttrs[i]).Name;
+                    fightAttrValues[i].text = PlayerPropertyConfig.GetValueDescription(fightAttrs[i], fightValues[i]);
+                }
+            }
+        }
+
+    }
     //寤惰繜澶勭悊鐗规晥澶у皬
     async UniTask RefreshEffect(ItemModel equip)
-    { 
+    {
         await UniTask.DelayFrame(3);
         int effectID = EquipModel.Instance.equipUIEffects[Math.Min(equip.config.ItemColor, EquipModel.Instance.equipUIEffects.Length) - 1];
         if (effectID == 0)
@@ -119,6 +203,24 @@
         }
     }
 
+    //寤惰繜澶勭悊鐗规晥澶у皬
+    async UniTask RefreshEffect(ItemConfig itemConfig)
+    {
+        await UniTask.DelayFrame(3);
+        int effectID = EquipModel.Instance.equipUIEffects[Math.Min(itemConfig.ItemColor, EquipModel.Instance.equipUIEffects.Length) - 1];
+        if (effectID == 0)
+        {
+            uieffect.Stop();
+        }
+        else
+        {
+            uieffect.effectId = effectID;
+            //璁$畻楂樺害缂╂斁姣斾緥 鐗规晥鏄剧ず渚濊禆rect鐨勬帓鐗�
+            uieffect.transform.localScale = new Vector3(0.98f, bgRect.rect.height / uieffect.GetComponent<RectTransform>().rect.height, 1);
+            uieffect.Play();
+        }
+    }
+
 }
 
 
diff --git a/Main/System/FirstCharge.meta b/Main/System/FirstCharge.meta
new file mode 100644
index 0000000..540d958
--- /dev/null
+++ b/Main/System/FirstCharge.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3a4c2bde079b6004a842bd139495b341
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FirstCharge/FirstChargeDayAward.cs b/Main/System/FirstCharge/FirstChargeDayAward.cs
new file mode 100644
index 0000000..d14dbeb
--- /dev/null
+++ b/Main/System/FirstCharge/FirstChargeDayAward.cs
@@ -0,0 +1,224 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+/// <summary>
+/// 棣栧厖姣忔棩濂栧姳鏄剧ず缁勪欢
+/// 璐熻矗鏄剧ず棣栧厖娲诲姩姣忓ぉ鐨勫鍔卞唴瀹瑰拰棰嗗彇鐘舵��
+/// </summary>
+public class FirstChargeDayAward : MonoBehaviour
+{
+    [SerializeField] ImageEx imgCanHaveBG;          // 鍙鍙栬儗鏅珮浜樉绀�
+    [SerializeField] ImageEx imgDay;                // 澶╂暟鍥剧墖
+    [SerializeField] TextEx txtDay;                 // 澶╂暟鏂囨湰
+    [SerializeField] Transform transCount4;         // 4涓鍔辩墿鍝佺殑瀹瑰櫒
+    [SerializeField] Transform transCount3;         // 3涓鍔辩墿鍝佺殑瀹瑰櫒
+    [SerializeField] Transform transCount2;         // 2涓鍔辩墿鍝佺殑瀹瑰櫒
+    [SerializeField] Transform transCount1;         // 1涓鍔辩墿鍝佺殑瀹瑰櫒
+
+    // 鍚勬暟閲忕骇濂栧姳鐗╁搧鏄剧ず鍗曞厓
+    [SerializeField] List<ItemCell> itemCellCount4 = new List<ItemCell>();
+    [SerializeField] List<ItemCell> itemCellCount3 = new List<ItemCell>();
+    [SerializeField] List<ItemCell> itemCellCount2 = new List<ItemCell>();
+    [SerializeField] ItemCell itemCellCount1 = new ItemCell();
+
+    // 濂栧姳宸查鍙栭伄缃╁浘鐗�
+    [SerializeField] List<ImageEx> imgHaveCount4 = new List<ImageEx>();
+    [SerializeField] List<ImageEx> imgHaveCount3 = new List<ImageEx>();
+    [SerializeField] List<ImageEx> imgHaveCount2 = new List<ImageEx>();
+    [SerializeField] ImageEx imgHaveCount1 = new ImageEx();
+
+    /// <summary>
+    /// 鏄剧ず鎸囧畾棣栧厖ID鍜屽ぉ鏁扮殑濂栧姳淇℃伅
+    /// </summary>
+    /// <param name="firstId">棣栧厖閰嶇疆ID</param>
+    /// <param name="day">绗嚑澶�(1-3)</param>
+    public void Display(int firstId, int day)
+    {
+        // 鑾峰彇棣栧厖鏁版嵁
+        if (!FirstChargeManager.Instance.TryGetFirstChargeDataByFirstId(firstId, out var firstChargeData))
+            return;
+
+        // 鑾峰彇濂栧姳鐘舵��: 0-宸查鍙�, 1-涓嶅彲棰嗗彇, 2-鍙鍙�, 3-鏈煡鐘舵��
+        int awardState = firstChargeData.GetHaveState(day);
+
+        // 鏍规嵁鐘舵�佽缃甎I鏄剧ず
+        imgCanHaveBG.SetActive(firstChargeData.IsBuy() && awardState == 2);
+        txtDay.text = awardState == 0 ? Language.Get("L1129_2") : Language.Get("FirstCharge02", day);
+        imgDay.gray = awardState == 0;  // 宸查鍙栧垯缃伆澶╂暟鍥炬爣
+
+        // 闅愯棌鎵�鏈夊鍔辩墿鍝佸鍣�
+        transCount4.SetActive(false);
+        transCount3.SetActive(false);
+        transCount2.SetActive(false);
+        transCount1.SetActive(false);
+
+        // 妫�鏌ラ厤缃槸鍚﹀瓨鍦�
+        if (!FirstChargeConfig.HasKey(firstId))
+            return;
+
+        FirstChargeConfig config = FirstChargeConfig.Get(firstId);
+        int[][] awardList = GetAwardListByDay(config, day);
+
+        // 妫�鏌ュ鍔卞垪琛ㄦ湁鏁堟��
+        if (awardList == null || awardList.Length <= 0)
+        {
+            Debug.LogError($"棣栧厖琛ㄧ{day}澶╁鍔辨病閰�");
+            return;
+        }
+
+        if (awardList.Length > 4)
+        {
+            Debug.LogError($"棣栧厖琛ㄥ鍔辩墿鍝佷笉鏀寔閰嶅ぇ浜�4涓�");
+            return;
+        }
+
+        // 鏍规嵁濂栧姳鏁伴噺鏄剧ず瀵瑰簲鐨刄I
+        switch (awardList.Length)
+        {
+            case 1:
+                ShowAwardsForCount1(awardList, awardState, firstId);
+                break;
+            case 2:
+                ShowAwardsForCount2(awardList, awardState);
+                break;
+            case 3:
+                ShowAwardsForCount3(awardList, awardState);
+                break;
+            case 4:
+                ShowAwardsForCount4(awardList, awardState);
+                break;
+        }
+    }
+
+    /// <summary>
+    /// 鏍规嵁澶╂暟鑾峰彇瀵瑰簲鐨勫鍔卞垪琛�
+    /// </summary>
+    /// <param name="config">棣栧厖閰嶇疆</param>
+    /// <param name="day">澶╂暟</param>
+    /// <returns>濂栧姳鍒楄〃</returns>
+    private int[][] GetAwardListByDay(FirstChargeConfig config, int day)
+    {
+        switch (day)
+        {
+            case 1:
+                return config.AwardListDay1;
+            case 2:
+                return config.AwardListDay2;
+            case 3:
+                return config.AwardListDay3;
+            default:
+                Debug.LogError("FirstChargeItemCellShow浼犲叆澶╂暟澶т簬3鎴栧皬浜�0");
+                return null;
+        }
+    }
+
+    /// <summary>
+    /// 鏄剧ず鍗曚釜濂栧姳鐗╁搧
+    /// </summary>
+    /// <param name="awardList">濂栧姳鍒楄〃</param>
+    /// <param name="awardState">濂栧姳鐘舵��</param>
+    /// <param name="firstId">棣栧厖ID</param>
+    private void ShowAwardsForCount1(int[][] awardList, int awardState, int firstId)
+    {
+        transCount1.SetActive(true);
+        itemCellCount1.Init(new ItemCellModel((int)awardList[0][0], true, awardList[0][1]));
+        itemCellCount1.button.SetListener(() => HandleItemClick((int)awardList[0][0], awardList[0][2]));
+        imgHaveCount1.SetActive(awardState == 0);
+    }
+
+    /// <summary>
+    /// 鏄剧ず涓や釜濂栧姳鐗╁搧
+    /// </summary>
+    /// <param name="awardList">濂栧姳鍒楄〃</param>
+    /// <param name="awardState">濂栧姳鐘舵��</param>
+    private void ShowAwardsForCount2(int[][] awardList, int awardState)
+    {
+        transCount2.SetActive(true);
+        ShowAwardsCommonLogic(awardList, awardState, itemCellCount2, imgHaveCount2);
+    }
+
+    /// <summary>
+    /// 鏄剧ず涓変釜濂栧姳鐗╁搧
+    /// </summary>
+    /// <param name="awardList">濂栧姳鍒楄〃</param>
+    /// <param name="awardState">濂栧姳鐘舵��</param>
+    private void ShowAwardsForCount3(int[][] awardList, int awardState)
+    {
+        transCount3.SetActive(true);
+        ShowAwardsCommonLogic(awardList, awardState, itemCellCount3, imgHaveCount3);
+    }
+
+    /// <summary>
+    /// 鏄剧ず鍥涗釜濂栧姳鐗╁搧
+    /// </summary>
+    /// <param name="awardList">濂栧姳鍒楄〃</param>
+    /// <param name="awardState">濂栧姳鐘舵��</param>
+    private void ShowAwardsForCount4(int[][] awardList, int awardState)
+    {
+        transCount4.SetActive(true);
+        ShowAwardsCommonLogic(awardList, awardState, itemCellCount4, imgHaveCount4);
+    }
+
+    /// <summary>
+    /// 缁熶竴澶勭悊鐗╁搧鐐瑰嚮浜嬩欢
+    /// </summary>
+    /// <param name="itemId">鐗╁搧ID</param>
+    private void HandleItemClick(int itemId, int customEquipId)
+    {
+        if (!ItemConfig.HasKey(itemId))
+            return;
+        if (ItemConfig.Get(itemId).Type == 150)
+        {
+            FirstChargeManager.Instance.heroItemID = itemId;
+            UIManager.Instance.OpenWindow<FirstChargeHeroInfoWin>();
+        }
+        else if (ItemConfig.Get(itemId).Type >= 101 &&
+                ItemConfig.Get(itemId).Type <= 117 &&
+                customEquipId > 0 &&
+                AppointItemConfig.HasKey(customEquipId))
+        {
+            ItemTipUtility.ShowCustomEquip(itemId, customEquipId);
+        }
+        else
+        {
+            ItemTipUtility.Show(itemId, true);
+        }
+    }
+
+    /// <summary>
+    /// 閫氱敤濂栧姳鏄剧ず閫昏緫
+    /// </summary>
+    /// <param name="awardList">濂栧姳鍒楄〃</param>
+    /// <param name="awardState">濂栧姳鐘舵��</param>
+    /// <param name="itemCells">鐗╁搧鏄剧ず鍗曞厓鍒楄〃</param>
+    /// <param name="haveImages">宸查鍙栭伄缃╁浘鐗囧垪琛�</param>
+    private void ShowAwardsCommonLogic<T>(int[][] awardList, int awardState, List<T> itemCells, List<ImageEx> haveImages) where T : ItemCell
+    {
+        for (int i = 0; i < awardList.Length; i++)
+        {
+            // 璁剧疆鐗╁搧鏄剧ず
+            if (i < itemCells.Count)
+            {
+                int index = i; // Lambda琛ㄨ揪寮忎腑浣跨敤锛岄渶瑕佸垱寤哄眬閮ㄥ壇鏈�
+                itemCells[i].SetActive(true);
+                itemCells[i].Init(new ItemCellModel((int)awardList[i][0], true, awardList[i][1]));
+                itemCells[i].button.SetListener(() => HandleItemClick((int)awardList[index][0], awardList[index][2]));
+            }
+            else
+            {
+                itemCells[i].SetActive(false);
+            }
+
+            // 璁剧疆宸查鍙栭伄缃�
+            if (awardState == 0 && i < haveImages.Count)
+            {
+                haveImages[i].SetActive(true);
+            }
+            else if (i < haveImages.Count)
+            {
+                haveImages[i].SetActive(false);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta b/Main/System/FirstCharge/FirstChargeDayAward.cs.meta
similarity index 83%
copy from Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
copy to Main/System/FirstCharge/FirstChargeDayAward.cs.meta
index 6477a20..856df5a 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
+++ b/Main/System/FirstCharge/FirstChargeDayAward.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 56da7e3109f052e46860b1ed27323ab4
+guid: c0aadae3ee9951048aef2bd511ce3d0d
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/System/FirstCharge/FirstChargeHeroInfoWin.cs b/Main/System/FirstCharge/FirstChargeHeroInfoWin.cs
new file mode 100644
index 0000000..67e5c3f
--- /dev/null
+++ b/Main/System/FirstCharge/FirstChargeHeroInfoWin.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class FirstChargeHeroInfoWin : UIBase
+{
+    [SerializeField] ItemCell itemCell;
+    [SerializeField] TextEx txtName;
+    [SerializeField] TextEx txtJob;
+    [SerializeField] TextEx txtDesc;
+    [SerializeField] RichText txtInherit;   //姝﹀皢缁ф壙鎻忚堪
+    [SerializeField] TextEx[] txtInheritAttr;    //姝﹀皢浼氱户鎵跨殑灞炴��
+    [SerializeField] RichText txtHeroAddPer; //涓诲叕锛堜笂闃碉級鍔犳垚鎻忚堪
+    [SerializeField] TextEx[] txtHeroAddAttrPer; //涓诲叕锛堜笂闃碉級鍔犳垚
+    [SerializeField] SkillBaseCell normalSkillCell;
+    [SerializeField] SkillBaseCell angerSkillCell;
+
+    protected override void InitComponent()
+    {
+        base.InitComponent();
+        txtInherit.OnClick = () =>
+        {
+            SmallTipWin.showText = Language.Get("herocard47");
+            SmallTipWin.worldPos = CameraManager.uiCamera.ScreenToWorldPoint(Input.mousePosition);
+            UIManager.Instance.OpenWindow<SmallTipWin>();
+        };
+        txtHeroAddPer.OnClick = () =>
+        {
+            SmallTipWin.showText = Language.Get("herocard48");
+            SmallTipWin.worldPos = CameraManager.uiCamera.ScreenToWorldPoint(Input.mousePosition);
+            UIManager.Instance.OpenWindow<SmallTipWin>();
+        };
+
+    }
+
+    protected override void OnPreOpen()
+    {
+        base.OnPreOpen();
+        ItemInfo itemInfo = new ItemInfo();
+        itemInfo.itemId = FirstChargeManager.Instance.heroItemID;
+        HeroInfo heroInfo = new HeroInfo(new ItemModel(PackType.Item, itemInfo));
+        txtInheritAttr[0].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.inheritAttrs[0], heroInfo.heroConfig.AtkInheritPer));
+        txtInheritAttr[1].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.inheritAttrs[1], heroInfo.heroConfig.DefInheritPer));
+        txtInheritAttr[2].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.inheritAttrs[2], heroInfo.heroConfig.HPInheritPer));
+
+        int valuePer = heroInfo.GetOnBattleAddPer();
+        for (int i = 0; i < txtHeroAddAttrPer.Length; i++)
+        {
+            txtHeroAddAttrPer[i].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.basePerAttrs[i], valuePer));
+        }
+
+        normalSkillCell.Init(heroInfo.heroConfig.AtkSkillID, () =>
+        {
+            UIManager.Instance.OpenWindow<HeroSkillWin>(heroInfo.heroId);
+        }, true);
+        angerSkillCell.Init(heroInfo.heroConfig.AngerSkillID, () =>
+        {
+            UIManager.Instance.OpenWindow<HeroSkillWin>(heroInfo.heroId);
+        }, true);
+
+        itemCell.Init(new ItemCellModel((int)FirstChargeManager.Instance.heroItemID, true, 1));
+        txtName.text = Language.Get("FirstCharge09", Language.Get("CommonQuality" + heroInfo.Quality),heroInfo.heroConfig.Name); 
+        txtName.color = UIHelper.GetUIColorByFunc(heroInfo.Quality);
+        txtJob.text = Language.Get("FirstCharge06",Language.Get(StringUtility.Contact("HeroClass",heroInfo.heroConfig.Class)));
+        txtDesc.text = Language.Get("FirstCharge07",heroInfo.heroConfig.Desc);
+    }
+
+    protected override void OnPreClose()
+    {
+        base.OnPreClose();
+
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta b/Main/System/FirstCharge/FirstChargeHeroInfoWin.cs.meta
similarity index 83%
copy from Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
copy to Main/System/FirstCharge/FirstChargeHeroInfoWin.cs.meta
index 6477a20..b5e4465 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
+++ b/Main/System/FirstCharge/FirstChargeHeroInfoWin.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 56da7e3109f052e46860b1ed27323ab4
+guid: b00cabe8422fffb4abb93695a3aeacf0
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/System/FirstCharge/FirstChargeManager.cs b/Main/System/FirstCharge/FirstChargeManager.cs
new file mode 100644
index 0000000..8c5cb99
--- /dev/null
+++ b/Main/System/FirstCharge/FirstChargeManager.cs
@@ -0,0 +1,522 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+public class FirstChargeManager : GameSystemManager<FirstChargeManager>
+{
+    public const int FuncID = 110;
+    public int mainItemId { get { return GetMainItemId(); } }
+    public int heroItemID;
+    public int maxGiftCount
+    {
+        get
+        {
+            var list = FirstChargeConfig.GetKeys();
+            return list.IsNullOrEmpty() ? 0 : list.Count;
+        }
+    }
+    public int maxDay = 3;
+    public Redpoint parentRedpoint = new Redpoint(MainRedDot.FirstChargeRepoint);
+
+    public Dictionary<int, Redpoint> tabRedpointDict = new Dictionary<int, Redpoint>();
+    public Dictionary<int, bool> clickTabDict = new Dictionary<int, bool>();
+    public Dictionary<int, FirstChargeData> firstChargeInfoDict = new Dictionary<int, FirstChargeData>();
+    public event Action OnUpdateFirstChargeInfo;
+    public override void Init()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitializeEvent;
+        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk;
+        RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent;
+        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
+
+    }
+
+    public override void Release()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitializeEvent;
+        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk;
+        RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent;
+        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
+    }
+
+    private void OnFuncStateChangeEvent(int obj)
+    {
+        if (FuncID == obj)
+        {
+            string key = $"FirstCharge_FirstTime_{FuncID}_{PlayerDatas.Instance.baseData.PlayerID}";
+            if (!LocalSave.HasKey(key))
+            {
+                // 绗竴娆″紑鍚姛鑳�
+                LocalSave.SetBool(key, true);
+                PopupWindowsProcessor.Instance.Add("FirstChargeWin");
+            }
+        }
+    }
+
+    public void InitClickTabDict()
+    {
+        var list = FirstChargeConfig.GetKeys();
+        if (!list.IsNullOrEmpty())
+        {
+            for (int i = 0; i < list.Count; i++)
+            {
+                int firstId = list[i];
+                clickTabDict[firstId] = false;
+            }
+        }
+    }
+    public bool GetClickTabState(int fristId)
+    {
+        return clickTabDict.ContainsKey(fristId) && clickTabDict[fristId];
+    }
+    public void SetClickTabState(int fristId)
+    {
+        clickTabDict[fristId] = true;
+        UpdateRedPoint();
+    }
+
+    public void InitRedPoint()
+    {
+        var list = FirstChargeConfig.GetKeys();
+        if (!list.IsNullOrEmpty())
+        {
+            for (int i = 0; i < list.Count; i++)
+            {
+                int firstId = list[i];
+                int redpointId = GetRedpointIdByFirstId(firstId);
+                tabRedpointDict[firstId] = new Redpoint(MainRedDot.FirstChargeRepoint, redpointId);
+            }
+        }
+
+    }
+
+    public int GetRedpointIdByFirstId(int firstId)
+    {
+        return MainRedDot.FirstChargeRepoint * 10000 + firstId;
+    }
+
+    private void OnRechargeCountEvent(int obj)
+    {
+        var list = FirstChargeConfig.GetCtgIDList();
+        if (!list.IsNullOrEmpty() && list.Contains(obj))
+        {
+            UpdateRedPoint();
+        }
+    }
+
+    public void OnBeforePlayerDataInitializeEvent()
+    {
+        firstChargeInfoDict.Clear();
+    }
+    public void OnPlayerLoginOk()
+    {
+        InitClickTabDict();
+        InitRedPoint();
+        if (FuncOpen.Instance.IsFuncOpen(FuncID)&& TryGetUnBuyFirstId(out int firstId))
+        {
+            PopupWindowsProcessor.Instance.Add("FirstChargeWin");
+        }
+    }
+    public bool TryGetFirstChargeDataByFirstId(int firstId, out FirstChargeData firstChargeData)
+    {
+        return firstChargeInfoDict.TryGetValue(firstId, out firstChargeData);
+    }
+
+    public bool TryGetUnBuyFirstId(out int firstId)
+    {
+        firstId = 0;
+        var firstChargeList = FirstChargeConfig.GetKeys();
+        if (firstChargeList != null)
+        {
+            firstChargeList.Sort();
+            foreach (int item in firstChargeList)
+            {
+                if (TryGetFirstChargeDataByFirstId(item, out FirstChargeData data))
+                {
+                    if (data.IsUnlock() && !data.IsBuy())
+                    {
+                        firstId = item;
+                        return true;
+                    }
+                }
+
+            }
+        }
+        return false;
+    }
+
+    /// <summary>
+    /// 鏍规嵁鏍囩椤电储寮曡幏鍙栧搴旂殑棣栧厖ID
+    /// </summary>
+    /// <param name="tabIndex">鏍囩椤电储寮曪紝浠�0寮�濮�</param>
+    /// <returns>瀵瑰簲鐨勯鍏匢D锛屼粠1寮�濮�</returns>
+    public int GetFirstIDByTabIndex(int tabIndex)
+    {
+        return tabIndex + 1;
+    }
+
+    /// <summary>
+    /// 鏍规嵁棣栧厖ID鑾峰彇瀵瑰簲鐨勬爣绛鹃〉绱㈠紩
+    /// </summary>
+    /// <param name="firstId">棣栧厖ID锛屼粠1寮�濮�</param>
+    /// <returns>瀵瑰簲鐨勬爣绛鹃〉绱㈠紩锛屼粠0寮�濮�</returns>
+    public int GetTabIndexByFirstID(int firstId)
+    {
+        return Math.Max(firstId - 1, 0);
+    }
+
+    public int GetLastFirstIDByTabIndex(int tabIndex)
+    {
+        return GetFirstIDByTabIndex(tabIndex == 0 ? tabIndex : tabIndex - 1);
+    }
+    public int GetNextFirstIDByTabIndex(int tabIndex)
+    {
+        return GetFirstIDByTabIndex(tabIndex >= maxGiftCount - 1 ? maxGiftCount - 1 : tabIndex + 1);
+    }
+    public int GetLastFirstIDByFirstID(int firstId)
+    {
+        int tabIndex = GetTabIndexByFirstID(firstId);
+        return GetLastFirstIDByTabIndex(tabIndex);
+    }
+    public int GetNextFirstIDByFirstID(int firstId)
+    {
+        int tabIndex = GetTabIndexByFirstID(firstId);
+        return GetNextFirstIDByTabIndex(tabIndex);
+    }
+
+    public bool TryGetFirstChargeConfigByFirstID(int firstId, out FirstChargeConfig firstChargeConfig)
+    {
+        firstChargeConfig = null;
+        if (!FirstChargeConfig.HasKey(firstId))
+            return false;
+        firstChargeConfig = FirstChargeConfig.Get(firstId);
+        return true;
+    }
+
+    public bool TryGetOrderInfoConfigByFirstID(int firstId, out OrderInfoConfig orderInfoConfig)
+    {
+        orderInfoConfig = null;
+        if (!TryGetFirstChargeConfigByFirstID(firstId, out FirstChargeConfig firstChargeConfig))
+            return false;
+        int ctgId = firstChargeConfig.CTGID;
+        return RechargeManager.Instance.TryGetOrderInfo(ctgId, out orderInfoConfig);
+    }
+
+    public bool TryGetCTGConfigByFirstID(int firstId, out CTGConfig ctgConfig)
+    {
+        ctgConfig = null;
+        if (!TryGetFirstChargeConfigByFirstID(firstId, out FirstChargeConfig firstChargeConfig))
+            return false;
+        int ctgId = firstChargeConfig.CTGID;
+        if (!CTGConfig.HasKey(ctgId))
+            return false;
+        ctgConfig = CTGConfig.Get(ctgId);
+        return true;
+    }
+    public int GetMainItemId()
+    {
+        var list = FirstChargeConfig.GetKeys();
+        list.Sort();
+        var config = FirstChargeConfig.Get(list[0]);
+        for (int i = 0; i < config.AwardListDay1.Length; i++)
+        {
+            int itemId = config.AwardListDay1[i][0];
+            if (!ItemConfig.HasKey(itemId))
+                continue;
+            if (ItemConfig.Get(itemId).Type == 150)
+            {
+                return itemId;
+            }
+        }
+        return 0;
+    }
+
+    public void UpdateFirstChargeInfo(HAA02_tagSCFirstChargeInfo vNetData)
+    {
+        if (vNetData.FirstChargeList.IsNullOrEmpty())
+            return;
+        foreach (var chargeInfo in vNetData.FirstChargeList)
+        {
+            int firstID = chargeInfo.FirstID;
+            if (!firstChargeInfoDict.TryGetValue(firstID, out var firstChargeData))
+            {
+                firstChargeData = new FirstChargeData();
+                firstChargeInfoDict[firstID] = firstChargeData;
+            }
+            firstChargeData.FirstID = firstID;
+            firstChargeData.ChargeTime = chargeInfo.ChargeTime;
+            firstChargeData.AwardRecord = chargeInfo.AwardRecord;
+        }
+        // 妫�鏌ユ槸鍚︽墍鏈夊鍔遍兘宸查鍙栵紝濡傛灉鏄紝鍒欒褰曞綋鍓嶆湇鍔″櫒鏃堕棿鍒版湰鍦�
+        CheckAndSaveAllRewardsClaimedTime();
+        UpdateRedPoint();
+        OnUpdateFirstChargeInfo?.Invoke();
+    }
+    
+    /// <summary>
+    /// 妫�鏌ユ槸鍚︽墍鏈夐鍏呭鍔遍兘宸查鍙栵紝濡傛灉鏄紝鍒欏皢褰撳墠鏈嶅姟鍣ㄦ椂闂翠繚瀛樺埌鏈湴
+    /// </summary>
+    private void CheckAndSaveAllRewardsClaimedTime()
+    {
+        // 妫�鏌ユ槸鍚︽墍鏈夊鍔遍兘宸查鍙�
+        if (IsAllFirstChargeRewardsClaimed())
+        {
+            // 鐢熸垚涓�涓敮涓�鐨勯敭鏉ュ瓨鍌ㄦ椂闂�
+            string key = $"FirstCharge_AllRewardsClaimed_Time_{PlayerDatas.Instance.baseData.PlayerID}";
+            // 灏嗗綋鍓嶆湇鍔″櫒鏃堕棿淇濆瓨鍒版湰鍦�
+            LocalSave.SetString(key, TimeUtility.ServerNow.Ticks.ToString());
+        }
+    }
+    public void UpdateRedPoint()
+    {
+        // 閲嶇疆鎵�鏈夌孩鐐圭姸鎬�
+        parentRedpoint.state = RedPointState.None;
+        foreach (var redpoint in tabRedpointDict.Values)
+        {
+            redpoint.state = RedPointState.None;
+        }
+
+        var firstChargeList = FirstChargeConfig.GetKeys();
+        if (firstChargeList.IsNullOrEmpty())
+            return;
+        firstChargeList.Sort();
+        foreach (int firstId in firstChargeList)
+        {
+            if (!tabRedpointDict.ContainsKey(firstId))
+                continue;
+            var redpoint = tabRedpointDict[firstId];
+
+            if (TryGetFirstChargeDataByFirstId(firstId, out var firstChargeData))
+            {
+                if (firstChargeData.IsBuy())
+                {
+                    for (int day = 1; day <= maxDay; day++)
+                    {
+                        int awardState = firstChargeData.GetHaveState(day);
+                        // 2: 鍙鍙�
+                        if (awardState == 2)
+                        {
+                            redpoint.state = RedPointState.Simple;
+                            break;
+                        }
+                    }
+                }
+                else
+                {
+                    bool clickTabState = GetClickTabState(firstId);
+                    if (firstChargeData.IsUnlock() && !clickTabState)
+                    {
+                        redpoint.state = RedPointState.Simple;
+                    }
+                }
+            }
+
+
+        }
+    }
+
+    /// <summary>
+    /// 鍙戦�侀鍙栭鍏呭鍔辫姹�
+    /// </summary>
+    /// <param name="day">瑕侀鍙栫殑濂栧姳鏄x澶╃殑, 浠�1寮�濮�</param>
+    /// <param name="firstID">棣栧厖琛ㄧ殑ID</param>
+    public void SendGetReward(int day, int firstID)
+    {
+        var pack = new CA504_tagCMPlayerGetReward();
+        pack.RewardType = 8;
+        pack.DataEx = (uint)day;//绗瑇澶╋紝1浠h〃绗�1澶�
+        string firstIdStr = firstID.ToString();//棰嗗彇鍝釜棣栧厖ID锛屽搴旈鍏呰〃鐨処D
+        pack.DataExStr = firstIdStr;
+        pack.DataExStrLen = (byte)firstIdStr.Length;
+        GameNetSystem.Instance.SendInfo(pack);
+    }
+
+    /// <summary>
+    /// 鑷姩棰嗗彇鐜╁鍙互棰嗗彇鐨勬墍鏈夐鍏呭鍔�
+    /// </summary>
+    /// <param name="firstID">棣栧厖琛ㄧ殑ID</param>
+    public void AutoClaimAllRewards(int firstID)
+    {
+        if (!TryGetFirstChargeDataByFirstId(firstID, out var firstChargeData))
+            return;
+        if (!firstChargeData.IsBuy())
+            return;
+        // 鑾峰彇褰撳墠鏄喘涔板悗鐨勭鍑犲ぉ
+        int currentDay = firstChargeData.GetNowBuyDay();
+        // 閬嶅巻浠庣1澶╁埌褰撳墠澶╂暟鐨勬墍鏈夊鍔�
+        for (int day = 1; day <= maxDay; day++)
+        {
+            // 妫�鏌ュ鍔辩姸鎬侊紝鍙湁鐘舵�佷负宸茶喘涔版病棰嗗彇鎵嶅彂閫侀鍙栬姹�
+            if (day <= currentDay && firstChargeData.GetHaveState(day) == 2)//0: 宸查鍙� 1: 涓嶅彲棰嗗彇 2: 鍙鍙� 
+            {
+                SendGetReward(day, firstID);
+            }
+        }
+    }
+    
+    // 妫�鏌ユ槸鍚︽墍鏈夐鍏呭鍔遍兘宸茬粡棰嗗彇
+    public bool IsAllFirstChargeRewardsClaimed()
+    {
+        // 鑾峰彇鎵�鏈夐鍏呴厤缃甀D
+        var firstChargeIds = FirstChargeConfig.GetKeys();
+        if (firstChargeIds == null || firstChargeIds.Count == 0)
+            return false;
+            
+        foreach (var firstId in firstChargeIds)
+        {
+            // 灏濊瘯鑾峰彇棣栧厖鏁版嵁
+            if (!TryGetFirstChargeDataByFirstId(firstId, out var firstChargeData))
+                return false;
+                
+            // 妫�鏌ユ槸鍚﹁喘涔�
+            if (!firstChargeData.IsBuy())
+                return false;
+                
+            // 妫�鏌ユ槸鍚︽墍鏈夊鍔遍兘宸查鍙�
+            if (!firstChargeData.IsAllHave())
+                return false;
+        }
+
+        // 鎵�鏈夐鍏呮。浣嶉兘宸茶喘涔颁笖鎵�鏈夊鍔遍兘宸查鍙�
+        // 妫�鏌ユ槸鍚﹀凡缁忚繃浜嗙浜屽ぉ0鐐�
+        return true;
+    }
+    
+    // 妫�鏌ユ槸鍚﹀凡缁忚繃浜嗘墍鏈夊鍔遍鍙栧畬姣曞悗鐨勭浜屽ぉ0鐐�
+    public bool IsNextDayAfterAllClaimed()
+    {
+        // 鐢熸垚涓�涓敮涓�鐨勯敭鏉ヨ幏鍙栨椂闂�
+        string key = $"FirstCharge_AllRewardsClaimed_Time_{PlayerDatas.Instance.baseData.PlayerID}";
+        
+        // 妫�鏌ユ槸鍚﹀瓨鍦ㄨ褰曠殑鏃堕棿鎴�
+        if (!LocalSave.HasKey(key))
+            return false;
+        
+        // 鑾峰彇璁板綍鐨勬椂闂存埑
+        string timeString = LocalSave.GetString(key);
+        if (string.IsNullOrEmpty(timeString))
+            return false;
+        
+        // 瑙f瀽鏃堕棿鎴�
+        if (!long.TryParse(timeString, out long ticks))
+            return false;
+        
+        // 灏嗘椂闂存埑杞崲涓篋ateTime
+        DateTime allRewardsClaimedTime = new DateTime(ticks);
+        
+        // 璁$畻绗簩澶�0鐐圭殑鏃堕棿
+        DateTime nextDayStart = allRewardsClaimedTime.Date.AddDays(1);
+        
+        // 鍒ゆ柇褰撳墠鏈嶅姟鍣ㄦ椂闂存槸鍚﹀凡缁忚繃浜嗙浜屽ぉ0鐐�
+        DateTime serverNow = TimeUtility.ServerNow;
+        return serverNow >= nextDayStart;
+    }
+
+}
+public class FirstChargeData
+{
+    public int FirstID;        //棣栧厖ID
+    public uint ChargeTime;        //鍏呭�艰棣栧厖鐨勬椂闂存埑
+    public ushort AwardRecord;        //棣栧厖濂栧姳棰嗗璁板綍锛屾寜浜岃繘鍒朵綅璁板綍棣栧厖绗琗澶╂槸鍚﹀凡棰嗗彇锛堢1澶╁搴旂1浣嶏級
+
+    public bool IsUnlock()
+    {
+        int tabIndex = FirstChargeManager.Instance.GetTabIndexByFirstID(FirstID);
+        if (tabIndex == 0)
+            return true;
+        int lastFirstID = FirstChargeManager.Instance.GetLastFirstIDByTabIndex(tabIndex);
+        FirstChargeData firstChargeDataNow;
+        if (!FirstChargeManager.Instance.TryGetFirstChargeDataByFirstId(lastFirstID, out firstChargeDataNow))
+            return false;
+        return firstChargeDataNow.IsBuy();
+    }
+
+    public bool IsBuy()
+    {
+        return ChargeTime > 0;
+    }
+
+    /// <summary>
+    /// 妫�鏌ユ寚瀹氬ぉ鐨勫鍔辨槸鍚﹀凡棰嗗彇
+    /// </summary>
+    /// <param name="day">澶╂暟锛屼粠1寮�濮�</param>
+    public bool IsHave(int day)
+    {
+        bool res = (AwardRecord & (1 << day)) != 0;
+        return res;
+    }
+
+    public bool IsAllHave()
+    {
+        int maxGiftCount = FirstChargeManager.Instance.maxGiftCount;
+        for (int i = 1; i <= maxGiftCount; i++)
+        {
+            if (!IsHave(i))
+                return false;
+        }
+        return true;
+    }
+    
+   // ... existing code ...
+    /// <summary>
+    /// 鑾峰彇褰撳墠鏃堕棿鏄喘涔拌繖妗e厖鍊肩ぜ鍖呯殑绗嚑澶�
+    /// 璐拱鐨勫綋澶╃畻浣滅涓�澶╋紝绗簩澶�0鐐瑰悗绠楃浜屽ぉ锛屼互姝ょ被鎺�
+    /// </summary>
+    /// <returns>绗嚑澶�</returns>
+    public int GetNowBuyDay()
+    {
+        DateTime serverNow = TimeUtility.ServerNow;
+        DateTime chargeTime = TimeUtility.GetTime(ChargeTime);
+      
+        DateTime chargeDate = chargeTime.Date;
+        DateTime serverDate = serverNow.Date;
+        
+        // 璁$畻浠庡厖鍊兼棩鏈熷埌褰撳墠鏃ユ湡鐨勫畬鏁村ぉ鏁�
+        // 璐拱鐨勫綋澶╃畻绗竴澶╋紝绗簩澶�0鐐瑰悗绠楃浜屽ぉ
+        TimeSpan timeSpan = serverDate - chargeDate;
+        int days = (int)timeSpan.TotalDays + 1; // +1 鍥犱负褰撳ぉ绠楃涓�澶�
+        
+        int maxDay = FirstChargeManager.Instance.maxDay;
+
+        return Mathf.Min(maxDay, Mathf.Max(1, days));
+    }
+
+    public bool HasNextDay()
+    {
+        int currentDay = GetNowBuyDay();
+        int maxDay = FirstChargeManager.Instance.maxDay;
+        return currentDay < maxDay;
+    }
+
+    /// <summary>
+    /// 鑾峰緱鎸囧畾澶╃殑棰嗗彇璇︾粏鐘舵��
+    /// </summary>
+    /// <param name="day">澶╂暟锛屼粠1寮�濮�</param>
+    //0: 宸查鍙� 1: 涓嶅彲棰嗗彇 2: 鍙鍙� 
+    public int GetHaveState(int day)
+    {
+        if (IsHave(day))
+            return 0;
+        int currentDay = GetNowBuyDay();
+        // 妫�鏌ユ槸鍚﹀彲浠ラ鍙栵紙璐拱杩欐。鍏呭�肩ぜ鍖呯殑绗竴澶╁悗鎵嶅彲棰嗗彇锛�
+        return day <= currentDay ? 2 : 1;
+    }
+
+    /// <summary>
+    /// 杩斿洖鏄剧ず璺濈绗簩澶�0鐐硅В閿佸鍔卞墿浣欐椂闂�
+    /// </summary>
+    /// <returns>鍓╀綑鏃堕棿瀛楃涓诧紝鏍煎紡锛氬皬鏃�:鍒嗛挓:绉掗挓</returns>
+    public string GetNextDayUnlockRemainingTime()
+    {
+        if (!IsBuy())
+            return string.Empty;
+        DateTime serverNow = TimeUtility.ServerNow;
+        DateTime nextDayStart = serverNow.Date.AddDays(1);
+        TimeSpan remainingTime = nextDayStart - serverNow;
+        int remainingSeconds = (int)remainingTime.TotalSeconds;
+        return TimeUtility.SecondsToHMS(remainingSeconds);
+    }
+
+}
\ No newline at end of file
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta b/Main/System/FirstCharge/FirstChargeManager.cs.meta
similarity index 83%
copy from Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
copy to Main/System/FirstCharge/FirstChargeManager.cs.meta
index 6477a20..c66c6d9 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
+++ b/Main/System/FirstCharge/FirstChargeManager.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 56da7e3109f052e46860b1ed27323ab4
+guid: b013edce05d6415418c0b0edbf55af71
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/System/FirstCharge/FirstChargeWin.cs b/Main/System/FirstCharge/FirstChargeWin.cs
new file mode 100644
index 0000000..30f1e62
--- /dev/null
+++ b/Main/System/FirstCharge/FirstChargeWin.cs
@@ -0,0 +1,308 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using UnityEngine;
+
+public class FirstChargeWin : FunctionsBaseWin
+{
+    [Header("鏍囩椤�")]
+    [SerializeField] TextEx[] txtTabTitles;
+    [SerializeField] ButtonEx[] btnTabs;
+    [SerializeField] RedpointBehaviour[] rpTabs;
+    [Header("涓荤墿鍝�")]
+    [SerializeField] TextEx txtName;
+    [SerializeField] TextEx txtDesc;
+    [SerializeField] ImageEx imgCountry;
+    [SerializeField] ImageEx imgJob;
+    [SerializeField] UIHeroController roleLhModel;    //灞曠ず鑻遍泟绔嬬粯
+    [SerializeField] ButtonEx btnPreviewHero;
+    [Header("棰濆閬撳叿瀹d紶鏂囧瓧")]
+    [SerializeField] ImageEx imgExtraRewardText;
+    [SerializeField] TextEx txtExtraRewardText;
+
+    [Header("濂栧姳鐗╁搧")]
+    [SerializeField] FirstChargeDayAward[] days;
+
+    [Header("鎬т环姣旀枃瀛�")]
+    [SerializeField] TextEx txtPercentage;
+
+    [Header("璐拱鍜岄鍙�")]
+    [SerializeField] ImageEx imgHave;
+    [SerializeField] ImageEx imgNoHave;
+    [SerializeField] ImageEx imgRed;
+    [SerializeField] TextEx txtHave;
+    [SerializeField] ButtonEx btnHave;
+    [SerializeField] TextEx txtBuy;
+    [SerializeField] ButtonEx btnBuy;
+    FirstChargeManager model { get { return FirstChargeManager.Instance; } }
+    protected override void InitComponent()
+    {
+        base.InitComponent();
+        btnHave.SetListener(OnClickHaveButton);
+        btnBuy.SetListener(OnClickBuyButton);
+        btnPreviewHero.SetListener(OnClickPreviewHero);
+    }
+
+
+
+    protected override void OnPreOpen()
+    {
+        base.OnPreOpen();
+        InitRedPoint();
+
+        functionOrder = GetDefaultTabIndex();
+        tabButtons[functionOrder].SelectBtn(true);
+
+        int firstId = model.GetFirstIDByTabIndex(functionOrder);
+        model.SetClickTabState(firstId);
+        model.OnUpdateFirstChargeInfo += OnUpdateFirstChargeInfo;
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        DisplayMainItem();
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        base.OnPreClose();
+        model.OnUpdateFirstChargeInfo -= OnUpdateFirstChargeInfo;
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+    }
+
+    private void OnSecondEvent()
+    {
+        int firstId = model.GetFirstIDByTabIndex(functionOrder);
+        if (!model.TryGetFirstChargeDataByFirstId(firstId, out var firstChargeData))
+            return;
+        if (!firstChargeData.IsUnlock())
+            return;
+        if (!firstChargeData.IsBuy())
+            return;
+        DisplayButton(firstId);
+    }
+
+    protected override void OpenSubUIByTabIndex()
+    {
+        int firstId = model.GetFirstIDByTabIndex(functionOrder);
+        model.SetClickTabState(firstId);
+        Display();
+    }
+
+    private void OnUpdateFirstChargeInfo()
+    {
+        Display();
+    }
+    private void OnClickBuyButton()
+    {
+        int firstId = model.GetFirstIDByTabIndex(functionOrder);
+        if (!model.TryGetFirstChargeConfigByFirstID(firstId, out FirstChargeConfig firstChargeConfig))
+            return;
+        RechargeManager.Instance.CTG(firstChargeConfig.CTGID);
+    }
+
+    private void OnClickHaveButton()
+    {
+        int firstId = model.GetFirstIDByTabIndex(functionOrder);
+        model.AutoClaimAllRewards(firstId);
+    }
+    private void OnClickPreviewHero()
+    {
+        HeroUIManager.Instance.selectForPreviewHeroID = model.mainItemId;
+        UIManager.Instance.OpenWindow<HeroBestWin>();
+    }
+    private void InitRedPoint()
+    {
+        for (int i = 0; i < rpTabs.Length; i++)
+        {
+            int firstID = model.GetFirstIDByTabIndex(i);
+            int redpointId = model.GetRedpointIdByFirstId(firstID);
+            rpTabs[i].redpointId = redpointId;
+        }
+    }
+
+    private int GetDefaultTabIndex()
+    {
+        List<int> unlockedAndBoughtAndClaimable = new List<int>();      // 宸茶В閿佸凡璐拱鍙鍙�
+        List<int> unlockedAndNotBought = new List<int>();               // 宸茶В閿佹湭璐拱
+        List<int> unlockedAndBoughtAndNotClaimed = new List<int>();     // 宸茶В閿佸凡璐拱鏈鍙�
+
+        var firstChargeList = FirstChargeConfig.GetKeys();
+        if (firstChargeList != null)
+        {
+            firstChargeList.Sort();
+            foreach (int firstId in firstChargeList)
+            {
+                if (!model.TryGetFirstChargeDataByFirstId(firstId, out FirstChargeData firstChargeData))
+                    continue;
+
+                if (!firstChargeData.IsUnlock())
+                    continue;
+
+                if (firstChargeData.IsBuy())
+                {
+                    bool hasClaimable = false;
+                    bool hasUnclaimed = false;
+
+                    for (int day = 1; day <= model.maxDay; day++)
+                    {
+                        int awardState = firstChargeData.GetHaveState(day);
+                        if (awardState == 2) // 鍙鍙�
+                        {
+                            hasClaimable = true;
+                            break;
+                        }
+                        else if (awardState == 1) // 鏈埌棰嗗彇鏃堕棿
+                        {
+                            hasUnclaimed = true;
+                        }
+                    }
+
+                    if (hasClaimable)
+                    {
+                        unlockedAndBoughtAndClaimable.Add(firstId);
+                    }
+                    else if (hasUnclaimed)
+                    {
+                        unlockedAndBoughtAndNotClaimed.Add(firstId);
+                    }
+                }
+                else
+                {
+                    // 鏈喘涔�
+                    unlockedAndNotBought.Add(firstId);
+                }
+            }
+
+            // 鎸夌収浼樺厛绾ц繑鍥�
+            if (unlockedAndBoughtAndClaimable.Count > 0)
+            {
+                return model.GetTabIndexByFirstID(unlockedAndBoughtAndClaimable[0]);
+            }
+            else if (unlockedAndNotBought.Count > 0)
+            {
+                return model.GetTabIndexByFirstID(unlockedAndNotBought[0]);
+            }
+            else if (unlockedAndBoughtAndNotClaimed.Count > 0)
+            {
+                return model.GetTabIndexByFirstID(unlockedAndBoughtAndNotClaimed[0]);
+            }
+        }
+
+        return 0;
+    }
+
+    private void Display()
+    {
+        int firstId = model.GetFirstIDByTabIndex(functionOrder);
+        DisplayTab();
+        DisplayExtraRewardText(firstId);
+        DisplayAward(firstId);
+        DisplayPercentage(firstId);
+        DisplayButton(firstId);
+    }
+    public void DisplayMainItem()
+    {
+        ItemInfo itemInfo = new ItemInfo();
+        itemInfo.itemId = FirstChargeManager.Instance.mainItemId;
+        HeroInfo heroInfo = new HeroInfo(new ItemModel(PackType.Item, itemInfo));
+        txtName.text = heroInfo.heroConfig.Name;
+        txtName.color = UIHelper.GetUIColorByFunc(heroInfo.Quality);
+        txtDesc.text = heroInfo.heroConfig.Desc;
+        imgCountry.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroInfo.heroConfig.Country));
+        imgJob.SetSprite(HeroUIManager.Instance.GetJobIconName(heroInfo.heroConfig.Class));
+        roleLhModel.Create(heroInfo.SkinID, 0.6f, motionName: "", isLh: true);
+        roleLhModel.transform.localScale = new Vector3(0.6f, 0.6f, 0.6f);
+    }
+
+    public void DisplayAward(int firstId)
+    {
+        for (int i = 0; i < days.Length; i++)
+        {
+            days[i].Display(firstId, i + 1);
+        }
+    }
+    public void DisplayExtraRewardText(int firstId)
+    {
+        if (!model.TryGetFirstChargeConfigByFirstID(firstId, out var config))
+            return;
+        int extraRewardTextType = config.ExtraRewardTextType;
+        if (extraRewardTextType < 0 || extraRewardTextType > 1)
+            return;
+        if (extraRewardTextType == 0)
+        {
+            if (!IconConfig.HasKey(config.ExtraRewardTextInfo))
+                return;
+            imgExtraRewardText.SetActive(true);
+            txtExtraRewardText.SetActive(false);
+            imgExtraRewardText.SetSprite(config.ExtraRewardTextInfo);
+        }
+        else
+        {
+            if (!LanguageConfig.HasKey(config.ExtraRewardTextInfo))
+                return;
+            imgExtraRewardText.SetActive(false);
+            txtExtraRewardText.SetActive(true);
+            txtExtraRewardText.text = Language.Get(config.ExtraRewardTextInfo);
+        }
+    }
+
+    public void DisplayTab()
+    {
+        for (int i = 0; i < btnTabs.Length; i++)
+        {
+            int firstID = model.GetFirstIDByTabIndex(i);
+            FirstChargeData firstChargeData;
+            if (!model.TryGetFirstChargeDataByFirstId(firstID, out firstChargeData))
+                continue;
+            btnTabs[i].SetActive(firstChargeData.IsUnlock());
+            OrderInfoConfig orderInfoConfig;
+            if (model.TryGetOrderInfoConfigByFirstID(firstID, out orderInfoConfig))
+            {
+                txtTabTitles[i].text = Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNum);
+            }
+        }
+    }
+
+    public void DisplayPercentage(int firstId)
+    {
+        if (!model.TryGetCTGConfigByFirstID(firstId, out CTGConfig ctgConfig))
+            return;
+        txtPercentage.text = Language.Get("FirstCharge03", model.maxDay, ctgConfig.Percentage);
+    }
+
+    public void DisplayButton(int firstId)
+    {
+        if (!model.TryGetFirstChargeDataByFirstId(firstId, out var firstChargeData))
+            return;
+        if (!model.TryGetOrderInfoConfigByFirstID(firstId, out OrderInfoConfig orderInfo))
+            return;
+
+        //璐拱
+        bool isBuy = firstChargeData.IsBuy();
+        btnBuy.SetActive(!isBuy);
+        btnHave.SetActive(isBuy);
+        txtBuy.text = Language.Get("PayMoneyNum", orderInfo.PayRMBNum);
+        //棰嗗彇
+        int day = firstChargeData.GetNowBuyDay();
+        //0: 宸查鍙� 1: 涓嶅彲棰嗗彇 2: 鍙鍙� 
+        int awardState = firstChargeData.GetHaveState(day);
+        bool isAllHave = firstChargeData.IsAllHave();
+        btnHave.interactable = awardState == 2;
+        imgNoHave.SetActive(awardState != 2);
+        imgHave.SetActive(awardState == 2);
+        imgRed.SetActive(awardState == 2);
+        if (awardState == 2)
+        {
+            txtHave.text = Language.Get("Mail09");
+        }
+        else if (awardState == 1 || (awardState == 0 && !isAllHave))
+        {
+            txtHave.text = firstChargeData.GetNextDayUnlockRemainingTime();
+        }
+        else
+        {
+            txtHave.text = Language.Get("FirstCharge04");
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta b/Main/System/FirstCharge/FirstChargeWin.cs.meta
similarity index 83%
copy from Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
copy to Main/System/FirstCharge/FirstChargeWin.cs.meta
index 6477a20..deba056 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA02_tagMCFirstGoldInfo.cs.meta
+++ b/Main/System/FirstCharge/FirstChargeWin.cs.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 56da7e3109f052e46860b1ed27323ab4
+guid: 3d259a77e6813334b92edc4ce7bb2111
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2
diff --git a/Main/System/ItemTip/ItemTipUtility.cs b/Main/System/ItemTip/ItemTipUtility.cs
index fc652e9..1615781 100644
--- a/Main/System/ItemTip/ItemTipUtility.cs
+++ b/Main/System/ItemTip/ItemTipUtility.cs
@@ -305,30 +305,30 @@
 
 
         switch (tipType)
-            {
-                case TipType.Equip:
-                    // WindowCenter.Instance.Open<EquipTipWin>();
-                    break;
+        {
+            case TipType.Equip:
+                // WindowCenter.Instance.Open<EquipTipWin>();
+                break;
 
-                // case TipType.PetMount:
-                //      WindowCenter.Instance.Open<PetMountTipWin>();
-                //     break;
+            // case TipType.PetMount:
+            //      WindowCenter.Instance.Open<PetMountTipWin>();
+            //     break;
 
-                case TipType.BoxItem:
-                    UIManager.Instance.OpenWindow<BoxItemWin>();
-                    break;
-                case TipType.BoxChooseItem:
-                    UIManager.Instance.OpenWindow<ChooseItemsWin>();
-                    break;
-                case TipType.TreasurePavilion:
-                    // TreasurePavilionModel.Instance.selectGubao = config.EffectValueA1;
-                    // TreasurePavilionModel.Instance.showTipFromPiece = config.ID;
-                    // WindowCenter.Instance.OpenIL<TreasurePavilionTipWin>();
-                    break;
-                default:
-                    UIManager.Instance.OpenWindow<ItemTipWin>();
-                    break;
-            }
+            case TipType.BoxItem:
+                UIManager.Instance.OpenWindow<BoxItemWin>();
+                break;
+            case TipType.BoxChooseItem:
+                UIManager.Instance.OpenWindow<ChooseItemsWin>();
+                break;
+            case TipType.TreasurePavilion:
+                // TreasurePavilionModel.Instance.selectGubao = config.EffectValueA1;
+                // TreasurePavilionModel.Instance.showTipFromPiece = config.ID;
+                // WindowCenter.Instance.OpenIL<TreasurePavilionTipWin>();
+                break;
+            default:
+                UIManager.Instance.OpenWindow<ItemTipWin>();
+                break;
+        }
     }
 
     public static void Show(string guid, bool operatable = true)
@@ -386,6 +386,7 @@
         switch (tipType)
         {
             case TipType.Equip:
+                isShowCustomEquip = false;
                 UIManager.Instance.OpenWindow<EquipTipWin>();
                 break;
             // case TipType.PetMount:
@@ -408,6 +409,16 @@
         }
 
     }
+    public static bool isShowCustomEquip = false;
+    public static int customEquipItemId;
+    public static int customEquipAppointItemId;
+    public static void ShowCustomEquip(int itemId, int appointItemId)
+    {
+        customEquipItemId = itemId;
+        customEquipAppointItemId = appointItemId;
+        isShowCustomEquip = true;
+        UIManager.Instance.OpenWindow<EquipTipWin>();
+    }
 
 
     // public static void ShowCustomEquip(CustomEquipInfo info)
@@ -417,7 +428,7 @@
     //     WindowCenter.Instance.Open<EquipTipWin>();
     // }
 
-    
+
 
     // static TipData CreateNormalEquipData(string guid)
     // {
@@ -765,8 +776,8 @@
         };
     }
 
-    
-    
+
+
     // public static void Operate(ItemOperateType type, string guid)
     // {
     //     switch (type)
@@ -1377,7 +1388,7 @@
     //     var data = new StrengthenProperty();
 
     //     var strengthenLevel = strengthenModel.GetStrengthLevel(level, place);
-        
+
     //     var type = EquipStrengthModel.GetEquipStrengthType(place);
     //     var maxStrengthenLevel = strengthenModel.GetEquipLevelMax(type, level);
 
@@ -1514,7 +1525,7 @@
 
         return skillInfo;
     }
-    
+
 
     private static SkillInfo GetSkillInfo(int itemId, CustomEquipInfo info)
     {
@@ -1556,7 +1567,7 @@
     //     return skillInfo;
     // }
 
-    
+
 
     // private static GetWay GetGetWay(int itemId)
     // {
@@ -1593,8 +1604,8 @@
     //     return getWay;
     // }
 
-    
-    
+
+
 
     private static List<ItemOperateType> GetGoodOperates(int goodId)
     {
@@ -1642,7 +1653,7 @@
     {
         var boxType = ChestsAwardConfig.GetBoxType(itemId);
         if (boxType == 1)
-        { 
+        {
             return TipType.BoxItem;
         }
         else if (boxType == 2)
@@ -1681,7 +1692,7 @@
     }
 
 
-    
+
 
 
     [System.Diagnostics.Conditional("UNITY_EDITOR")]
diff --git a/Main/System/Main/HomeWin.cs b/Main/System/Main/HomeWin.cs
index 20c62b6..e3d2826 100644
--- a/Main/System/Main/HomeWin.cs
+++ b/Main/System/Main/HomeWin.cs
@@ -1,3 +1,4 @@
+using System;
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
@@ -53,6 +54,7 @@
 
     //鍏朵粬鍔熻兘鍏ュ彛
     [SerializeField] Button monthCardBtn;
+    [SerializeField] Button FirstChargeBtn;
 
     /// <summary>
     /// 鍒濆鍖栫粍浠�
@@ -83,6 +85,11 @@
             InvestModel.Instance.BuyInvest(InvestModel.monthCardType);
         });
 
+        FirstChargeBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<FirstChargeWin>();
+        });
+
         blessLVBtn.AddListener(() =>
         {
             UIManager.Instance.OpenWindow<BlessLVWin>();
@@ -92,7 +99,7 @@
         {
             UIManager.Instance.OpenWindow<MailWin>();
         });
-        
+
         officialUpBtn.AddListener(() =>
         {
             if (RealmConfig.GetKeys().Count <= PlayerDatas.Instance.baseData.realmLevel)
@@ -128,7 +135,12 @@
         AutoFightModel.Instance.OnFightEvent += ChangeMode;
         TeamManager.Instance.OnTeamChange += DisplayCard;
         UIManager.Instance.OnCloseWindow += OnCloseWindow;
+        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChange;
+        FirstChargeManager.Instance.OnUpdateFirstChargeInfo += OnUpdateFirstChargeInfo;
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
         Display();
+        DisplayFirstChargeBtn();
+
         // var battleWin = UIManager.Instance.OpenWindow<BattleWin>();
         // battleWin.SetBattleField(BattleManager.Instance.storyBattleField);
     }
@@ -144,6 +156,9 @@
         AutoFightModel.Instance.OnFightEvent -= ChangeMode;
         TeamManager.Instance.OnTeamChange -= DisplayCard;
         UIManager.Instance.OnCloseWindow -= OnCloseWindow;
+        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChange;
+        FirstChargeManager.Instance.OnUpdateFirstChargeInfo -= OnUpdateFirstChargeInfo;
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
 
         //  鍏抽棴鐨勬椂鍊欐妸鎴樻枟鐣岄潰涔熺粰鍏充簡 铏界劧鏄湪澶栭潰寮�鐨�
         UIManager.Instance.CloseWindow<BattleWin>();
@@ -174,7 +189,7 @@
                 break;
             case PlayerDataType.LV:
                 if (lastLV != PlayerDatas.Instance.baseData.LV)
-                { 
+                {
                     lastLV = PlayerDatas.Instance.baseData.LV;
                     lvUPEffect.Play();
                 }
@@ -375,11 +390,44 @@
     }
 
     void GotoRest()
-    { 
+    {
         if (BattleManager.Instance.storyBattleField != null &&
             BattleManager.Instance.storyBattleField.GetBattleMode() != BattleMode.Stop)
         {
             BattleManager.Instance.storyBattleField.HaveRest();
         }
     }
+
+    private void DisplayFirstChargeBtn()
+    {
+        bool isFirstChargeFuncOpen = FuncOpen.Instance.IsFuncOpen(FirstChargeManager.FuncID);
+        if (FirstChargeManager.Instance.IsAllFirstChargeRewardsClaimed() &&
+        FirstChargeManager.Instance.IsNextDayAfterAllClaimed())
+        {
+            FirstChargeBtn.SetActive(false);
+        }
+        else
+        {
+            FirstChargeBtn.SetActive(isFirstChargeFuncOpen);
+        }
+
+    }
+
+    private void OnFuncStateChange(int funcId)
+    {
+        if (funcId == FirstChargeManager.FuncID)
+        {
+            DisplayFirstChargeBtn();
+        }
+    }
+
+    private void OnUpdateFirstChargeInfo()
+    {
+        DisplayFirstChargeBtn();
+    }
+
+    private void OnSecondEvent()
+    {
+        DisplayFirstChargeBtn();
+    }
 }
\ No newline at end of file
diff --git a/Main/System/Recharge/RechargeManager.cs b/Main/System/Recharge/RechargeManager.cs
index 74707d9..5bf1598 100644
--- a/Main/System/Recharge/RechargeManager.cs
+++ b/Main/System/Recharge/RechargeManager.cs
@@ -674,13 +674,13 @@
         return 0;
     }
 
-    public void UpdateFirstChargeReward(HAA02_tagMCFirstGoldInfo package)
-    {
-        FirstGoldServerDay = package.FirstGoldServerDay;
-        firstChargeRewardGet = package.FirstGoldRewardState;
-        UpdateFirstRechargeRedpoint();
-        UpdateRedpoint();
-    }
+    // public void UpdateFirstChargeReward(HAA02_tagMCFirstGoldInfo package)
+    // {
+    //     FirstGoldServerDay = package.FirstGoldServerDay;
+    //     firstChargeRewardGet = package.FirstGoldRewardState;
+    //     UpdateFirstRechargeRedpoint();
+    //     UpdateRedpoint();
+    // }
 
     private void UpdateFirstRechargeRedpoint()
     {
diff --git a/Main/System/Redpoint/MainRedDot.cs b/Main/System/Redpoint/MainRedDot.cs
index 08cdb4b..315913f 100644
--- a/Main/System/Redpoint/MainRedDot.cs
+++ b/Main/System/Redpoint/MainRedDot.cs
@@ -95,7 +95,7 @@
     public const int LianQiRepoint = 465; //浠欏尃澶т細
     public const int FairySiegeRepoint = 466; //浠欑洘鏀诲煄鎴�
     public const int MailRepoint = 467; //閭
-    
+    public const int FirstChargeRepoint = 468; //棣栧厖
 
 
 

--
Gitblit v1.8.0