From 42c8ae5a4fe49c5afdf898da874df55d8d2361cb Mon Sep 17 00:00:00 2001
From: lcy <1459594991@qq.com>
Date: 星期二, 28 四月 2026 21:19:46 +0800
Subject: [PATCH] 628 节假日活动-五一活动 基本功能

---
 Main/System/FestivalActivity/FestivalActivityPopWin.cs.meta                                              |   11 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA71_tagSCActTaskInfo.cs                           |   23 
 Main/System/FestivalActivity/FestivalActivityPopWin.cs                                                   |   83 +
 Main/System/FestivalActivity/FestivalActivityRechargeTotDayManager.cs.meta                               |   11 
 Main/System/FestivalActivity/FestivalActivityShopWin.cs.meta                                             |   11 
 Main/System/FestivalActivity/FestivalActivityShopLineCell.cs.meta                                        |   11 
 Main/System/BoneField/AdsManager.cs                                                                      |    3 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA1C_tagSCActTotalRechargePlayerInfo.cs  |    1 
 Main/System/FestivalActivity/FestivalActivityRechargeBaseWin.cs                                          |   52 
 Main/System/Redpoint/MainRedDot.cs                                                                       |    3 
 Main/System/FestivalActivity/FestivalActivityManager.cs                                                  |  502 ++++++
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA71_tagSCActTaskInfo.cs.meta            |   11 
 Main/System/FestivalActivity/FestivalActivityCheckInManager.cs                                           |  191 ++
 Main/System/FestivalActivity/FestivalActivityShopLineCell.cs                                             |   31 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA72_tagSCActTaskPlayerValueInfo.cs      |   12 
 Main/System/FestivalActivity/FestivalActivityManager.cs.meta                                             |   11 
 Main/Config/Configs/ActTaskTempConfig.cs                                                                 |   56 
 Main/Config/Configs/ActSignConfig.cs                                                                     |   41 
 Main/System/FestivalActivity/FestivalActivityRechargeTotalManager.cs.meta                                |   11 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA10_tagSCActSpecialSaleInfo.cs.meta     |   11 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA10_tagSCActSpecialSaleInfo.cs.meta               |   11 
 Main/Config/Configs/ActTaskConfig.cs.meta                                                                |   11 
 Main/Utility/EnumHelper.cs                                                                               |   10 
 Main/System/FestivalActivity/OperationMissionActivityInfo.cs                                             |   23 
 Main/System/FestivalActivity/FestivalActivityShopWin.cs                                                  |   84 +
 Main/System/FestivalActivity/OperationMissionActivityInfo.cs.meta                                        |   11 
 Main/System/FestivalActivity/FestivalActivityCheckInCell.cs                                              |   60 
 Main/System/FestivalActivity/FestivalActivityMissionManager.cs.meta                                      |   11 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA73_tagSCActTaskPlayerInfo.cs.meta                |   11 
 Main/System/FestivalActivity/FestivalActivityMissionManager.cs                                           |  385 +++++
 Main/System/FestivalActivity/OperationCheckInActivityInfo.cs.meta                                        |   11 
 Main/Config/Configs/ActSignConfig.cs.meta                                                                |   11 
 Main/System/FestivalActivity/OperationFlashSaleActivityInfo.cs.meta                                      |   11 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA10_tagSCActSpecialSaleInfo.cs                    |   23 
 Main/Config/Configs/ActSpecialSaleConfig.cs.meta                                                         |   11 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA71_tagSCActTaskInfo.cs.meta                      |   11 
 Main/System/FestivalActivity/FestivalActivityRechargeTotDayCell.cs                                       |   74 +
 Main/Config/PartialConfigs/ActTaskTempConfig.cs                                                          |   63 
 Main/System/OpenServerActivity/OperationTimeHepler.cs                                                    |  227 ++
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA71_tagSCActTaskInfo.cs                 |   12 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA72_tagSCActTaskPlayerValueInfo.cs.meta           |   11 
 Main/System/FestivalActivity/FestivalActivityRechargeTotalWin.cs                                         |  118 +
 Main/System/FestivalActivity/FestivalActivityShopCell.cs                                                 |  135 +
 Main/System/FestivalActivity/FestivalActivityMissionCell.cs.meta                                         |   11 
 Main/System/FestivalActivity/FestivalActivityWin.cs.meta                                                 |   11 
 Main/System/FestivalActivity/FestivalActivityRechargeTotalWin.cs.meta                                    |   11 
 Main/System/FestivalActivity/FestivalActivityPopCell.cs                                                  |   18 
 Main/System/FestivalActivity/FestivalActivityWin.cs                                                      |   79 +
 Main/Config/ConfigManager.cs                                                                             |   12 
 Main/System/FestivalActivity/FestivalActivityRechargeTotalCell.cs                                        |   74 +
 Main/System/FestivalActivity/FestivalActivityRechargeTotDayWin.cs                                        |  113 +
 Main/System/FestivalActivity/FestivalActivityRechargeTotalManager.cs                                     |  249 +++
 Main/System/FestivalActivity/FestivalActivityMissionWin.cs.meta                                          |   11 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA73_tagSCActTaskPlayerInfo.cs                     |   25 
 Main/System/FestivalActivity/FestivalActivityRechargeTotDayManager.cs                                    |  248 +++
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA23_tagSCActSignInfo.cs                           |   23 
 Main/System/FestivalActivity/FestivalActivityPopCell.cs.meta                                             |   11 
 Main/System/FestivalActivity/FestivalActivityGiftWin.cs.meta                                             |   11 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA72_tagSCActTaskPlayerValueInfo.cs.meta |   11 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA10_tagSCActSpecialSaleInfo.cs          |   14 
 Main/System/FestivalActivity/FestivalActivityCheckInWin.cs.meta                                          |   11 
 Main/System/FestivalActivity/FestivalActivityCheckInWin.cs                                               |   63 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA23_tagSCActSignInfo.cs                 |   14 
 Main/System/Main/HomeWin.cs                                                                              |   22 
 Main/System/FestivalActivity/FestivalActivityCheckInCell.cs.meta                                         |   11 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA1A_tagSCActTotDayRechargePlayerInfo.cs |    1 
 Main/Main.cs                                                                                             |    6 
 Main/Config/Configs/ActTaskConfig.cs                                                                     |   50 
 Main/System/FestivalActivity/FestivalActivityRechargeBaseWin.cs.meta                                     |   11 
 Main/Config/Configs/ActSpecialSaleConfig.cs                                                              |   68 
 Main/System/FestivalActivity/FestivalActivityMissionWin.cs                                               |  149 ++
 Main/System/FestivalActivity/FestivalActivityGiftCell.cs.meta                                            |   11 
 Main/Config/Configs/ActTaskTempConfig.cs.meta                                                            |   11 
 Main/Config/PartialConfigs/ActTaskTempConfig.cs.meta                                                     |   11 
 Main/System/FestivalActivity/FestivalActivityRechargeTotDayWin.cs.meta                                   |   11 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA73_tagSCActTaskPlayerInfo.cs.meta      |   11 
 Main/System/FestivalActivity/FestivalActivityGiftCell.cs                                                 |  227 +++
 Main/System/FestivalActivity/OperationCheckInActivityInfo.cs                                             |   23 
 Main/System/FestivalActivity/FestivalActivityGiftWin.cs                                                  |   82 +
 Main/System/FestivalActivity/FestivalActivityRechargeTotalCell.cs.meta                                   |   11 
 Main/System/FestivalActivity/FestivalActivityShopCell.cs.meta                                            |   11 
 Main/System/FestivalActivity/OperationFlashSaleActivityInfo.cs                                           |   34 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA23_tagSCActSignInfo.cs.meta                      |   11 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA23_tagSCActSignInfo.cs.meta            |   11 
 Main/System/FestivalActivity/FestivalActivityCheckInManager.cs.meta                                      |   11 
 Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs                                                     |    5 
 Main/System/FestivalActivity/FestivalActivityMissionCell.cs                                              |   73 +
 Main/System/FestivalActivity.meta                                                                        |    8 
 Main/System/FestivalActivity/FestivalActivityRechargeTotDayCell.cs.meta                                  |   11 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA73_tagSCActTaskPlayerInfo.cs           |   12 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA72_tagSCActTaskPlayerValueInfo.cs                |   31 
 91 files changed, 4,318 insertions(+), 57 deletions(-)

diff --git a/Main/Config/ConfigManager.cs b/Main/Config/ConfigManager.cs
index 2852c9d..8dc9afe 100644
--- a/Main/Config/ConfigManager.cs
+++ b/Main/Config/ConfigManager.cs
@@ -45,6 +45,10 @@
             typeof(ActHeroReturnArtConfig),
             typeof(ActLunhuidianTypeConfig),
             typeof(ActSignAwardConfig),
+            typeof(ActSignConfig),
+            typeof(ActSpecialSaleConfig),
+            typeof(ActTaskConfig),
+            typeof(ActTaskTempConfig),
             typeof(ActTotalRechargeConfig),
             typeof(ActTotalRechargeTempConfig),
             typeof(ActTotDayRechargeConfig),
@@ -287,6 +291,14 @@
         ClearConfigDictionary<ActLunhuidianTypeConfig>();
         // 娓呯┖ ActSignAwardConfig 瀛楀吀
         ClearConfigDictionary<ActSignAwardConfig>();
+        // 娓呯┖ ActSignConfig 瀛楀吀
+        ClearConfigDictionary<ActSignConfig>();
+        // 娓呯┖ ActSpecialSaleConfig 瀛楀吀
+        ClearConfigDictionary<ActSpecialSaleConfig>();
+        // 娓呯┖ ActTaskConfig 瀛楀吀
+        ClearConfigDictionary<ActTaskConfig>();
+        // 娓呯┖ ActTaskTempConfig 瀛楀吀
+        ClearConfigDictionary<ActTaskTempConfig>();
         // 娓呯┖ ActTotalRechargeConfig 瀛楀吀
         ClearConfigDictionary<ActTotalRechargeConfig>();
         // 娓呯┖ ActTotalRechargeTempConfig 瀛楀吀
diff --git a/Main/Config/Configs/ActSignConfig.cs b/Main/Config/Configs/ActSignConfig.cs
new file mode 100644
index 0000000..9b58a27
--- /dev/null
+++ b/Main/Config/Configs/ActSignConfig.cs
@@ -0,0 +1,41 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           Tuesday, April 28, 2026
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class ActSignConfig : ConfigBase<int, ActSignConfig>
+{
+    static ActSignConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int CfgID;
+	public int SignTempID;
+
+    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 CfgID); 
+
+			int.TryParse(tables[1],out SignTempID); 
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/ActSignConfig.cs.meta b/Main/Config/Configs/ActSignConfig.cs.meta
new file mode 100644
index 0000000..50b4b82
--- /dev/null
+++ b/Main/Config/Configs/ActSignConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 28335628185079b4cae244317f179653
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/Configs/ActSpecialSaleConfig.cs b/Main/Config/Configs/ActSpecialSaleConfig.cs
new file mode 100644
index 0000000..94bf2ba
--- /dev/null
+++ b/Main/Config/Configs/ActSpecialSaleConfig.cs
@@ -0,0 +1,68 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           Tuesday, April 28, 2026
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class ActSpecialSaleConfig : ConfigBase<int, ActSpecialSaleConfig>
+{
+    static ActSpecialSaleConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int CfgID;
+	public int[] CTGIDList;
+	public int ActShopType;
+	public int ADID;
+	public int ShopType;
+	public int ShopItemID;
+	public int[][] PopItems;
+
+    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 CfgID); 
+
+			if (tables[1].Contains("["))
+			{
+				CTGIDList = JsonMapper.ToObject<int[]>(tables[1]);
+			}
+			else
+			{
+				string[] CTGIDListStringArray = tables[1].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				CTGIDList = new int[CTGIDListStringArray.Length];
+				for (int i=0;i<CTGIDListStringArray.Length;i++)
+				{
+					 int.TryParse(CTGIDListStringArray[i],out CTGIDList[i]);
+				}
+			}
+
+			int.TryParse(tables[2],out ActShopType); 
+
+			int.TryParse(tables[3],out ADID); 
+
+			int.TryParse(tables[4],out ShopType); 
+
+			int.TryParse(tables[5],out ShopItemID); 
+
+			PopItems = JsonMapper.ToObject<int[][]>(tables[6].Replace("(", "[").Replace(")", "]")); 
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/ActSpecialSaleConfig.cs.meta b/Main/Config/Configs/ActSpecialSaleConfig.cs.meta
new file mode 100644
index 0000000..47a71d6
--- /dev/null
+++ b/Main/Config/Configs/ActSpecialSaleConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fee90584a2c90bf429ad939a6a80973a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/Configs/ActTaskConfig.cs b/Main/Config/Configs/ActTaskConfig.cs
new file mode 100644
index 0000000..196da59
--- /dev/null
+++ b/Main/Config/Configs/ActTaskConfig.cs
@@ -0,0 +1,50 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           Tuesday, April 28, 2026
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class ActTaskConfig : ConfigBase<int, ActTaskConfig>
+{
+    static ActTaskConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int CfgID;
+	public int IsDayReset;
+	public int TemplateID;
+	public int ActScoreItemID;
+	public string ActScoreAwardInfo;
+
+    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 CfgID); 
+
+			int.TryParse(tables[1],out IsDayReset); 
+
+			int.TryParse(tables[2],out TemplateID); 
+
+			int.TryParse(tables[3],out ActScoreItemID); 
+
+			ActScoreAwardInfo = tables[4];
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/ActTaskConfig.cs.meta b/Main/Config/Configs/ActTaskConfig.cs.meta
new file mode 100644
index 0000000..6162e71
--- /dev/null
+++ b/Main/Config/Configs/ActTaskConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 18ccb33588d91924e929f132457591f2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/Configs/ActTaskTempConfig.cs b/Main/Config/Configs/ActTaskTempConfig.cs
new file mode 100644
index 0000000..d340282
--- /dev/null
+++ b/Main/Config/Configs/ActTaskTempConfig.cs
@@ -0,0 +1,56 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           2026骞�4鏈�28鏃�
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class ActTaskTempConfig : ConfigBase<int, ActTaskTempConfig>
+{
+    static ActTaskTempConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int ID;
+	public int TemplateID;
+	public int TasklD;
+	public int TaskType;
+	public int NeedValue;
+	public int[][] AwardItemList;
+	public int GuideID;
+
+    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 ID); 
+
+			int.TryParse(tables[1],out TemplateID); 
+
+			int.TryParse(tables[2],out TasklD); 
+
+			int.TryParse(tables[3],out TaskType); 
+
+			int.TryParse(tables[4],out NeedValue); 
+
+			AwardItemList = JsonMapper.ToObject<int[][]>(tables[5].Replace("(", "[").Replace(")", "]")); 
+
+			int.TryParse(tables[6],out GuideID); 
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/ActTaskTempConfig.cs.meta b/Main/Config/Configs/ActTaskTempConfig.cs.meta
new file mode 100644
index 0000000..c27b0cd
--- /dev/null
+++ b/Main/Config/Configs/ActTaskTempConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ec9a5f1c58db6994b8f558fc17c191d9
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/PartialConfigs/ActTaskTempConfig.cs b/Main/Config/PartialConfigs/ActTaskTempConfig.cs
new file mode 100644
index 0000000..915dfd5
--- /dev/null
+++ b/Main/Config/PartialConfigs/ActTaskTempConfig.cs
@@ -0,0 +1,63 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public partial class ActTaskTempConfig : ConfigBase<int, ActTaskTempConfig>
+{
+    public static Dictionary<int, List<ActTaskTempConfig>> templateIDToConfigsDict = new Dictionary<int, List<ActTaskTempConfig>>();
+
+    protected override void OnConfigParseCompleted()
+    {
+        if (!templateIDToConfigsDict.ContainsKey(TemplateID))
+        {
+            templateIDToConfigsDict[TemplateID] = new List<ActTaskTempConfig>();
+        }
+        templateIDToConfigsDict[TemplateID].Add(this);
+    }
+
+    public static List<ActTaskTempConfig> GetTemplateIDToConfigsDict(int templateID)
+    {
+        if (templateIDToConfigsDict.ContainsKey(templateID))
+        {
+            return templateIDToConfigsDict[templateID];
+        }
+        return null;
+    }
+
+    // 绱绉垎濂栧姳閰嶇疆
+    public class TotalScoreAwardConfig
+    {
+        public int needScore;      // 鎵�闇�绉垎
+        public int recordIndex;    // 璁板綍绱㈠紩
+        public int itemId;         // 濂栧姳鐗╁搧ID
+        public int itemCount;      // 濂栧姳鐗╁搧鏁伴噺
+    }
+
+    // 閫氳繃CfgID鑾峰彇绱绉垎濂栧姳鍒楄〃
+    public static List<TotalScoreAwardConfig> GetTotalScoreAwardListByCfgID(int cfgId)
+    {
+        var result = new List<TotalScoreAwardConfig>();
+        var config = ActTaskConfig.Get(cfgId);
+        if (config == null || string.IsNullOrEmpty(config.ActScoreAwardInfo) || config.ActScoreAwardInfo == "{}")
+        {
+            return result;
+        }
+
+
+        var dict = ConfigParse.ParseIntArrayDict(config.ActScoreAwardInfo);
+        foreach (var kvp in dict)
+        {
+            var arr = kvp.Value;
+            if (arr != null && arr.Length >= 3)
+            {
+                result.Add(new TotalScoreAwardConfig
+                {
+                    needScore = kvp.Key,
+                    recordIndex = arr[0],
+                    itemId = arr[1],
+                    itemCount = arr[2]
+                });
+            }
+        }
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/Main/Config/PartialConfigs/ActTaskTempConfig.cs.meta b/Main/Config/PartialConfigs/ActTaskTempConfig.cs.meta
new file mode 100644
index 0000000..afa5dca
--- /dev/null
+++ b/Main/Config/PartialConfigs/ActTaskTempConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0f7b949b0b810ea4b83d18d7d1113caf
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA10_tagSCActSpecialSaleInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA10_tagSCActSpecialSaleInfo.cs
new file mode 100644
index 0000000..75f4835
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA10_tagSCActSpecialSaleInfo.cs
@@ -0,0 +1,14 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 10 鐗瑰崠娲诲姩淇℃伅 #tagSCActSpecialSaleInfo
+
+public class DTCAA10_tagSCActSpecialSaleInfo : DtcBasic
+{
+    public override void Done(GameNetPackBasic vNetPack)
+    {
+        base.Done(vNetPack);
+        HAA10_tagSCActSpecialSaleInfo vNetData = vNetPack as HAA10_tagSCActSpecialSaleInfo;
+        OperationTimeHepler.Instance.UpdateFlashSaleActivityInfo(vNetData);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA10_tagSCActSpecialSaleInfo.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA10_tagSCActSpecialSaleInfo.cs.meta
new file mode 100644
index 0000000..4410fcf
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA10_tagSCActSpecialSaleInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 93050a26bbe6ce449a5021d8cdebc682
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA1A_tagSCActTotDayRechargePlayerInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA1A_tagSCActTotDayRechargePlayerInfo.cs
index 58c7e01..b263010 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA1A_tagSCActTotDayRechargePlayerInfo.cs
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA1A_tagSCActTotDayRechargePlayerInfo.cs
@@ -10,5 +10,6 @@
         base.Done(vNetPack);
         HAA1A_tagSCActTotDayRechargePlayerInfo vNetData = vNetPack as HAA1A_tagSCActTotDayRechargePlayerInfo;
         TotDayRechargeManager.Instance.UpdateTotDayRechargePlayerInfo(vNetData);
+        FestivalActivityRechargeTotDayManager.Instance.UpdateTotDayRechargePlayerInfo(vNetData);
     }
 }
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA1C_tagSCActTotalRechargePlayerInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA1C_tagSCActTotalRechargePlayerInfo.cs
index 15cb47b..28fd150 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA1C_tagSCActTotalRechargePlayerInfo.cs
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA1C_tagSCActTotalRechargePlayerInfo.cs
@@ -8,5 +8,6 @@
         base.Done(vNetPack);
         HAA1C_tagSCActTotalRechargePlayerInfo vNetData = vNetPack as HAA1C_tagSCActTotalRechargePlayerInfo;
         TotalRechargeManager.Instance.UpdateTotalRechargePlayerInfo(vNetData);
+        FestivalActivityRechargeTotalManager.Instance.UpdateTotalRechargePlayerInfo(vNetData);
     }
 }
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA23_tagSCActSignInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA23_tagSCActSignInfo.cs
new file mode 100644
index 0000000..9677e36
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA23_tagSCActSignInfo.cs
@@ -0,0 +1,14 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 23 绛惧埌娲诲姩淇℃伅 #tagSCActSignInfo
+
+public class DTCAA23_tagSCActSignInfo : DtcBasic
+{
+    public override void Done(GameNetPackBasic vNetPack)
+    {
+        base.Done(vNetPack);
+        HAA23_tagSCActSignInfo vNetData = vNetPack as HAA23_tagSCActSignInfo;
+        OperationTimeHepler.Instance.UpdateCheckInActivityInfo(vNetData);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA23_tagSCActSignInfo.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA23_tagSCActSignInfo.cs.meta
new file mode 100644
index 0000000..a94783c
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA23_tagSCActSignInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7b92c42956c922f4689fb3d005ccd63c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA71_tagSCActTaskInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA71_tagSCActTaskInfo.cs
new file mode 100644
index 0000000..a756868
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA71_tagSCActTaskInfo.cs
@@ -0,0 +1,12 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 71 浠诲姟娲诲姩淇℃伅 #tagSCActTaskInfo
+
+public class DTCAA71_tagSCActTaskInfo : DtcBasic {
+    public override void Done(GameNetPackBasic vNetPack) {
+        base.Done(vNetPack);
+        HAA71_tagSCActTaskInfo vNetData = vNetPack as HAA71_tagSCActTaskInfo;
+        OperationTimeHepler.Instance.UpdateMissionActivityInfo(vNetData);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA71_tagSCActTaskInfo.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA71_tagSCActTaskInfo.cs.meta
new file mode 100644
index 0000000..972addf
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA71_tagSCActTaskInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e5bfd63d84d04a64295b1e67df4182ba
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA72_tagSCActTaskPlayerValueInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA72_tagSCActTaskPlayerValueInfo.cs
new file mode 100644
index 0000000..2e80c04
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA72_tagSCActTaskPlayerValueInfo.cs
@@ -0,0 +1,12 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 72 浠诲姟娲诲姩鐜╁浠诲姟鍊� #tagSCActTaskPlayerValueInfo
+
+public class DTCAA72_tagSCActTaskPlayerValueInfo : DtcBasic {
+    public override void Done(GameNetPackBasic vNetPack) {
+        base.Done(vNetPack);
+        HAA72_tagSCActTaskPlayerValueInfo vNetData = vNetPack as HAA72_tagSCActTaskPlayerValueInfo;
+        FestivalActivityMissionManager.Instance.UpdatePlayerValueInfo(vNetData);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA72_tagSCActTaskPlayerValueInfo.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA72_tagSCActTaskPlayerValueInfo.cs.meta
new file mode 100644
index 0000000..f7dbefe
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA72_tagSCActTaskPlayerValueInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ff88da8b58bd357419087982180462a2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA73_tagSCActTaskPlayerInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA73_tagSCActTaskPlayerInfo.cs
new file mode 100644
index 0000000..9e6cda6
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA73_tagSCActTaskPlayerInfo.cs
@@ -0,0 +1,12 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 73 浠诲姟娲诲姩鐜╁淇℃伅 #tagSCActTaskPlayerInfo
+
+public class DTCAA73_tagSCActTaskPlayerInfo : DtcBasic {
+    public override void Done(GameNetPackBasic vNetPack) {
+        base.Done(vNetPack);
+        HAA73_tagSCActTaskPlayerInfo vNetData = vNetPack as HAA73_tagSCActTaskPlayerInfo;
+        FestivalActivityMissionManager.Instance.UpdatePlayerInfo(vNetData);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA73_tagSCActTaskPlayerInfo.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA73_tagSCActTaskPlayerInfo.cs.meta
new file mode 100644
index 0000000..afbbab7
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA73_tagSCActTaskPlayerInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2622ac73ea207bc41b42b0bea6da8886
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs b/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
index 270cccc..a02adb8 100644
--- a/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
+++ b/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
@@ -167,6 +167,11 @@
         Register(typeof(HAA1B_tagSCActTotDayRechargeInfo), typeof(DTCAA1B_tagSCActTotDayRechargeInfo));
         Register(typeof(HAA1C_tagSCActTotalRechargePlayerInfo), typeof(DTCAA1C_tagSCActTotalRechargePlayerInfo));
         Register(typeof(HAA1D_tagSCActTotalRechargeInfo), typeof(DTCAA1D_tagSCActTotalRechargeInfo));
+        Register(typeof(HAA10_tagSCActSpecialSaleInfo), typeof(DTCAA10_tagSCActSpecialSaleInfo));
+        Register(typeof(HAA23_tagSCActSignInfo), typeof(DTCAA23_tagSCActSignInfo));
+        Register(typeof(HAA71_tagSCActTaskInfo), typeof(DTCAA71_tagSCActTaskInfo));
+        Register(typeof(HAA72_tagSCActTaskPlayerValueInfo), typeof(DTCAA72_tagSCActTaskPlayerValueInfo));
+        Register(typeof(HAA73_tagSCActTaskPlayerInfo), typeof(DTCAA73_tagSCActTaskPlayerInfo));
     }
 
     //涓诲伐绋嬫敞鍐屽皝鍖�
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA10_tagSCActSpecialSaleInfo.cs b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA10_tagSCActSpecialSaleInfo.cs
new file mode 100644
index 0000000..4ae96a6
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA10_tagSCActSpecialSaleInfo.cs
@@ -0,0 +1,23 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 10 鐗瑰崠娲诲姩淇℃伅 #tagSCActSpecialSaleInfo
+
+public class HAA10_tagSCActSpecialSaleInfo : GameNetPackBasic {
+    public byte ActNum;    // 娲诲姩缂栧彿
+    public string StartDate;    // 寮�濮嬫棩鏈� y-m-d
+    public string EndtDate;    // 缁撴潫鏃ユ湡 y-m-d
+    public ushort CfgID;    // 娲诲姩鏃堕棿琛ㄩ厤缃甀D
+
+    public HAA10_tagSCActSpecialSaleInfo () {
+        _cmd = (ushort)0xAA10;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out ActNum, vBytes, NetDataType.BYTE);
+        TransBytes (out StartDate, vBytes, NetDataType.Chars, 10);
+        TransBytes (out EndtDate, vBytes, NetDataType.Chars, 10);
+        TransBytes (out CfgID, vBytes, NetDataType.WORD);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA10_tagSCActSpecialSaleInfo.cs.meta b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA10_tagSCActSpecialSaleInfo.cs.meta
new file mode 100644
index 0000000..5da34ee
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA10_tagSCActSpecialSaleInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0cedf55511caa534a998927e86ba2ac5
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA23_tagSCActSignInfo.cs b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA23_tagSCActSignInfo.cs
new file mode 100644
index 0000000..7d38872
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA23_tagSCActSignInfo.cs
@@ -0,0 +1,23 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 23 绛惧埌娲诲姩淇℃伅 #tagSCActSignInfo
+
+public class HAA23_tagSCActSignInfo : GameNetPackBasic {
+    public byte ActNum;    // 娲诲姩缂栧彿
+    public string StartDate;    // 寮�濮嬫棩鏈� y-m-d
+    public string EndtDate;    // 缁撴潫鏃ユ湡 y-m-d
+    public ushort CfgID;    // 娲诲姩鏃堕棿琛ㄩ厤缃甀D
+
+    public HAA23_tagSCActSignInfo () {
+        _cmd = (ushort)0xAA23;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out ActNum, vBytes, NetDataType.BYTE);
+        TransBytes (out StartDate, vBytes, NetDataType.Chars, 10);
+        TransBytes (out EndtDate, vBytes, NetDataType.Chars, 10);
+        TransBytes (out CfgID, vBytes, NetDataType.WORD);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA23_tagSCActSignInfo.cs.meta b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA23_tagSCActSignInfo.cs.meta
new file mode 100644
index 0000000..829d122
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA23_tagSCActSignInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e62482e93459c95489f5f137a1367382
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA71_tagSCActTaskInfo.cs b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA71_tagSCActTaskInfo.cs
new file mode 100644
index 0000000..6a5e0f0
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA71_tagSCActTaskInfo.cs
@@ -0,0 +1,23 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 71 浠诲姟娲诲姩淇℃伅 #tagSCActTaskInfo
+
+public class HAA71_tagSCActTaskInfo : GameNetPackBasic {
+    public byte ActNum;    // 娲诲姩缂栧彿
+    public string StartDate;    // 寮�濮嬫棩鏈� y-m-d
+    public string EndtDate;    // 缁撴潫鏃ユ湡 y-m-d
+    public ushort CfgID;    // 娲诲姩鏃堕棿琛ㄩ厤缃甀D
+
+    public HAA71_tagSCActTaskInfo () {
+        _cmd = (ushort)0xAA71;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out ActNum, vBytes, NetDataType.BYTE);
+        TransBytes (out StartDate, vBytes, NetDataType.Chars, 10);
+        TransBytes (out EndtDate, vBytes, NetDataType.Chars, 10);
+        TransBytes (out CfgID, vBytes, NetDataType.WORD);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA71_tagSCActTaskInfo.cs.meta b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA71_tagSCActTaskInfo.cs.meta
new file mode 100644
index 0000000..5d64d0d
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA71_tagSCActTaskInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 43a1369401f48644886a0ed6ead11c9a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA72_tagSCActTaskPlayerValueInfo.cs b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA72_tagSCActTaskPlayerValueInfo.cs
new file mode 100644
index 0000000..00c21f6
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA72_tagSCActTaskPlayerValueInfo.cs
@@ -0,0 +1,31 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 72 浠诲姟娲诲姩鐜╁浠诲姟鍊� #tagSCActTaskPlayerValueInfo
+
+public class HAA72_tagSCActTaskPlayerValueInfo : GameNetPackBasic {
+    public byte ActNum;    // 娲诲姩缂栧彿
+    public byte TaskCount;
+    public  tagSCActTaskPlayerValue[] TaskValueList;    // 鏈夊悓姝ョ殑浠诲姟绫诲瀷鐩存帴瑕嗙洊鍗冲彲
+
+    public HAA72_tagSCActTaskPlayerValueInfo () {
+        _cmd = (ushort)0xAA72;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out ActNum, vBytes, NetDataType.BYTE);
+        TransBytes (out TaskCount, vBytes, NetDataType.BYTE);
+        TaskValueList = new tagSCActTaskPlayerValue[TaskCount];
+        for (int i = 0; i < TaskCount; i ++) {
+            TaskValueList[i] = new tagSCActTaskPlayerValue();
+            TransBytes (out TaskValueList[i].TaskType, vBytes, NetDataType.BYTE);
+            TransBytes (out TaskValueList[i].TaskValue, vBytes, NetDataType.DWORD);
+        }
+    }
+
+    public class tagSCActTaskPlayerValue {
+        public byte TaskType;        // 浠诲姟绫诲瀷
+        public uint TaskValue;        // 褰撳墠浠诲姟鍊硷紝鎵�鏈夌浉鍚屼换鍔$被鍨嬪叡浜杩涘害鍊�
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA72_tagSCActTaskPlayerValueInfo.cs.meta b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA72_tagSCActTaskPlayerValueInfo.cs.meta
new file mode 100644
index 0000000..dbeeb58
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA72_tagSCActTaskPlayerValueInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e3ae0803689cf9c41a5e5fdf2674875a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA73_tagSCActTaskPlayerInfo.cs b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA73_tagSCActTaskPlayerInfo.cs
new file mode 100644
index 0000000..99b600f
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA73_tagSCActTaskPlayerInfo.cs
@@ -0,0 +1,25 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 73 浠诲姟娲诲姩鐜╁淇℃伅 #tagSCActTaskPlayerInfo
+
+public class HAA73_tagSCActTaskPlayerInfo : GameNetPackBasic {
+    public byte ActNum;    // 娲诲姩缂栧彿
+    public uint ActScoreTotal;    // 绱娲诲姩绉垎锛岀敤浜庨獙璇侀鍙栫疮璁$Н鍒嗗鍔辩敤锛屽晢搴楀厬鎹㈢洿鎺ョ敤鐗╁搧鍏戞崲鐗╁搧
+    public uint ActScoreAward;    // 绱娲诲姩绉垎棰嗗璁板綍锛屾寜濂栧姳绱㈠紩浣嶈繍绠楀垽鏂槸鍚﹀凡棰嗗彇
+    public byte AwardCount;
+    public  uint[] AwardRecordList;    // 浠诲姟ID棰嗗璁板綍鍊煎垪琛紝鏍规嵁浠诲姟ID浣嶅垽鏂槸鍚﹀凡棰嗗彇锛屼竴涓褰曞�煎瓨31浣� [璁板綍鍊�0, 璁板綍鍊�1, ...]
+
+    public HAA73_tagSCActTaskPlayerInfo () {
+        _cmd = (ushort)0xAA73;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out ActNum, vBytes, NetDataType.BYTE);
+        TransBytes (out ActScoreTotal, vBytes, NetDataType.DWORD);
+        TransBytes (out ActScoreAward, vBytes, NetDataType.DWORD);
+        TransBytes (out AwardCount, vBytes, NetDataType.BYTE);
+        TransBytes (out AwardRecordList, vBytes, NetDataType.DWORD, AwardCount);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA73_tagSCActTaskPlayerInfo.cs.meta b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA73_tagSCActTaskPlayerInfo.cs.meta
new file mode 100644
index 0000000..267ed65
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA73_tagSCActTaskPlayerInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 822917aa36513164eaa88bab3498a208
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Main.cs b/Main/Main.cs
index 424a388..7c58da3 100644
--- a/Main/Main.cs
+++ b/Main/Main.cs
@@ -117,7 +117,11 @@
         managers.Add(CrossServerBaseManager.Instance);
         managers.Add(TotalRechargeManager.Instance);
         managers.Add(TotDayRechargeManager.Instance);
-
+        managers.Add(FestivalActivityManager.Instance);
+        managers.Add(FestivalActivityRechargeTotalManager.Instance);
+        managers.Add(FestivalActivityRechargeTotDayManager.Instance);
+        managers.Add(FestivalActivityCheckInManager.Instance);
+        managers.Add(FestivalActivityMissionManager.Instance);
 
         foreach (var manager in managers)
         {
diff --git a/Main/System/BoneField/AdsManager.cs b/Main/System/BoneField/AdsManager.cs
index 45afd4b..439d04a 100644
--- a/Main/System/BoneField/AdsManager.cs
+++ b/Main/System/BoneField/AdsManager.cs
@@ -189,6 +189,9 @@
             case 6:
                 SendGetReward(ADID);
                 break;
+            case 7:
+                SendGetReward(ADID);
+                break;
 
         }
     }
diff --git a/Main/System/FestivalActivity.meta b/Main/System/FestivalActivity.meta
new file mode 100644
index 0000000..e2902c7
--- /dev/null
+++ b/Main/System/FestivalActivity.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 5533b52633741964d91069149670dd58
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityCheckInCell.cs b/Main/System/FestivalActivity/FestivalActivityCheckInCell.cs
new file mode 100644
index 0000000..8582b5e
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityCheckInCell.cs
@@ -0,0 +1,60 @@
+using UnityEngine;
+
+public class FestivalActivityCheckInCell : MonoBehaviour
+{
+    [SerializeField] ButtonEx clickButton;
+    [SerializeField] ImageEx bgImage;
+    [SerializeField] TextEx dayText;
+    [SerializeField] TextEx itemNameText;
+    [SerializeField] ItemCell itemCell;
+    [SerializeField] UIEffectPlayer uiEffectPlayer;
+    [SerializeField] Transform imgMask;
+
+    FestivalActivityCheckInManager manager => FestivalActivityCheckInManager.Instance;
+
+    private int currentItemId;
+    private int currentState;
+
+    public void Display(int templateID, int dayNum)
+    {
+        uiEffectPlayer.Stop();
+
+        var config = ActSignAwardConfig.GetConfig(templateID, dayNum);
+        if (config == null) return;
+        if (config.SignAwardItemList.IsNullOrEmpty()) return;
+
+        currentItemId = config.SignAwardItemList[0][0];
+        int count = config.SignAwardItemList[0][1];
+
+        var itemConfig = ItemConfig.Get(currentItemId);
+        if (itemConfig == null) return;
+
+        currentState = manager.GetCheckInState(dayNum);
+        imgMask.SetActive(currentState == 2);
+        bgImage.SetSprite(currentState == 1 ? "HeroDebutCheckInDayBG1" : "HeroDebutCheckInDayBG2");
+        if (currentState == 1)
+        {
+            uiEffectPlayer.Play();
+        }
+
+        dayText.text = Language.Get($"SignDay{dayNum}");
+        itemNameText.text = itemConfig.ItemName;
+
+        itemCell.Init(new ItemCellModel(currentItemId, false, count));
+        itemCell.button.AddListener(OnItemClicked);
+
+        clickButton.SetListener(() => manager.SendGetCheckInReward());
+    }
+
+    private void OnItemClicked()
+    {
+        if (currentState == 1)
+        {
+            manager.SendGetCheckInReward();
+        }
+        else
+        {
+            ItemTipUtility.Show(currentItemId);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/System/FestivalActivity/FestivalActivityCheckInCell.cs.meta b/Main/System/FestivalActivity/FestivalActivityCheckInCell.cs.meta
new file mode 100644
index 0000000..d20e360
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityCheckInCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 466abe185fe4c1e4bbd404360dfe9e42
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityCheckInManager.cs b/Main/System/FestivalActivity/FestivalActivityCheckInManager.cs
new file mode 100644
index 0000000..26e4a0f
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityCheckInManager.cs
@@ -0,0 +1,191 @@
+using System;
+
+public class FestivalActivityCheckInManager : GameSystemManager<FestivalActivityCheckInManager>, IOpenServerActivity
+{
+    public readonly int ActNum = 30;
+
+    public override void Init()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
+        OperationTimeHepler.Instance.operationTimeUpdateEvent += OperationTimeUpdateEvent;
+        OperationTimeHepler.Instance.operationStartEvent += OperationStartEvent;
+        OperationTimeHepler.Instance.operationEndEvent += OperationEndEvent;
+        OperationTimeHepler.Instance.operationAdvanceEvent += OperationAdvanceEvent;
+        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
+        GeneralActInfoManager.Instance.OnUpdateActSignInfosEvent += OnUpdateActSignInfosEvent;
+        TimeMgr.Instance.OnDayEvent += OnDayEvent;
+    }
+
+    public override void Release()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin;
+        OperationTimeHepler.Instance.operationTimeUpdateEvent -= OperationTimeUpdateEvent;
+        OperationTimeHepler.Instance.operationStartEvent -= OperationStartEvent;
+        OperationTimeHepler.Instance.operationEndEvent -= OperationEndEvent;
+        OperationTimeHepler.Instance.operationAdvanceEvent -= OperationAdvanceEvent;
+        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
+        GeneralActInfoManager.Instance.OnUpdateActSignInfosEvent -= OnUpdateActSignInfosEvent;
+        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
+    }
+
+    private void OnBeforePlayerDataInitializeEventOnRelogin()
+    {
+    }
+
+    private void OnDayEvent()
+    {
+        UpdateRedPoint();
+    }
+
+    private void OnUpdateActSignInfosEvent(int arg1, int arg2)
+    {
+        UpdateRedPoint();
+    }
+
+    private void OnFuncStateChangeEvent(int obj)
+    {
+        if (obj != (int)FuncOpenEnum.FestivalActivity)
+            return;
+        UpdateRedPoint();
+    }
+
+    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
+    public const int activityID = (int)NewDayActivityID.FestivalActivityCheckInAct;
+    public static OperationType operaType = OperationType.FestivalActivity_CheckIn;
+
+    public Redpoint redPoint = new Redpoint(MainRedDot.FestivalActivityRepoint,
+        FestivalActivityManager.Instance.GetRedPointId(FestivalActivityRepointType.CheckIn));
+
+    public bool IsOpen => OperationTimeHepler.Instance.SatisfyOpenCondition(operaType);
+    public bool IsAdvance => OperationTimeHepler.Instance.SatisfyAdvanceCondition(operaType);
+    public bool priorityOpen => redPoint.state == RedPointState.Simple;
+    public event Action<int> onStateUpdate;
+
+    private void OperationTimeUpdateEvent(OperationType type)
+    {
+        if (type == operaType)
+        {
+            UpdateRedPoint();
+        }
+    }
+
+    private void OperationStartEvent(OperationType type, int state)
+    {
+        if (type == operaType && state == 0)
+        {
+            UpdateRedPoint();
+            onStateUpdate?.Invoke(activityID);
+        }
+    }
+
+    private void OperationEndEvent(OperationType type, int state)
+    {
+        if (type == operaType)
+        {
+            UpdateRedPoint();
+            onStateUpdate?.Invoke(activityID);
+        }
+    }
+
+    private void OperationAdvanceEvent(OperationType type)
+    {
+        if (type == operaType)
+        {
+            UpdateRedPoint();
+            onStateUpdate?.Invoke(activityID);
+        }
+    }
+
+    public void UpdateRedPoint()
+    {
+        redPoint.state = RedPointState.None;
+        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.FestivalActivity))
+            return;
+        if (!IsOpen)
+            return;
+
+        if (HasCheckInCanHave())
+        {
+            redPoint.state = RedPointState.Simple;
+        }
+    }
+
+    public OperationCheckInActivityInfo GetOperationCheckInInfo()
+    {
+        OperationTimeHepler.Instance.TryGetOperation(operaType, out OperationCheckInActivityInfo act);
+        return act;
+    }
+
+    public bool GetActInfo(out OperationCheckInActivityInfo act, out ActSignConfig config)
+    {
+        config = null;
+        act = GetOperationCheckInInfo();
+        if (act == null)
+            return false;
+        config = ActSignConfig.Get(act.CfgID);
+        return config != null;
+    }
+
+    private int GetNowDayNum()
+    {
+        var act = GetOperationCheckInInfo();
+        if (act == null) return 0;
+
+        int dayNum = act.IndexOfDays(TimeUtility.ServerNow);
+        return dayNum < 0 ? 0 : dayNum + 1;
+    }
+
+    private bool IsCheckInGridUnlock(int gridDayNum)
+    {
+        int nowDayNum = GetNowDayNum();
+        if (nowDayNum <= 0) return false;
+
+        return nowDayNum >= gridDayNum;
+    }
+
+    /// <summary>
+    /// 0-鏈В閿� 1-鍙 2-宸茬
+    /// </summary>
+    public int GetCheckInState(int gridDayNum)
+    {
+        // 绛惧埌娲诲姩鐨凙ctType榛樿涓�0
+        if (GeneralActInfoManager.Instance.IsDaySigned(0, ActNum, gridDayNum)) return 2;
+        if (IsCheckInGridUnlock(gridDayNum)) return 1;
+        return 0;
+    }
+
+    public void SendGetCheckInReward()
+    {
+        // 绛惧埌娲诲姩鐨凙ctType榛樿涓�0
+        GeneralActInfoManager.Instance.SendGetSignReward(0, ActNum);
+    }
+
+    public bool HasCheckInCanHave()
+    {
+        if (!GetActInfo(out var act, out var config))
+            return false;
+
+        int templateID = config.SignTempID;
+        var list = ActSignAwardConfig.GetDayNumSortList(templateID);
+        if (list == null) return false;
+
+        for (int i = 0; i < list.Count; i++)
+        {
+            int dayNum = list[i];
+            int state = GetCheckInState(dayNum);
+            if (state == 1) return true;
+        }
+        return false;
+    }
+
+    public void GetActTimeStr(TextEx timeText, string key = "TimeRush05")
+    {
+        var act = GetOperationCheckInInfo();
+        if (act == null)
+        {
+            timeText.text = Language.Get("OSActivity6");
+            return;
+        }
+        timeText.text = Language.Get(key, TimeUtility.SecondsToShortDHMS(act.GetResetSurplusTime()));
+    }
+}
\ No newline at end of file
diff --git a/Main/System/FestivalActivity/FestivalActivityCheckInManager.cs.meta b/Main/System/FestivalActivity/FestivalActivityCheckInManager.cs.meta
new file mode 100644
index 0000000..d2fa745
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityCheckInManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 36e836fe2fdb08041955a6e15c6346ef
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityCheckInWin.cs b/Main/System/FestivalActivity/FestivalActivityCheckInWin.cs
new file mode 100644
index 0000000..5880a8d
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityCheckInWin.cs
@@ -0,0 +1,63 @@
+using UnityEngine;
+
+public class FestivalActivityCheckInWin : UIBase
+{
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] TextEx timeText;
+    [SerializeField] FestivalActivityCheckInCell[] cells;
+    FestivalActivityCheckInManager manager => FestivalActivityCheckInManager.Instance;
+    protected override void InitComponent()
+    {
+        closeButton.SetListener(CloseWindow);
+    }
+    protected override void OnPreOpen()
+    {
+        GeneralActInfoManager.Instance.OnUpdateActSignInfosEvent += OnUpdateActSignInfosEvent;
+        TimeMgr.Instance.OnDayEvent += OnDayEvent;
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        Display();
+    }
+    protected override void OnPreClose()
+    {
+        GeneralActInfoManager.Instance.OnUpdateActSignInfosEvent -= OnUpdateActSignInfosEvent;
+        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+    }
+    private void OnDayEvent()
+    {
+        Display();
+    }
+    private void OnUpdateActSignInfosEvent(int arg1, int arg2)
+    {
+        Display();
+    }
+
+    private void OnSecondEvent()
+    {
+        manager.GetActTimeStr(timeText);
+    }
+    private void Display()
+    {
+        if (!manager.GetActInfo(out var act, out var config))
+            return;
+
+        int templateID = config.SignTempID;
+        var list = ActSignAwardConfig.GetDayNumSortList(templateID);
+        if (list == null) return;
+
+        for (int i = 0; i < cells.Length; i++)
+        {
+            if (i < list.Count)
+            {
+                cells[i].SetActive(true);
+                cells[i].Display(templateID, list[i]);
+            }
+            else
+            {
+                cells[i].SetActive(false);
+            }
+        }
+
+        OnSecondEvent();
+    }
+}
\ No newline at end of file
diff --git a/Main/System/FestivalActivity/FestivalActivityCheckInWin.cs.meta b/Main/System/FestivalActivity/FestivalActivityCheckInWin.cs.meta
new file mode 100644
index 0000000..c75b84e
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityCheckInWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a837dc5f21722df49bca4419569b24bb
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityGiftCell.cs b/Main/System/FestivalActivity/FestivalActivityGiftCell.cs
new file mode 100644
index 0000000..c799d16
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityGiftCell.cs
@@ -0,0 +1,227 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class FestivalActivityGiftCell : MonoBehaviour
+{
+    [SerializeField] ImageEx vipImage;
+    [SerializeField] TextEx vipText;
+    [SerializeField] OutlineEx vipTextOutline;
+    [SerializeField] ImageEx rateImage;
+    [SerializeField] TextEx rateText;
+
+    [SerializeField] ItemCell[] itemCells;
+    [SerializeField] TextEx titleText;
+    [SerializeField] ButtonEx buyButton;
+    [SerializeField] ImageEx buyImage;
+
+    [SerializeField] TextEx buyText;
+    [SerializeField] TextEx buyText1;
+    [SerializeField] ImageEx moneyIconImage;
+    [SerializeField] ImageEx adImage;
+    [SerializeField] TextEx limitCountText;
+    [SerializeField] ImageEx redImage;
+    FestivalActivityManager manager => FestivalActivityManager.Instance;
+    StoreModel storeModel => StoreModel.Instance;
+
+    public void Display(int index, List<FestivalActivityGiftItem> giftItems)
+    {
+        if (giftItems.IsNullOrEmpty() || index < 0 || index >= giftItems.Count) return;
+
+        FestivalActivityGiftItem item = giftItems[index];
+        if (item.type == 0)
+        {
+            DisplayStore(item.id);
+            return;
+        }
+
+        if (item.type == 1)
+        {
+            DisplayAD(item.id);
+            return;
+        }
+
+
+        DisplayCTG(item.id);
+    }
+
+    private void DisplayCTG(int ctgId)
+    {
+        redImage.SetActive(false);
+        buyText.SetActive(true);
+        buyText1.SetActive(false);
+        moneyIconImage.SetActive(false);
+        adImage.SetActive(false);
+        rateImage.SetActive(true);
+
+        if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderConfig)) return;
+        if (!RechargeManager.Instance.TryGetRechargeCount(ctgId, out var rechargeCount)) return;
+        if (!CTGConfig.HasKey(ctgId)) return;
+        if (!RechargeManager.Instance.TryGetRechargeItem(ctgId, out var rechargeItemList)) return;
+
+        CTGConfig config = CTGConfig.Get(ctgId);
+        vipImage.SetActive(config.VipLevel > 0);
+        if (config.VipLevel > 0)
+        {
+            vipImage.SetSprite($"VipLevel{config.VipLevel}");
+            vipText.text = Language.Get($"VipLevelInfo{config.VipLevel}");
+            vipText.color = InvestModel.Instance.GetTextColor(config.VipLevel);
+            vipTextOutline.OutlineColor = InvestModel.Instance.GetOutlineColor(config.VipLevel);
+        }
+
+        rateImage.SetActive(true);
+        rateText.text = Language.Get("DailySpecials07", config.Percentage);
+
+        bool isCanBuy = manager.IsCanBuy(ctgId, out bool isNoLimitBuy, out int nowBuyCnt, out int maxBuyCnt);
+        titleText.text = config.Title;
+        buyImage.SetSprite(isCanBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2");
+        buyText.text = !isCanBuy ? Language.Get("storename11") : Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.PayRMBNumOnSale));
+        limitCountText.SetActive(!isNoLimitBuy && maxBuyCnt > 0);
+        if (!isNoLimitBuy && maxBuyCnt > 0)
+        {
+            limitCountText.text = Language.Get("HeroDebut39", UIHelper.AppendColor(nowBuyCnt >= maxBuyCnt ? TextColType.Red : TextColType.LightGreen, Mathf.Max(0, maxBuyCnt - nowBuyCnt).ToString()));
+        }
+        buyButton.interactable = isCanBuy;
+        buyButton.SetListener(() =>
+        {
+            if (config.VipLevel > 0 && !FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.PrivilegeCard))
+            {
+                SysNotifyMgr.Instance.ShowTip("MinggeAuto8");
+                return;
+            }
+            if (config.VipLevel == 1 && !InvestModel.Instance.IsInvested(InvestModel.monthCardType))
+            {
+                SysNotifyMgr.Instance.ShowTip("MinggeAuto5");
+                UIManager.Instance.OpenWindow<PrivilegeCardWin>();
+                return;
+            }
+            if (config.VipLevel == 2 && !InvestModel.Instance.IsInvested(InvestModel.foreverCardType))
+            {
+                SysNotifyMgr.Instance.ShowTip("MinggeAuto7");
+                UIManager.Instance.OpenWindow<PrivilegeCardWin>();
+                return;
+            }
+            RechargeManager.Instance.CTG(ctgId);
+        });
+
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            var itemBaisc = itemCells[i];
+            if (i < rechargeItemList.Count)
+            {
+                var itemInfo = rechargeItemList[i];
+                itemBaisc.SetActive(true);
+                itemBaisc.Init(new ItemCellModel((int)itemInfo.id, false, itemInfo.countEx));
+                itemBaisc.button.AddListener(() =>
+                {
+                    ItemTipUtility.Show((int)itemInfo.id);
+                });
+            }
+            else
+            {
+                itemBaisc.SetActive(false);
+            }
+        }
+    }
+
+    private void DisplayStore(int id)
+    {
+        rateImage.SetActive(false);
+        vipImage.SetActive(false);
+        if (!StoreConfig.HasKey(id)) return;
+
+        StoreConfig storeConfig = StoreConfig.Get(id);
+        int remainNum;
+        storeModel.TryGetIsSellOut(storeConfig, out remainNum);
+
+        bool isFree = manager.IsFreeShop(id);
+        titleText.text = storeConfig.Name;
+
+        limitCountText.SetActive(!isFree);
+        limitCountText.text = Language.Get("HeroDebut39", UIHelper.AppendColor(remainNum == 0 ? TextColType.Red : TextColType.LightGreen, Mathf.Max(0, remainNum).ToString(), true));
+
+        bool isCanBuy = manager.IsNoSellOutShopID(id);
+
+        redImage.SetActive(isFree && isCanBuy);
+        buyText.SetActive(isFree || !isCanBuy);
+        buyText.text = isFree ? Language.Get("L1127") : Language.Get("storename11");
+        buyText1.SetActive(!isFree && isCanBuy);
+        buyText1.text = UIHelper.GetMoneyFormat(storeConfig.MoneyNum);
+        adImage.SetActive(false);
+        moneyIconImage.SetActive(!isFree && isCanBuy);
+        moneyIconImage.SetIconWithMoneyType(1);
+        buyImage.SetSprite(isCanBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2");
+        buyButton.interactable = isCanBuy;
+        buyButton.SetListener(() =>
+        {
+            storeModel.SendBuyShopItemWithPopCheck(storeConfig, 1, (int)BuyStoreItemCheckType.ActGift);
+        });
+
+        var items = storeModel.GetShopItemlistByIndex(storeConfig);
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            var itemBaisc = itemCells[i];
+            if (i < items.Count)
+            {
+                var itemInfo = items[i];
+                itemBaisc.SetActive(true);
+                itemBaisc.Init(new ItemCellModel(itemInfo.itemId, false, itemInfo.count));
+                itemBaisc.button.AddListener(() =>
+                {
+                    ItemTipUtility.Show(itemInfo.itemId);
+                });
+            }
+            else
+            {
+                itemBaisc.SetActive(false);
+            }
+        }
+    }
+
+    private void DisplayAD(int ADID)
+    {
+        rateImage.SetActive(false);
+        vipImage.SetActive(false);
+
+        ADAwardConfig config = ADAwardConfig.Get(ADID);
+        if (config == null) return;
+        bool isCanBuy = manager.IsAdAwardCanReceive(ADID);
+        int receivedCnt = AdsManager.Instance.GetADCntByADID(ADID);
+
+        titleText.text = config.Name;
+        limitCountText.SetActive(true);
+        limitCountText.text = Language.Get("HeroDebut39", UIHelper.AppendColor(!isCanBuy ? TextColType.Red : TextColType.LightGreen, Mathf.Max(config.ADCntMax - receivedCnt, 0).ToString()));
+        redImage.SetActive(isCanBuy);
+        buyText.SetActive(false);
+        buyText1.SetActive(true);
+        buyText1.text = Language.Get("L1127");
+        moneyIconImage.SetActive(false);
+        adImage.SetActive(true);
+        adImage.gray = !isCanBuy;
+        buyImage.SetSprite(isCanBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2");
+        buyButton.interactable = isCanBuy;
+        buyButton.SetListener(() =>
+        {
+            AdsManager.Instance.GetAdsAward(ADID);
+        });
+
+        var items = config.ADAwardItemList;
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            var itemBaisc = itemCells[i];
+            if (i < items.Length)
+            {
+                var itemInfo = items[i];
+                itemBaisc.SetActive(true);
+                itemBaisc.Init(new ItemCellModel(itemInfo[0], false, itemInfo[1]));
+                itemBaisc.button.AddListener(() =>
+                {
+                    ItemTipUtility.Show(itemInfo[0]);
+                });
+            }
+            else
+            {
+                itemBaisc.SetActive(false);
+            }
+        }
+    }
+}
diff --git a/Main/System/FestivalActivity/FestivalActivityGiftCell.cs.meta b/Main/System/FestivalActivity/FestivalActivityGiftCell.cs.meta
new file mode 100644
index 0000000..6969ef2
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityGiftCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: cce6bd2f32961ec42b60c48e47665255
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityGiftWin.cs b/Main/System/FestivalActivity/FestivalActivityGiftWin.cs
new file mode 100644
index 0000000..24be001
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityGiftWin.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class FestivalActivityGiftWin : UIBase
+{
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] ScrollerController scroller;
+    [SerializeField] TextEx timeText;
+    FestivalActivityManager manager => FestivalActivityManager.Instance;
+    StoreModel storeModel => StoreModel.Instance;
+    protected override void InitComponent()
+    {
+        closeButton.SetListener(CloseWindow);
+    }
+
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent;
+        storeModel.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent;
+        AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdateEvent;
+        CreateGiftScroller();
+        OnSecondEvent();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+        RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent;
+        storeModel.RefreshBuyShopLimitEvent -= RefreshBuyShopLimitEvent;
+        AdsManager.Instance.OnAdsInfoListUpdateEvent -= OnAdsInfoListUpdateEvent;
+    }
+
+    private void OnAdsInfoListUpdateEvent(int arg1, int arg2, int arg3)
+    {
+        RefreshAll();
+    }
+
+    private void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<FestivalActivityGiftCell>();
+        _cell?.Display(cell.index, giftItems);
+    }
+
+    private void OnSecondEvent()
+    {
+        manager.GetActTimeStr(timeText);
+    }
+
+    private void OnRechargeCountEvent(int obj)
+    {
+        RefreshAll();
+    }
+
+    private void RefreshBuyShopLimitEvent()
+    {
+        RefreshAll();
+    }
+
+    List<FestivalActivityGiftItem> giftItems;
+    private void CreateGiftScroller()
+    {
+        giftItems = manager.GetGiftItemList(true);
+        scroller.Refresh();
+        if (!giftItems.IsNullOrEmpty())
+        {
+            for (int i = 0; i < giftItems.Count; i++)
+            {
+                scroller.AddCell(ScrollerDataType.Header, i);
+            }
+        }
+        scroller.Restart();
+    }
+
+    void RefreshAll()
+    {
+        scroller.m_Scorller.RefreshActiveCellViews();
+    }
+}
diff --git a/Main/System/FestivalActivity/FestivalActivityGiftWin.cs.meta b/Main/System/FestivalActivity/FestivalActivityGiftWin.cs.meta
new file mode 100644
index 0000000..e5aa9f3
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityGiftWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 030c0370cba35da49bde2e5b27d0c437
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityManager.cs b/Main/System/FestivalActivity/FestivalActivityManager.cs
new file mode 100644
index 0000000..419385e
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityManager.cs
@@ -0,0 +1,502 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+public class FestivalActivityManager : GameSystemManager<FestivalActivityManager>, IOpenServerActivity
+{
+    public override void Init()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
+        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk;
+        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
+        OperationTimeHepler.Instance.operationTimeUpdateEvent += OperationTimeUpdateEvent;
+        OperationTimeHepler.Instance.operationStartEvent += OperationStartEvent;
+        OperationTimeHepler.Instance.operationEndEvent += OperationEndEvent;
+        OperationTimeHepler.Instance.operationAdvanceEvent += OperationAdvanceEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += RefreshBuyShopLimitEvent;
+        GeneralActInfoManager.Instance.OnUpdateActSignInfosEvent += OnUpdateActSignInfosEvent;
+        HeroManager.Instance.onHeroChangeEvent += OnHeroChangeEvent;
+        TimeMgr.Instance.OnDayEvent += OnDayEvent;
+        AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdateEvent;
+        InitRedPointId();
+
+    }
+
+    public override void Release()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin;
+        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk;
+        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
+        OperationTimeHepler.Instance.operationTimeUpdateEvent -= OperationTimeUpdateEvent;
+        OperationTimeHepler.Instance.operationStartEvent -= OperationStartEvent;
+        OperationTimeHepler.Instance.operationEndEvent -= OperationEndEvent;
+        OperationTimeHepler.Instance.operationAdvanceEvent -= OperationAdvanceEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= RefreshBuyShopLimitEvent;
+        GeneralActInfoManager.Instance.OnUpdateActSignInfosEvent -= OnUpdateActSignInfosEvent;
+        HeroManager.Instance.onHeroChangeEvent -= OnHeroChangeEvent;
+        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
+        AdsManager.Instance.OnAdsInfoListUpdateEvent -= OnAdsInfoListUpdateEvent;
+    }
+
+    private void OnAdsInfoListUpdateEvent(int arg1, int arg2, int arg3)
+    {
+        UpdateRedpoint();
+    }
+
+    private void OnDayEvent()
+    {
+        UpdateRedpoint();
+    }
+
+    private void OnHeroChangeEvent(HeroInfo info)
+    {
+        UpdateRedpoint();
+    }
+
+    private void OnUpdateActSignInfosEvent(int arg1, int arg2)
+    {
+        UpdateRedpoint();
+    }
+
+    private void RefreshBuyShopLimitEvent()
+    {
+        UpdateRedpoint();
+    }
+
+    private void OnBeforePlayerDataInitializeEventOnRelogin()
+    {
+
+    }
+
+    private void OnPlayerLoginOk()
+    {
+        TryPopWin();
+    }
+
+    private void OnFuncStateChangeEvent(int obj)
+    {
+        if (obj != (int)FuncOpenEnum.HeroDebut)
+            return;
+        TryPopWin();
+    }
+
+    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
+    public const int activityID = (int)NewDayActivityID.FestivalActivityAct;
+    public static OperationType operaType = OperationType.FestivalActivity;
+    public Redpoint redPoint = new Redpoint(MainRedDot.FestivalActivityRepoint);
+
+    public bool IsOpen => OperationTimeHepler.Instance.SatisfyOpenCondition(operaType);
+
+    public bool IsAdvance => OperationTimeHepler.Instance.SatisfyAdvanceCondition(operaType);
+
+    public bool priorityOpen => redPoint.state == RedPointState.Simple;
+    public readonly int actNum = 30;
+    public event Action<int> onStateUpdate;
+
+    private void OperationTimeUpdateEvent(OperationType type)
+    {
+        if (type == operaType)
+        {
+            if (UIManager.Instance.IsOpened<FestivalActivityPopWin>())
+                UIManager.Instance.CloseWindow<FestivalActivityPopWin>();
+            if (UIManager.Instance.IsOpened<FestivalActivityWin>())
+                UIManager.Instance.CloseWindow<FestivalActivityWin>();
+            UpdateRedpoint();
+        }
+    }
+
+    private void OperationStartEvent(OperationType type, int state)
+    {
+        if (type == operaType && state == 0)
+        {
+            onStateUpdate?.Invoke(activityID);
+            TryPopWin();
+            UpdateRedpoint();
+        }
+    }
+
+    private void OperationEndEvent(OperationType type, int state)
+    {
+        if (type == operaType)
+        {
+            onStateUpdate?.Invoke(activityID);
+            if (UIManager.Instance.IsOpened<FestivalActivityPopWin>())
+                UIManager.Instance.CloseWindow<FestivalActivityPopWin>();
+            if (UIManager.Instance.IsOpened<FestivalActivityWin>())
+                UIManager.Instance.CloseWindow<FestivalActivityWin>();
+            UpdateRedpoint();
+        }
+    }
+    private void OperationAdvanceEvent(OperationType type)
+    {
+        if (type == operaType)
+        {
+            onStateUpdate?.Invoke(activityID);
+            UpdateRedpoint();
+        }
+    }
+
+    public OperationFlashSaleActivityInfo GetActInfo()
+    {
+        OperationTimeHepler.Instance.TryGetOperation(operaType, out OperationFlashSaleActivityInfo act);
+        return act;
+    }
+    #region 绾㈢偣
+    public int GetRedPointId(FestivalActivityRepointType type)
+    {
+        return MainRedDot.FestivalActivityRepoint * 10 + (int)type;
+    }
+
+    public Redpoint shopRedpoint;
+    public Redpoint giftRedpoint;
+    public Redpoint rechargeRedpoint;
+    public void InitRedPointId()
+    {
+        shopRedpoint ??= new Redpoint(MainRedDot.FestivalActivityRepoint, GetRedPointId(FestivalActivityRepointType.Shop));
+        giftRedpoint ??= new Redpoint(MainRedDot.FestivalActivityRepoint, GetRedPointId(FestivalActivityRepointType.Gift));
+        rechargeRedpoint ??= new Redpoint(MainRedDot.FestivalActivityRepoint, GetRedPointId(FestivalActivityRepointType.Recharge));
+    }
+
+    public void UpdateRedpoint()
+    {
+        redPoint.state = RedPointState.None;
+        shopRedpoint.state = RedPointState.None;
+        giftRedpoint.state = RedPointState.None;
+
+        if (ShowShopRedpoint())//鍟嗗簵
+            shopRedpoint.state = RedPointState.Simple;
+
+        if (HasGiftCanHave())//绀煎寘
+            giftRedpoint.state = RedPointState.Simple;
+    }
+    #endregion
+    #region 鎷嶈劯鐣岄潰
+    public bool IsTodayPop
+    {
+        get
+        {
+            int lastPopTime = LoadPopTimeData();
+            int todayStartTime = TimeUtility.GetTodayStartTick();
+            return lastPopTime < todayStartTime;
+        }
+    }
+    private string PopTimeDataKey { get { return $"FestivalActivityManager_PopTimeData_{PlayerDatas.Instance.PlayerId}"; } }
+
+    private int LoadPopTimeData()
+    {
+        return LocalSave.GetInt(PopTimeDataKey);
+    }
+
+    public void SavePopTimeData()
+    {
+        LocalSave.SetInt(PopTimeDataKey, TimeUtility.AllSeconds);
+    }
+
+    public void ClearPopTimeData()
+    {
+        LocalSave.SetInt(PopTimeDataKey, 0);
+    }
+
+    private void TryPopWin()
+    {
+        if (!IsFestivalActivityOpen()) return;
+        if (!IsTodayPop) return;
+        if (UIManager.Instance.IsOpened<FestivalActivityPopWin>()) return;
+        if (UIManager.Instance.IsOpened<FestivalActivityWin>()) return;
+        PopupWindowsProcessor.Instance.Add("FestivalActivityPopWin");
+    }
+    #endregion
+
+
+    public void GetActTimeStr(TextEx timeText, string key = "TimeRush05")
+    {
+        var act = GetActInfo();
+        if (act == null)
+        {
+            timeText.text = Language.Get("OSActivity6");
+            return;
+        }
+        timeText.text = Language.Get(key, TimeUtility.SecondsToShortDHMS(act.GetResetSurplusTime()));
+    }
+
+
+
+    public Color32 ParseColor32(int[] colorArr)
+    {
+        return new Color32()
+        {
+            r = (byte)(colorArr.Length > 0 ? colorArr[0] : 0),
+            g = (byte)(colorArr.Length > 1 ? colorArr[1] : 0),
+            b = (byte)(colorArr.Length > 2 ? colorArr[2] : 0),
+            a = (byte)(colorArr.Length > 3 ? colorArr[3] : 255),
+        };
+    }
+
+    public bool IsFestivalActivityOpen()
+    {
+        if (!IsOpen) return false;
+        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.FestivalActivity)) return false;
+        return true;
+    }
+
+    #region 鍏戞崲鍟嗗簵
+    private string ShopVisitTimeDataKey { get { return $"FestivalActivityManager_ShopVisitTime_{PlayerDatas.Instance.PlayerId}"; } }
+
+    private int LoadShopVisitTimeData()
+    {
+        return LocalSave.GetInt(ShopVisitTimeDataKey);
+    }
+
+    public void SaveShopVisitTimeData()
+    {
+        LocalSave.SetInt(ShopVisitTimeDataKey, TimeUtility.AllSeconds);
+    }
+    public bool IsShopVisitedToday
+    {
+        get
+        {
+            int lastVisitTime = LoadShopVisitTimeData();
+            int todayStartTime = TimeUtility.GetTodayStartTick();
+            return lastVisitTime >= todayStartTime;
+        }
+    }
+
+    public bool ShowShopRedpoint()
+    {
+        var act = GetActInfo();
+        if (act == null)
+            return false;
+        var config = ActSpecialSaleConfig.Get(act.CfgID);
+        if (config == null)
+            return false;
+        if (!StoreModel.Instance.storeTypeDict.TryGetValue(config.ShopType, out var list) || list.IsNullOrEmpty())
+            return false;
+
+        for (int i = 0; i < list.Count; i++)
+        {
+            var item = list[i];
+            bool isFree = IsFreeShop(item.shopId);
+            bool isCanBuy = IsNoSellOutShopID(item.shopId);
+            if (isFree && isCanBuy)
+                return true;
+        }
+
+        return !IsShopVisitedToday;
+    }
+    #endregion
+
+    #region 闄愭椂绀煎寘
+    public bool IsCanBuy(int ctgID, out bool isNoLimitBuy, out int nowBuyCnt, out int maxBuyCnt)
+    {
+        isNoLimitBuy = false;
+        nowBuyCnt = 0;
+        maxBuyCnt = 0;
+        CTGConfig config = CTGConfig.Get(ctgID);
+        if (config == null)
+            return false;
+        if (!RechargeManager.Instance.TryGetRechargeCount(ctgID, out var rechargeCount))
+            return false;
+
+        // 鎵�鏈夐檺鍒堕兘涓�0鏃讹紝鏃犻檺璐拱
+        if (config.TotalBuyCount == 0 && config.DailyBuyCount == 0 &&
+            config.WeekBuyCount == 0 && config.MonthBuyCount == 0)
+        {
+            isNoLimitBuy = true;
+            return true;
+        }
+
+        // 鎸変紭鍏堢骇妫�鏌ワ細姣忔棩 > 姣忓懆 > 姣忔湀 > 鎬昏
+        if (config.DailyBuyCount > 0)
+        {
+            nowBuyCnt = rechargeCount.todayCount;
+            maxBuyCnt = config.DailyBuyCount;
+            return rechargeCount.todayCount < config.DailyBuyCount;
+        }
+        if (config.WeekBuyCount > 0)
+        {
+            nowBuyCnt = rechargeCount.weekPayCount;
+            maxBuyCnt = config.WeekBuyCount;
+            return rechargeCount.weekPayCount < config.WeekBuyCount;
+        }
+        if (config.MonthBuyCount > 0)
+        {
+            nowBuyCnt = rechargeCount.monthPayCount;
+            maxBuyCnt = config.MonthBuyCount;
+            return rechargeCount.monthPayCount < config.MonthBuyCount;
+        }
+        if (config.TotalBuyCount > 0)
+        {
+            nowBuyCnt = rechargeCount.totalCount;
+            maxBuyCnt = config.TotalBuyCount;
+            return rechargeCount.totalCount < config.TotalBuyCount;
+        }
+        return false;
+    }
+
+
+    // 鍏嶈垂鍟嗗搧
+    public bool IsFreeShop(int shopID)
+    {
+        StoreConfig config = StoreConfig.Get(shopID);
+        if (config == null) return false;
+        return config.MoneyNum == 0;
+    }
+
+    //娌″敭缃�
+    public bool IsNoSellOutShopID(int shopID)
+    {
+        StoreConfig config = StoreConfig.Get(shopID);
+        if (config == null) return false;
+
+        StoreModel.Instance.TryGetIsSellOut(config, out int remainNum);
+        return remainNum > 0;
+    }
+
+    public List<FestivalActivityGiftItem> GetGiftItemList(bool isSort = false)
+    {
+        var act = GetActInfo();
+        if (act == null) return null;
+
+        var config = ActSpecialSaleConfig.Get(act.CfgID);
+        if (config == null) return null;
+
+        List<FestivalActivityGiftItem> res = new List<FestivalActivityGiftItem>();
+
+        var list = StoreModel.Instance.storeTypeDict[config.ActShopType];
+        if (!list.IsNullOrEmpty())
+        {
+            for (int i = 0; i < list.Count; i++)
+            {
+                var item = list[i];
+                if (item.storeConfig == null)
+                    continue;
+                res.Add(new FestivalActivityGiftItem
+                {
+                    type = 0,
+                    id = item.storeConfig.ID,
+                });
+            }
+        }
+
+        var adAwardConfig = ADAwardConfig.Get(config.ADID);
+        if (adAwardConfig != null)
+        {
+            res.Add(new FestivalActivityGiftItem
+            {
+                type = 1,
+                id = config.ADID,
+            });
+        }
+
+        if (config.CTGIDList != null)
+        {
+            for (int i = 0; i < config.CTGIDList.Length; i++)
+            {
+                var item = config.CTGIDList[i];
+                res.Add(new FestivalActivityGiftItem
+                {
+                    type = 2,
+                    id = item,
+                });
+            }
+        }
+
+        if (isSort)
+        {
+            res = res.OrderBy(item =>
+            {
+                bool isCanBuy;
+                if (item.type == 0) // 鍟嗗簵
+                {
+                    isCanBuy = IsNoSellOutShopID(item.id);
+                }
+                else if (item.type == 1) // 骞垮憡
+                {
+                    isCanBuy = IsAdAwardCanReceive(item.id);
+                }
+                else // 鍏呭��
+                {
+                    isCanBuy = IsCanBuy(item.id, out bool isNoLimitBuy, out int nowBuyCnt, out int maxBuyCnt);
+                }
+                return !isCanBuy;
+            })
+            .ThenBy(item => GetSortOrder(item))
+            .ThenBy(item => item.id)
+            .ToList();
+        }
+        return res;
+    }
+
+    // 骞垮憡鏄惁宸查鍙栧畬
+    public bool IsAdAwardCanReceive(int adID)
+    {
+        var config = ADAwardConfig.Get(adID);
+        if (config == null) return false;
+        int receivedCnt = AdsManager.Instance.GetADCntByADID(adID);
+        return receivedCnt < config.ADCntMax;
+    }
+
+    private int GetSortOrder(FestivalActivityGiftItem item)
+    {
+        if (item.type == 0) // 鍟嗗簵
+        {
+            return IsFreeShop(item.id) ? 0 : 2; // 鍏嶈垂=0, 鍏冨疂=2
+        }
+        if (item.type == 1) // 骞垮憡
+        {
+            return 1;
+        }
+        return 3; // RMB (type == 2)
+    }
+
+
+    public bool HasGiftCanHave()
+    {
+        var list = GetGiftItemList(false);
+        if (list.IsNullOrEmpty())
+            return false;
+
+        for (int i = 0; i < list.Count; i++)
+        {
+            var item = list[i];
+            if (item.type == 0)
+            {
+                bool isFree = IsFreeShop(item.id);
+                bool isCanBuy = IsNoSellOutShopID(item.id);
+                if (isFree && isCanBuy)
+                    return true;
+            }
+        }
+
+        var act = GetActInfo();
+        if (act == null) return false;
+        var config = ActSpecialSaleConfig.Get(act.CfgID);
+        if (config == null) return false;
+        var adAwardConfig = ADAwardConfig.Get(config.ADID);
+        if (adAwardConfig == null) return false;
+
+        if (IsAdAwardCanReceive(config.ADID))
+            return true;
+        return false;
+    }
+
+    #endregion
+}
+
+public enum FestivalActivityRepointType
+{
+    CheckIn = 1,
+    Mission = 2,
+    Shop = 3,
+    Gift = 4,
+    Recharge = 5,
+    TotalRecharge = 6,
+    TotDayRecharge = 7,
+}
+
+public class FestivalActivityGiftItem
+{
+    public int type;//0 鍟嗗簵id 1 骞垮憡id 2 鍏呭�糹d
+    public int id;
+}
\ No newline at end of file
diff --git a/Main/System/FestivalActivity/FestivalActivityManager.cs.meta b/Main/System/FestivalActivity/FestivalActivityManager.cs.meta
new file mode 100644
index 0000000..aae21cc
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e28bb6a585249d94eabdd1bf556d81e7
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityMissionCell.cs b/Main/System/FestivalActivity/FestivalActivityMissionCell.cs
new file mode 100644
index 0000000..b9bff06
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityMissionCell.cs
@@ -0,0 +1,73 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.UI;
+
+
+public class FestivalActivityMissionCell : CellView
+{
+    [SerializeField] Text nameText;
+    [SerializeField] Image processImg;
+    [SerializeField] Text processText;
+    [SerializeField] ItemCell[] itemCells;
+
+    [SerializeField] Button getBtn;
+    [SerializeField] Button gotoBtn;
+    [SerializeField] Transform gotRect;
+
+
+    public void Display(ActTaskTempConfig config, int taskIndex)
+    {
+        int targetValue = config.NeedValue;
+        uint curValue = FestivalActivityMissionManager.Instance.GetTaskProgress((byte)config.TaskType);
+        
+        // 浣跨敤鏂扮殑璇█閿牸寮� ActTaskType{TaskType}
+        nameText.text = Language.Get($"ActTaskType{config.TaskType}", config.NeedValue);
+        
+        processImg.fillAmount = Mathf.Clamp01((float)curValue / targetValue);
+        processText.text = Mathf.Min(targetValue, (int)curValue) + "/" + targetValue;
+
+        var state = FestivalActivityMissionManager.Instance.GetTaskState(config.TasklD);
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            if (i < config.AwardItemList.Length)
+            {
+                itemCells[i].SetActive(true);
+                int itemID = config.AwardItemList[i][0];
+                itemCells[i].Init(new ItemCellModel(itemID, false, config.AwardItemList[i][1]));
+                itemCells[i].button.AddListener(() =>
+                {
+                    ItemTipUtility.Show(itemID);
+                });
+            }
+            else
+            {
+                itemCells[i].SetActive(false);
+            }
+        }
+
+        getBtn.SetActive(state == 1);
+        gotRect.SetActive(state == 2);
+        gotoBtn.SetActive(state == 0);
+
+        getBtn.AddListener(() =>
+        {
+            FestivalActivityMissionManager.Instance.SendGetAward(config.TasklD);
+        });
+        
+        gotoBtn.AddListener(() =>
+        {
+            UIManager.Instance.CloseWindow<FestivalActivityWin>();
+
+            if (config.GuideID > 0)
+            {
+                NewBieCenter.Instance.StartNewBieGuide(config.GuideID);
+            }
+        });
+    }
+
+    
+}
+
+
diff --git a/Main/System/FestivalActivity/FestivalActivityMissionCell.cs.meta b/Main/System/FestivalActivity/FestivalActivityMissionCell.cs.meta
new file mode 100644
index 0000000..cac76d7
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityMissionCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f1170cec164834e4ab20b21cb2be5cca
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityMissionManager.cs b/Main/System/FestivalActivity/FestivalActivityMissionManager.cs
new file mode 100644
index 0000000..6cc4fd3
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityMissionManager.cs
@@ -0,0 +1,385 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+public class FestivalActivityMissionManager : GameSystemManager<FestivalActivityMissionManager>, IOpenServerActivity
+{
+    public readonly int ActNum = 30;
+
+    // 鐜╁浠诲姟杩涘害淇℃伅 (宸紓鏇存柊瀛楀吀: 浠诲姟绫诲瀷 -> 褰撳墠浠诲姟鍊�)
+    private Dictionary<int, uint> taskProgressDict = new Dictionary<int, uint>();
+    public uint ActScoreTotal;    // 绱娲诲姩绉垎锛岀敤浜庨獙璇侀鍙栫疮璁$Н鍒嗗鍔辩敤锛屽晢搴楀厬鎹㈢洿鎺ョ敤鐗╁搧鍏戞崲鐗╁搧
+    public uint ActScoreAward;    // 绱娲诲姩绉垎棰嗗璁板綍锛屾寜濂栧姳绱㈠紩浣嶈繍绠楀垽鏂槸鍚﹀凡棰嗗彇
+    public byte AwardCount;
+    public uint[] AwardRecordList;    // 浠诲姟ID棰嗗璁板綍鍊煎垪琛紝鏍规嵁浠诲姟ID浣嶅垽鏂槸鍚﹀凡棰嗗彇锛屼竴涓褰曞�煎瓨31浣� [璁板綍鍊�0, 璁板綍鍊�1, ...]
+
+    public override void Init()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
+        OperationTimeHepler.Instance.operationTimeUpdateEvent += OperationTimeUpdateEvent;
+        OperationTimeHepler.Instance.operationStartEvent += OperationStartEvent;
+        OperationTimeHepler.Instance.operationEndEvent += OperationEndEvent;
+        OperationTimeHepler.Instance.operationAdvanceEvent += OperationAdvanceEvent;
+        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += OnRefreshBuyShopLimitEvent;
+    }
+
+    public override void Release()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin;
+        OperationTimeHepler.Instance.operationTimeUpdateEvent -= OperationTimeUpdateEvent;
+        OperationTimeHepler.Instance.operationStartEvent -= OperationStartEvent;
+        OperationTimeHepler.Instance.operationEndEvent -= OperationEndEvent;
+        OperationTimeHepler.Instance.operationAdvanceEvent -= OperationAdvanceEvent;
+        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= OnRefreshBuyShopLimitEvent;
+    }
+
+    private void OnRefreshBuyShopLimitEvent()
+    {
+        UpdateRedPoint();
+    }
+
+    private void OnFuncStateChangeEvent(int obj)
+    {
+        if (obj != (int)FuncOpenEnum.FestivalActivity)
+            return;
+        UpdateRedPoint();
+    }
+
+    private void OnBeforePlayerDataInitializeEventOnRelogin()
+    {
+        taskProgressDict.Clear();
+        ActScoreTotal = 0;
+        ActScoreAward = 0;
+        AwardCount = 0;
+        AwardRecordList = null;
+        UpdateRedPoint();
+    }
+
+    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
+    public const int activityID = (int)NewDayActivityID.FestivalActivityMissionAct;
+    public static OperationType operaType = OperationType.FestivalActivity_Mission;
+
+    public Redpoint redPoint = new Redpoint(MainRedDot.FestivalActivityRepoint, FestivalActivityManager.Instance.GetRedPointId(FestivalActivityRepointType.Mission));
+
+    // 瀹炴椂鑾峰彇褰撳墠娲诲姩閰嶇疆
+    private ActTaskConfig GetCurrentConfig()
+    {
+        if (!OperationTimeHepler.Instance.TryGetOperation(operaType, out OperationMissionActivityInfo operation))
+            return null;
+        return ActTaskConfig.Get(operation.CfgID);
+    }
+
+    // 瀹炴椂鑾峰彇浠诲姟妯℃澘鍒楄〃
+    private List<ActTaskTempConfig> GetCurrentTaskList()
+    {
+        ActTaskConfig config = GetCurrentConfig();
+        if (config == null)
+            return null;
+        return ActTaskTempConfig.GetTemplateIDToConfigsDict(config.TemplateID);
+    }
+
+    public bool IsOpen => OperationTimeHepler.Instance.SatisfyOpenCondition(operaType);
+    public bool IsAdvance => OperationTimeHepler.Instance.SatisfyAdvanceCondition(operaType);
+    public bool priorityOpen => redPoint.state == RedPointState.Simple;
+    public event Action<int> onStateUpdate;
+    public event Action OnMissionDataChangeEvent;
+
+    private void OperationTimeUpdateEvent(OperationType type)
+    {
+        if (type != operaType)
+            return;
+
+        if (UIManager.Instance.IsOpened<FestivalActivityMissionWin>())
+            UIManager.Instance.CloseWindow<FestivalActivityMissionWin>();
+
+        // 瀹炴椂鑾峰彇娲诲姩閰嶇疆
+        if (!OperationTimeHepler.Instance.TryGetOperation(operaType, out OperationMissionActivityInfo operation))
+            return;
+
+        ActTaskConfig config = ActTaskConfig.Get(operation.CfgID);
+        if (config == null)
+            return;
+
+        UpdateRedPoint();
+    }
+
+    private void OperationStartEvent(OperationType type, int state)
+    {
+        if (type == operaType && state == 0)
+        {
+            // 瀹炴椂鑾峰彇娲诲姩閰嶇疆
+            if (!OperationTimeHepler.Instance.TryGetOperation(operaType, out OperationMissionActivityInfo operation))
+                return;
+
+            ActTaskConfig config = ActTaskConfig.Get(operation.CfgID);
+            if (config == null)
+                return;
+
+            UpdateRedPoint();
+            onStateUpdate?.Invoke(activityID);
+        }
+    }
+
+    private void OperationEndEvent(OperationType type, int state)
+    {
+        if (type == operaType)
+        {
+            if (UIManager.Instance.IsOpened<FestivalActivityMissionWin>())
+                UIManager.Instance.CloseWindow<FestivalActivityMissionWin>();
+            UpdateRedPoint();
+            onStateUpdate?.Invoke(activityID);
+        }
+    }
+
+    private void OperationAdvanceEvent(OperationType type)
+    {
+        if (type == operaType)
+        {
+            // 瀹炴椂鑾峰彇娲诲姩閰嶇疆
+            if (!OperationTimeHepler.Instance.TryGetOperation(operaType, out OperationMissionActivityInfo operation))
+                return;
+
+            ActTaskConfig config = ActTaskConfig.Get(operation.CfgID);
+            if (config == null)
+                return;
+
+            UpdateRedPoint();
+            onStateUpdate?.Invoke(activityID);
+        }
+    }
+
+    public void UpdateRedPoint()
+    {
+        redPoint.state = RedPointState.None;
+        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.FestivalActivity))
+            return;
+        if (!IsOpen)
+            return;
+
+        ActTaskConfig config = GetCurrentConfig();
+        if (config == null)
+            return;
+
+        var taskList = GetCurrentTaskList();
+        if (taskList == null)
+            return;
+
+        // 妫�鏌ヤ换鍔℃槸鍚︽湁鍙鍙栫殑
+        for (int i = 0; i < taskList.Count; i++)
+        {
+            if (GetTaskState(taskList[i].TasklD) == 1)
+            {
+                redPoint.state = RedPointState.Simple;
+                return;
+            }
+        }
+
+        // 妫�鏌ョ疮璁$Н鍒嗗鍔辨槸鍚︽湁鍙鍙栫殑
+        var totalScoreAwardList = ActTaskTempConfig.GetTotalScoreAwardListByCfgID(config.CfgID);
+        for (int i = 0; i < totalScoreAwardList.Count; i++)
+        {
+            if (GetTotalScoreState(i) == 1)
+            {
+                redPoint.state = RedPointState.Simple;
+                return;
+            }
+        }
+    }
+
+    // 鑾峰彇浠诲姟鍒楄〃锛堟帓搴忥細1鍙鍙� > 0涓嶅彲棰嗗彇 > 2宸查鍙栵級
+    public List<ActTaskTempConfig> GetTaskConfigList()
+    {
+        var taskList = GetCurrentTaskList();
+        if (taskList == null)
+            return new List<ActTaskTempConfig>();
+
+        // 鎸変换鍔$姸鎬佹帓搴忥細1鍙鍙� > 0涓嶅彲棰嗗彇 > 2宸查鍙�
+        return taskList.OrderBy(t => GetTaskState(t.TasklD) == 2)
+            .ThenBy(t => GetTaskState(t.TasklD) == 0)
+            .ToList();
+    }
+
+    // 鑾峰彇浠诲姟鐘舵��: 0涓嶅彲棰嗗彇 1鍙鍙� 2宸查鍙�
+    public int GetTaskState(int taskId)
+    {
+        if (AwardRecordList == null)
+            return 0;
+
+        var taskList = GetCurrentTaskList();
+        if (taskList == null)
+            return 0;
+
+        // 妫�鏌ユ槸鍚﹀凡棰嗗彇
+        if (IsTaskAwardReceived(taskId))
+            return 2;
+
+        // 妫�鏌ユ槸鍚﹁揪鎴�
+        if (CanReceiveTaskAward(taskId))
+            return 1;
+
+        return 0;
+    }
+
+    // 妫�鏌ヤ换鍔″鍔辨槸鍚﹀凡棰嗗彇
+    private bool IsTaskAwardReceived(int id)
+    {
+        if (AwardRecordList == null)
+            return false;
+        var index = id / 31;
+        var bit = id % 31;
+        return (AwardRecordList[index] & (1u << bit)) != 0;
+    }
+
+    // 妫�鏌ヤ换鍔℃槸鍚﹀彲棰嗗彇
+    private bool CanReceiveTaskAward(int taskId)
+    {
+        if (taskProgressDict.Count == 0)
+            return false;
+
+        var taskList = GetCurrentTaskList();
+        if (taskList == null)
+            return false;
+
+        var config = taskList.FirstOrDefault(t => t.TasklD == taskId);
+        if (config == null)
+            return false;
+
+        uint currentValue = GetTaskProgress((byte)config.TaskType);
+        return currentValue >= (uint)config.NeedValue;
+    }
+
+    // 鑾峰彇浠诲姟褰撳墠杩涘害
+    public uint GetTaskProgress(byte taskType)
+    {
+        if (taskProgressDict.TryGetValue(taskType, out uint value))
+            return value;
+        return 0;
+    }
+
+    // 鑾峰彇浠诲姟鐩爣鍊�
+    public uint GetTaskTarget(byte taskType)
+    {
+        var taskList = GetCurrentTaskList();
+        if (taskList == null)
+            return 0;
+
+        var config = taskList.FirstOrDefault(t => t.TaskType == taskType);
+        if (config == null)
+            return 0;
+        return (uint)config.NeedValue;
+    }
+
+    // 鑾峰彇绱绉垎濂栧姳鐘舵��: 0涓嶅彲棰嗗彇 1鍙鍙� 2宸查鍙�
+    public int GetTotalScoreState(int awardIndex)
+    {
+        if (AwardRecordList == null)
+            return 0;
+
+        ActTaskConfig config = GetCurrentConfig();
+        if (config == null)
+            return 0;
+
+        var totalScoreAwardList = ActTaskTempConfig.GetTotalScoreAwardListByCfgID(config.CfgID);
+        if (awardIndex < 0 || awardIndex >= totalScoreAwardList.Count)
+            return 0;
+
+        // 妫�鏌ユ槸鍚﹀凡棰嗗彇
+        if (IsTotalScoreAwardReceived(awardIndex))
+            return 2;
+
+        // 妫�鏌ョН鍒嗘槸鍚﹁冻澶�
+        if (ActScoreTotal >= (uint)totalScoreAwardList[awardIndex].needScore)
+            return 1;
+
+        return 0;
+    }
+
+    // 妫�鏌ョ疮璁$Н鍒嗗鍔辨槸鍚﹀凡棰嗗彇
+    private bool IsTotalScoreAwardReceived(int awardIndex)
+    {
+        if (AwardRecordList == null)
+            return false;
+
+        return (ActScoreAward & (1u << awardIndex)) != 0;
+    }
+
+    // 鑾峰彇绱绉垎
+    public uint GetTotalScore()
+    {
+        return ActScoreTotal;
+    }
+
+    // 鑾峰彇绱绉垎濂栧姳鍒楄〃
+    public List<ActTaskTempConfig.TotalScoreAwardConfig> GetTotalScoreAwardList()
+    {
+        ActTaskConfig config = GetCurrentConfig();
+        if (config == null)
+            return new List<ActTaskTempConfig.TotalScoreAwardConfig>();
+        return ActTaskTempConfig.GetTotalScoreAwardListByCfgID(config.CfgID);
+    }
+
+    // 澶勭悊鐜╁浠诲姟杩涘害淇℃伅 (HAA72)
+    public void UpdatePlayerValueInfo(HAA72_tagSCActTaskPlayerValueInfo info)
+    {
+        if (ActNum != info.ActNum)
+            return;
+
+        for (int i = 0; i < info.TaskValueList.Length; i++)
+        {
+            var taskValue = info.TaskValueList[i];
+            taskProgressDict[(int)taskValue.TaskType] = taskValue.TaskValue;
+        }
+        UpdateRedPoint();
+        OnMissionDataChangeEvent?.Invoke();
+    }
+
+    // 澶勭悊鐜╁濂栧姳棰嗗彇淇℃伅 (HAA73)
+    public void UpdatePlayerInfo(HAA73_tagSCActTaskPlayerInfo info)
+    {
+        if (ActNum != info.ActNum)
+            return;
+
+        ActScoreTotal = info.ActScoreTotal;
+        ActScoreAward = info.ActScoreAward;
+        AwardCount = info.AwardCount;
+        AwardRecordList = info.AwardRecordList;
+        UpdateRedPoint();
+        OnMissionDataChangeEvent?.Invoke();
+    }
+
+    // 鍙戦�侀鍙栦换鍔″鍔�
+    public void SendGetAward(int taskId)
+    {
+        string actStr = ActNum.ToString();
+        var pack = new CA504_tagCMPlayerGetReward();
+        pack.RewardType = 71;
+        pack.DataEx = (uint)taskId;
+        pack.DataExStr = actStr;
+        pack.DataExStrLen = (byte)actStr.Length;
+        GameNetSystem.Instance.SendInfo(pack);
+    }
+
+    // 鍙戦�侀鍙栫疮璁$Н鍒嗗鍔�
+    public void SendGetTotalScoreAward()
+    {
+        string actStr = ActNum.ToString();
+        var pack = new CA504_tagCMPlayerGetReward();
+        pack.RewardType = 71;
+        pack.DataEx = 0; // 0琛ㄧず棰嗗彇绱绉垎濂栧姳
+        pack.DataExStr = actStr;
+        pack.DataExStrLen = (byte)actStr.Length;
+        GameNetSystem.Instance.SendInfo(pack);
+    }
+
+    public string GetActTimeStr()
+    {
+        if (!OperationTimeHepler.Instance.TryGetOperation(operaType, out OperationMissionActivityInfo operation))
+        {
+            return Language.Get("OSActivity6");
+        }
+        return Language.Get("TotalRecharge08", TimeUtility.SecondsToShortDHMS(operation.GetResetSurplusTime()));
+    }
+}
\ No newline at end of file
diff --git a/Main/System/FestivalActivity/FestivalActivityMissionManager.cs.meta b/Main/System/FestivalActivity/FestivalActivityMissionManager.cs.meta
new file mode 100644
index 0000000..329845b
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityMissionManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 16ba7e2787f697440a4d3ad20ecec557
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityMissionWin.cs b/Main/System/FestivalActivity/FestivalActivityMissionWin.cs
new file mode 100644
index 0000000..c131f4f
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityMissionWin.cs
@@ -0,0 +1,149 @@
+锘�//--------------------------------------------------------
+//    [Author]:           鐜╀釜娓告垙
+//    [  Date ]:           Tuesday, July 24, 2018
+//--------------------------------------------------------
+
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.UI;
+
+
+////寮�鏈嶇洓鍏�
+public class FestivalActivityMissionWin : UIBase
+{
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] Image processImg;
+    [SerializeField] Text galaTimeText;
+    [SerializeField] Text totalScoreText;
+    [SerializeField] ItemCell[] itemCells;
+    [SerializeField] Image[] gotImgs;
+    [SerializeField] Text[] scoreTexts;
+    [SerializeField] UIEffectPlayer[] effectPlayers;
+    [SerializeField] ScrollerController scroller;
+
+    List<ActTaskTempConfig> taskConfigs = new List<ActTaskTempConfig>();
+
+    protected override void InitComponent()
+    {
+        closeButton.SetListener(CloseWindow);
+    }
+    protected override void OnPreOpen()
+    {
+        FestivalActivityMissionManager.Instance.OnMissionDataChangeEvent += OnMissionDataChangeEvent;
+        GlobalTimeEvent.Instance.secondEvent += ShowTime;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += OnRefreshBuyShopLimitEvent;
+        scroller.OnRefreshCell += OnRefreshCell;
+        RefreshScroller();
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        FestivalActivityMissionManager.Instance.OnMissionDataChangeEvent -= OnMissionDataChangeEvent;
+        GlobalTimeEvent.Instance.secondEvent -= ShowTime;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= OnRefreshBuyShopLimitEvent;
+        scroller.OnRefreshCell -= OnRefreshCell;
+    }
+    void OnMissionDataChangeEvent()
+    {
+        scroller.m_Scorller.RefreshActiveCellViews();
+        Display();
+    }
+
+    void RefreshScroller()
+    {
+        taskConfigs = FestivalActivityMissionManager.Instance.GetTaskConfigList();
+        var count = taskConfigs.Count;
+        scroller.Refresh();
+        for (int i = 0; i < count; i++)
+        {
+            scroller.AddCell(ScrollerDataType.Header, i);
+        }
+        scroller.Restart();
+    }
+
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as FestivalActivityMissionCell;
+        _cell.Display(taskConfigs[cell.index], cell.index);
+    }
+
+    private void OnRefreshBuyShopLimitEvent()
+    {
+        Display();
+    }
+
+    void Display()
+    {
+        uint totalScore = FestivalActivityMissionManager.Instance.GetTotalScore();
+        var awardList = FestivalActivityMissionManager.Instance.GetTotalScoreAwardList();
+
+        // 杩涘害鏉¤绠�
+        uint maxScore = 0;
+        if (awardList != null && awardList.Count > 0)
+        {
+            maxScore = (uint)awardList[awardList.Count - 1].needScore;
+        }
+
+        if (maxScore > 0)
+        {
+            processImg.fillAmount = Mathf.Clamp01((float)totalScore / maxScore);
+        }
+        else
+        {
+            processImg.fillAmount = 0;
+        }
+
+        ShowTime();
+        totalScoreText.text = Language.Get("OSActivity11") + totalScore.ToString();
+
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            if (i < awardList.Count)
+            {
+                itemCells[i].SetActive(true);
+                int index = i;
+                int itemID = awardList[i].itemId;
+                itemCells[i].Init(new ItemCellModel(itemID, false, awardList[i].itemCount));
+                itemCells[i].button.AddListener(() =>
+                {
+                    if (FestivalActivityMissionManager.Instance.GetTotalScoreState(index) != 1)
+                    {
+                        ItemTipUtility.Show(itemID);
+                        return;
+                    }
+
+                    FestivalActivityMissionManager.Instance.SendGetTotalScoreAward();
+                });
+
+                gotImgs[i].SetActive(FestivalActivityMissionManager.Instance.GetTotalScoreState(i) == 2);
+                scoreTexts[i].text = awardList[i].needScore.ToString();
+                if (FestivalActivityMissionManager.Instance.GetTotalScoreState(i) == 1)
+                {
+                    effectPlayers[i].Play();
+                }
+                else
+                {
+                    effectPlayers[i].Stop();
+                }
+            }
+            else
+            {
+                itemCells[i].SetActive(false);
+            }
+        }
+    }
+
+    void ShowTime()
+    {
+        galaTimeText.text = FestivalActivityMissionManager.Instance.GetActTimeStr();
+    }
+}
+
+
+
+
diff --git a/Main/System/FestivalActivity/FestivalActivityMissionWin.cs.meta b/Main/System/FestivalActivity/FestivalActivityMissionWin.cs.meta
new file mode 100644
index 0000000..cf25a4a
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityMissionWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8cc4efe602e822743a4ee236fcd0e3d4
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityPopCell.cs b/Main/System/FestivalActivity/FestivalActivityPopCell.cs
new file mode 100644
index 0000000..ee1a0d0
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityPopCell.cs
@@ -0,0 +1,18 @@
+using UnityEngine;
+
+public class FestivalActivityPopCell : CellView
+{
+    [SerializeField] ItemCell itemCell;
+    public void Display(int index, int[][] popItems)
+    {
+        if (popItems == null || popItems.Length <= index || index < 0)
+            return;
+        int itemID = popItems[index][0];
+        int itemCount = popItems[index][1];
+        itemCell.Init(new ItemCellModel(itemID, false, itemCount));
+        itemCell.button.AddListener(() =>
+        {
+            ItemTipUtility.Show(itemID);
+        });
+    }
+}
diff --git a/Main/System/FestivalActivity/FestivalActivityPopCell.cs.meta b/Main/System/FestivalActivity/FestivalActivityPopCell.cs.meta
new file mode 100644
index 0000000..ce03b66
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityPopCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5698be6bce9f11240b0f8866851956f3
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityPopWin.cs b/Main/System/FestivalActivity/FestivalActivityPopWin.cs
new file mode 100644
index 0000000..e72d533
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityPopWin.cs
@@ -0,0 +1,83 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+public class FestivalActivityPopWin : UIBase
+{
+    [SerializeField] TextEx timeText;
+    [SerializeField] ButtonEx goButton;
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] Toggle todayPopToggle;
+    [SerializeField] ScrollerController scroller;
+
+    FestivalActivityManager manager => FestivalActivityManager.Instance;
+    protected override void InitComponent()
+    {
+        closeButton.SetListener(CloseWindow);
+        goButton.SetListener(() =>
+        {
+            UIManager.Instance.CloseWindow<FestivalActivityPopWin>();
+            if (!UIManager.Instance.IsOpened<FestivalActivityWin>())
+                UIManager.Instance.OpenWindow<FestivalActivityWin>();
+        });
+        todayPopToggle.AddListener((bool value) =>
+        {
+            if (value)
+            {
+                // 鍕鹃�夛細浠婃棩涓嶅啀寮瑰嚭
+                manager.SavePopTimeData();
+            }
+            else
+            {
+                // 鍙栨秷鍕鹃�夛細浠婃棩渚濈劧鍙互寮瑰嚭锛堥噸缃椂闂磋褰曪級
+                manager.ClearPopTimeData();
+            }
+        });
+    }
+
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        todayPopToggle.isOn = !manager.IsTodayPop;
+        DisplayTime();
+        CreateScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as FestivalActivityPopCell;
+        _cell.Display(cell.index, popItems);
+    }
+    int[][] popItems;
+    void CreateScroller()
+    {
+        var act = manager.GetActInfo();
+        if (act == null)
+            return;
+        var config = ActSpecialSaleConfig.Get(act.CfgID);
+        if (config == null)
+            return;
+        popItems = config.PopItems;
+
+        scroller.Refresh();
+        if (popItems != null)
+        {
+            for (int i = 0; i < popItems.Length; i++)
+            {
+                scroller.AddCell(ScrollerDataType.Header, i);
+            }
+        }
+        scroller.Restart();
+    }
+
+
+    private void DisplayTime()
+    {
+        var act = manager.GetActInfo();
+        timeText.text = act == null ? string.Empty : Language.Get("FestivalActivity01", act.ToDisplayTime());
+    }
+}
diff --git a/Main/System/FestivalActivity/FestivalActivityPopWin.cs.meta b/Main/System/FestivalActivity/FestivalActivityPopWin.cs.meta
new file mode 100644
index 0000000..46a9073
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityPopWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6a7825299693150499da31b4f94eefbb
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeBaseWin.cs b/Main/System/FestivalActivity/FestivalActivityRechargeBaseWin.cs
new file mode 100644
index 0000000..0dc9c0b
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeBaseWin.cs
@@ -0,0 +1,52 @@
+using System;
+using UnityEngine;
+public class FestivalActivityRechargeBaseWin : FunctionsBaseWin
+{
+    [SerializeField] TextEx timeText;
+    [SerializeField] ButtonEx closeButton;
+    FestivalActivityManager manager => FestivalActivityManager.Instance;
+    protected override void InitComponent()
+    {
+        base.InitComponent();
+        closeButton.SetListener(CloseWindow);
+    }
+    protected override void OnPreOpen()
+    {
+        base.OnPreOpen();
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        tabButtons[0].redpoint.redpointId = FestivalActivityManager.Instance.GetRedPointId(FestivalActivityRepointType.TotalRecharge);
+        tabButtons[1].redpoint.redpointId = FestivalActivityManager.Instance.GetRedPointId(FestivalActivityRepointType.TotDayRecharge);
+        OnSecondEvent();
+    }
+    protected override void OnPreClose()
+    {
+        base.OnPreClose();
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+    }
+
+    protected override void OpenSubUIByTabIndex()
+    {
+        switch (functionOrder)
+        {
+            case 0:
+                currentSubUI = UIManager.Instance.OpenWindow<FestivalActivityRechargeTotalWin>();
+                break;
+            case 1:
+                currentSubUI = UIManager.Instance.OpenWindow<FestivalActivityRechargeTotDayWin>();
+                break;
+        }
+    }
+
+    private void OnSecondEvent()
+    {
+        var act = manager.GetActInfo();
+        if (act == null)
+        {
+            timeText.text = Language.Get("OSActivity6");
+            return;
+        }
+        timeText.text = Language.Get("TotalRecharge08", TimeUtility.SecondsToShortDHMS(act.GetResetSurplusTime()));
+    }
+
+}
+
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeBaseWin.cs.meta b/Main/System/FestivalActivity/FestivalActivityRechargeBaseWin.cs.meta
new file mode 100644
index 0000000..5eae932
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeBaseWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2ed22b2a27c50074ab0addf5fe7c945e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeTotDayCell.cs b/Main/System/FestivalActivity/FestivalActivityRechargeTotDayCell.cs
new file mode 100644
index 0000000..fc62023
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeTotDayCell.cs
@@ -0,0 +1,74 @@
+锘縰sing System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class FestivalActivityRechargeTotDayCell : CellView
+{
+    [SerializeField] Text nameText;
+    [SerializeField] Image processImage;
+    [SerializeField] Text processText;
+    [SerializeField] ItemCell[] itemCells;
+
+    [SerializeField] Button getBtn;
+    [SerializeField] Button gotoBtn;
+    [SerializeField] Transform gotRect;
+
+    FestivalActivityRechargeTotDayManager manager { get { return FestivalActivityRechargeTotDayManager.Instance; } }
+
+    public void Display(int index, List<int> list)
+    {
+        if (list.IsNullOrEmpty() || index < 0 || index >= list.Count)
+            return;
+        int awardID = list[index];
+        var config = ActTotDayRechargeTempConfig.Get(awardID);
+        if (config == null)
+            return;
+        nameText.text = Language.Get($"TotalRecharge03", config.NeedDay);
+
+        if (config.AwardItemList != null)
+        {
+            for (int i = 0; i < itemCells.Length; i++)
+            {
+                var cell = itemCells[i];
+
+                if (i < config.AwardItemList.Length)
+                {
+                    var item = config.AwardItemList[i];
+                    cell.SetActive(true);
+                    cell.Init(new ItemCellModel(item[0], false, item[1]));
+                    cell.button.AddListener(() => ItemTipUtility.Show(item[0]));
+                }
+                else
+                {
+                    cell.SetActive(false);
+                }
+            }
+        }
+
+        processText.text = Language.Get("BoneField09", manager.totalDays, config.NeedDay);
+        processImage.fillAmount = manager.totalDays / (float)config.NeedDay;
+
+        int state = manager.GetState(awardID);// 鑾峰彇濂栧姳鐘舵�� 0 涓嶅彲棰嗗彇 1 鏈鍙� 2 宸查鍙�
+
+        gotoBtn.SetActive(state == 0);
+        getBtn.SetActive(state == 1);
+        gotRect.SetActive(state == 2);
+
+        getBtn.SetListener(() => manager.SendGetReward(config.NeedDay));
+        gotoBtn.SetListener(() =>
+        {
+            if (FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Recharge, true))
+            {
+                RechargeManager.Instance.selectTabIndex = 1;
+                if (UIManager.Instance.IsOpened<StoreBaseWin>())
+                {
+                    UIManager.Instance.GetUI<StoreBaseWin>().ClickFuncBtn(2);
+                }
+                else
+                {
+                    UIManager.Instance.OpenWindow<StoreBaseWin>(2);
+                }
+            }
+        });
+    }
+}
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeTotDayCell.cs.meta b/Main/System/FestivalActivity/FestivalActivityRechargeTotDayCell.cs.meta
new file mode 100644
index 0000000..d9d58f0
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeTotDayCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a0ea141844e14b645b403981c1b265c0
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeTotDayManager.cs b/Main/System/FestivalActivity/FestivalActivityRechargeTotDayManager.cs
new file mode 100644
index 0000000..0299911
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeTotDayManager.cs
@@ -0,0 +1,248 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+public class FestivalActivityRechargeTotDayManager : GameSystemManager<FestivalActivityRechargeTotDayManager>, IOpenServerActivity
+{
+    public readonly int ActNum = 30;
+    public override void Init()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
+        OperationTimeHepler.Instance.operationTimeUpdateEvent += OperationTimeUpdateEvent;
+        OperationTimeHepler.Instance.operationStartEvent += OperationStartEvent;
+        OperationTimeHepler.Instance.operationEndEvent += OperationEndEvent;
+        OperationTimeHepler.Instance.operationAdvanceEvent += OperationAdvanceEvent;
+        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += OnRefreshBuyShopLimitEvent;
+    }
+
+    public override void Release()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin;
+        OperationTimeHepler.Instance.operationTimeUpdateEvent -= OperationTimeUpdateEvent;
+        OperationTimeHepler.Instance.operationStartEvent -= OperationStartEvent;
+        OperationTimeHepler.Instance.operationEndEvent -= OperationEndEvent;
+        OperationTimeHepler.Instance.operationAdvanceEvent -= OperationAdvanceEvent;
+        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= OnRefreshBuyShopLimitEvent;
+
+    }
+
+    private void OnRefreshBuyShopLimitEvent()
+    {
+        UpdateRedPoint();
+    }
+
+
+    private void OnFuncStateChangeEvent(int obj)
+    {
+        if (obj != (int)FuncOpenEnum.OSGala)
+            return;
+        UpdateRedPoint();
+    }
+
+    private void OnBeforePlayerDataInitializeEventOnRelogin()
+    {
+        totalDays = 0;
+        awardRecord = 0;
+    }
+
+    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
+    public const int activityID = (int)NewDayActivityID.FestivalActivityRechargeTotDayAct;
+    public static OperationType operaType = OperationType.FestivalActivity_RechargeTotDay;
+    // 鎬诲鍔�
+    public Redpoint redPoint = new Redpoint(
+       FestivalActivityManager.Instance.GetRedPointId(FestivalActivityRepointType.Recharge),
+       FestivalActivityManager.Instance.GetRedPointId(FestivalActivityRepointType.TotDayRecharge));
+    public bool IsOpen => OperationTimeHepler.Instance.SatisfyOpenCondition(operaType);
+    public bool IsAdvance => OperationTimeHepler.Instance.SatisfyAdvanceCondition(operaType);
+    public bool priorityOpen => redPoint.state == RedPointState.Simple;
+    public event Action<int> onStateUpdate;
+
+    private void OperationTimeUpdateEvent(OperationType type)
+    {
+        if (UIManager.Instance.IsOpened<FestivalActivityRechargeBaseWin>())
+            UIManager.Instance.CloseWindow<FestivalActivityRechargeBaseWin>();
+        UpdateRedPoint();
+    }
+
+    private void OperationStartEvent(OperationType type, int state)
+    {
+        if (type == operaType && state == 0)
+        {
+            UpdateRedPoint();
+            onStateUpdate?.Invoke(activityID);
+        }
+    }
+
+    private void OperationEndEvent(OperationType type, int state)
+    {
+        if (type == operaType)
+        {
+            if (UIManager.Instance.IsOpened<FestivalActivityRechargeBaseWin>())
+                UIManager.Instance.CloseWindow<FestivalActivityRechargeBaseWin>();
+            UpdateRedPoint();
+            onStateUpdate?.Invoke(activityID);
+        }
+    }
+
+    private void OperationAdvanceEvent(OperationType type)
+    {
+        if (type == operaType)
+        {
+            UpdateRedPoint();
+            onStateUpdate?.Invoke(activityID);
+        }
+    }
+
+    public void UpdateRedPoint()
+    {
+        redPoint.state = RedPointState.None;
+        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.OSGala))
+            return;
+        if (!IsOpen)
+            return;
+
+        var awardList = GetShowList();
+        if (awardList == null)
+            return;
+        for (int i = 0; i < awardList.Count; i++)
+        {
+            if (GetState(awardList[i]) == 1)
+            {
+                redPoint.state = RedPointState.Simple;
+                return;
+            }
+        }
+
+        var storeData = GetStoreData();
+        if (storeData != null && !IsReceived(storeData.shopId))
+        {
+            redPoint.state = RedPointState.Simple;
+        }
+    }
+
+    public bool GetActInfo(out OperationTotDayRechargeInfo act, out ActTotDayRechargeConfig config)
+    {
+        config = null;
+        if (!OperationTimeHepler.Instance.TryGetOperation(operaType, out act) || act == null)
+            return false;
+        config = ActTotDayRechargeConfig.Get(act.CfgID);
+        return config != null;
+    }
+
+    public List<int> GetShowList(bool isSort = false)
+    {
+        if (!GetActInfo(out var act, out var config))
+            return null;
+
+        int templateID = config.TemplateID;
+        var res = new List<int>();
+
+        var awardIndexSortList = ActTotDayRechargeTempConfig.GetNeedDaySortList(templateID);
+        for (int i = 0; i < awardIndexSortList.Count; i++)
+        {
+            var tempConfig = ActTotDayRechargeTempConfig.GetConfig(templateID, awardIndexSortList[i]);
+            if (tempConfig == null)
+                continue;
+            res.Add(tempConfig.AwardID);
+        }
+
+        if (isSort)
+        {
+            res = res.OrderBy(awardId =>
+            {
+                var tempConfig = ActTotDayRechargeTempConfig.Get(awardId);
+                return IsAwardHave(tempConfig.NeedDay);
+            })
+            .ThenBy(awardId => awardId)
+            .ToList();
+
+        }
+        return res;
+    }
+
+    public bool IsCanBuyShop(int shopID)
+    {
+        StoreConfig config = StoreConfig.Get(shopID);
+        if (config == null)
+            return false;
+        StoreModel.Instance.TryGetIsSellOut(config, out int remainNum);
+        return remainNum > 0;
+    }
+
+    public StoreModel.StoreData GetStoreData()
+    {
+        if (!GetActInfo(out var act, out var config))
+            return null;
+        int actShopType = config.ActShopType;
+        if (StoreModel.Instance.storeTypeDict == null)
+            return null;
+        if (!StoreModel.Instance.storeTypeDict.TryGetValue(actShopType, out var list))
+            return null;
+        if (list.IsNullOrEmpty())
+            return null;
+        return list[0];
+    }
+
+    bool IsAwardHave(int awardIndex)
+    {
+        if (awardIndex < 0 || awardIndex >= 32)
+            return false;
+        return (awardRecord & (1u << awardIndex)) != 0;
+    }
+
+    // 鑾峰彇濂栧姳鐘舵�� 0 涓嶅彲棰嗗彇 1 鏈鍙� 2 宸查鍙�
+    public int GetState(int awardID)
+    {
+        var config = ActTotDayRechargeTempConfig.Get(awardID);
+        if (config == null)
+            return 0;
+        if (totalDays < config.NeedDay)
+            return 0;
+        bool isAwardHave = IsAwardHave(config.NeedDay);
+        return isAwardHave ? 2 : 1;
+    }
+
+    public bool IsReceived(int shopId)
+    {
+        var config = StoreConfig.Get(shopId);
+        if (config == null)
+            return false;
+        int boughtCount = StoreModel.Instance.GetShopLimitBuyCount(shopId);
+        return boughtCount >= config.LimitCnt;
+    }
+
+    public string GetActTimeStr()
+    {
+        if (!GetActInfo(out var act, out var config))
+        {
+            return Language.Get("OSActivity6");
+        }
+        return Language.Get("TotalRecharge08", TimeUtility.SecondsToShortDHMS(act.GetResetSurplusTime()));
+    }
+
+    public byte totalDays;    //娲诲姩绱厖澶╂暟
+    public uint awardRecord;    //绱厖濂栧姳棰嗗璁板綍锛屾寜濂栧姳绱㈠紩浜岃繘鍒朵綅瀛樺偍鏄惁宸查鍙�
+    public event Action OnTotDayRechargePlayerInfoEvent;
+    public void UpdateTotDayRechargePlayerInfo(HAA1A_tagSCActTotDayRechargePlayerInfo vNetData)
+    {
+        if (ActNum != vNetData.ActNum)
+            return;
+        totalDays = vNetData.TotalDays;
+        awardRecord = vNetData.AwardRecord;
+        UpdateRedPoint();
+        OnTotDayRechargePlayerInfoEvent?.Invoke();
+    }
+
+    public void SendGetReward(int needDay)
+    {
+        string actStr = ActNum.ToString();
+        var pack = new CA504_tagCMPlayerGetReward();
+        pack.RewardType = 19;
+        pack.DataEx = (uint)needDay;
+        pack.DataExStr = actStr;
+        pack.DataExStrLen = (byte)actStr.Length;
+        GameNetSystem.Instance.SendInfo(pack);
+    }
+}
\ No newline at end of file
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeTotDayManager.cs.meta b/Main/System/FestivalActivity/FestivalActivityRechargeTotDayManager.cs.meta
new file mode 100644
index 0000000..9182328
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeTotDayManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0625bbc16a0d77046b6393549c59b91a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeTotDayWin.cs b/Main/System/FestivalActivity/FestivalActivityRechargeTotDayWin.cs
new file mode 100644
index 0000000..e869844
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeTotDayWin.cs
@@ -0,0 +1,113 @@
+锘縰sing System.Collections.Generic;
+using UnityEngine;
+
+//寮�鏈嶆椿鍔�-绱厖
+public class FestivalActivityRechargeTotDayWin : UIBase
+{
+    [SerializeField] ItemCell totDayRechargeItemCell;
+    [SerializeField] TextEx totDayRechargeScoreText;
+    [SerializeField] RotationTween totDayRechargeRotationTween;
+    [SerializeField] ImageEx totDayRechargeFreeRedImage;
+    [SerializeField] ImageEx totDayRechargeHaveImage;
+
+    [SerializeField] ScrollerController scroller;
+
+    FestivalActivityRechargeTotDayManager manager { get { return FestivalActivityRechargeTotDayManager.Instance; } }
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        manager.OnTotDayRechargePlayerInfoEvent += OnTotDayRechargePlayerInfoEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += OnRefreshBuyShopLimitEvent;
+        CreateScroller();
+        InitRechargeData();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        manager.OnTotDayRechargePlayerInfoEvent -= OnTotDayRechargePlayerInfoEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= OnRefreshBuyShopLimitEvent;
+    }
+
+    private void OnRefreshBuyShopLimitEvent()
+    {
+        scroller.m_Scorller.RefreshActiveCellViews();
+        RefreshRechargeData();
+    }
+
+    private void OnTotDayRechargePlayerInfoEvent()
+    {
+        scroller.m_Scorller.RefreshActiveCellViews();
+        RefreshRechargeData();
+    }
+
+    void InitRechargeData()
+    {
+        var data = manager.GetStoreData();
+        bool isReceived = manager.IsReceived(data.shopId);
+        totDayRechargeItemCell.Init(new ItemCellModel(data.storeConfig.ItemID, false, data.storeConfig.ItemCnt));
+        totDayRechargeItemCell.button.SetListener(() =>
+        {
+            if (!isReceived)
+            {
+                StoreModel.Instance.SendBuyShopItem(data.storeConfig, 1);
+            }
+            else
+            {
+                ItemTipUtility.Show(data.storeConfig.ItemID);
+            }
+        });
+
+        totDayRechargeHaveImage.SetActive(isReceived);
+        totDayRechargeFreeRedImage.SetActive(!isReceived);
+        totDayRechargeScoreText.text = Language.Get("TotalRecharge07", manager.totalDays);
+        if (!isReceived)
+        {
+            totDayRechargeRotationTween.Play();
+        }
+        else
+        {
+            totDayRechargeRotationTween.Stop();
+            totDayRechargeRotationTween.SetStartState();
+        }
+    }
+
+    void RefreshRechargeData()
+    {
+        var data = manager.GetStoreData();
+        bool isReceived = manager.IsReceived(data.shopId);
+        totDayRechargeItemCell.Init(new ItemCellModel(data.storeConfig.ItemID, false, data.storeConfig.ItemCnt));
+        totDayRechargeHaveImage.SetActive(isReceived);
+        totDayRechargeFreeRedImage.SetActive(!isReceived);
+        totDayRechargeScoreText.text = Language.Get("TotalRecharge07", manager.totalDays);
+        if (!isReceived)
+        {
+            totDayRechargeRotationTween.Play();
+        }
+        else
+        {
+            totDayRechargeRotationTween.Stop();
+            totDayRechargeRotationTween.SetStartState();
+        }
+    }
+
+    List<int> showList;
+    void CreateScroller()
+    {
+        showList = manager.GetShowList(true);
+        scroller.Refresh();
+        for (int i = 0; i < showList.Count; i++)
+        {
+            scroller.AddCell(ScrollerDataType.Header, i);
+        }
+        scroller.Restart();
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as FestivalActivityRechargeTotDayCell;
+        _cell.Display(cell.index, showList);
+    }
+}
+
+
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeTotDayWin.cs.meta b/Main/System/FestivalActivity/FestivalActivityRechargeTotDayWin.cs.meta
new file mode 100644
index 0000000..6ecb634
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeTotDayWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6f977063d346b8f4881b912d1243fbdb
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeTotalCell.cs b/Main/System/FestivalActivity/FestivalActivityRechargeTotalCell.cs
new file mode 100644
index 0000000..bf53931
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeTotalCell.cs
@@ -0,0 +1,74 @@
+锘縰sing System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class FestivalActivityRechargeTotalCell : CellView
+{
+    [SerializeField] Text nameText;
+    [SerializeField] Image processImage;
+    [SerializeField] Text processText;
+    [SerializeField] ItemCell[] itemCells;
+
+    [SerializeField] Button getBtn;
+    [SerializeField] Button gotoBtn;
+    [SerializeField] Transform gotRect;
+
+    FestivalActivityRechargeTotalManager manager { get { return FestivalActivityRechargeTotalManager.Instance; } }
+
+    public void Display(int index, List<int> list)
+    {
+        if (list.IsNullOrEmpty() || index < 0 || index >= list.Count)
+            return;
+        int awardID = list[index];
+        var config = ActTotalRechargeTempConfig.Get(awardID);
+        if (config == null)
+            return;
+        nameText.text = Language.Get($"TotalRecharge02", config.NeedAmount);
+
+        if (config.AwardItemList != null)
+        {
+            for (int i = 0; i < itemCells.Length; i++)
+            {
+                var cell = itemCells[i];
+
+                if (i < config.AwardItemList.Length)
+                {
+                    var item = config.AwardItemList[i];
+                    cell.SetActive(true);
+                    cell.Init(new ItemCellModel(item[0], false, item[1]));
+                    cell.button.AddListener(() => ItemTipUtility.Show(item[0]));
+                }
+                else
+                {
+                    cell.SetActive(false);
+                }
+            }
+        }
+
+        processText.text = Language.Get("BoneField09", manager.coinTotal, config.NeedAmount);
+        processImage.fillAmount = manager.coinTotal / (float)config.NeedAmount;
+
+        int state = manager.GetState(awardID);// 鑾峰彇濂栧姳鐘舵�� 0 涓嶅彲棰嗗彇 1 鏈鍙� 2 宸查鍙�
+
+        gotoBtn.SetActive(state == 0);
+        getBtn.SetActive(state == 1);
+        gotRect.SetActive(state == 2);
+
+        getBtn.SetListener(() => manager.SendGetReward(config.AwardIndex));
+        gotoBtn.SetListener(() =>
+        {
+            if (FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Recharge, true))
+            {
+                RechargeManager.Instance.selectTabIndex = 1;
+                if (UIManager.Instance.IsOpened<StoreBaseWin>())
+                {
+                    UIManager.Instance.GetUI<StoreBaseWin>().ClickFuncBtn(2);
+                }
+                else
+                {
+                    UIManager.Instance.OpenWindow<StoreBaseWin>(2);
+                }
+            }
+        });
+    }
+}
\ No newline at end of file
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeTotalCell.cs.meta b/Main/System/FestivalActivity/FestivalActivityRechargeTotalCell.cs.meta
new file mode 100644
index 0000000..a883fc6
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeTotalCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 57f1d393b81fe04409bfc2fd5e5ecebc
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeTotalManager.cs b/Main/System/FestivalActivity/FestivalActivityRechargeTotalManager.cs
new file mode 100644
index 0000000..70fc403
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeTotalManager.cs
@@ -0,0 +1,249 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+public class FestivalActivityRechargeTotalManager : GameSystemManager<FestivalActivityRechargeTotalManager>, IOpenServerActivity
+{
+    public readonly int ActNum = 30;
+    public override void Init()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
+        OperationTimeHepler.Instance.operationTimeUpdateEvent += OperationTimeUpdateEvent;
+        OperationTimeHepler.Instance.operationStartEvent += OperationStartEvent;
+        OperationTimeHepler.Instance.operationEndEvent += OperationEndEvent;
+        OperationTimeHepler.Instance.operationAdvanceEvent += OperationAdvanceEvent;
+        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += OnRefreshBuyShopLimitEvent;
+    }
+
+    public override void Release()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin;
+        OperationTimeHepler.Instance.operationTimeUpdateEvent -= OperationTimeUpdateEvent;
+        OperationTimeHepler.Instance.operationStartEvent -= OperationStartEvent;
+        OperationTimeHepler.Instance.operationEndEvent -= OperationEndEvent;
+        OperationTimeHepler.Instance.operationAdvanceEvent -= OperationAdvanceEvent;
+        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= OnRefreshBuyShopLimitEvent;
+
+    }
+
+    private void OnRefreshBuyShopLimitEvent()
+    {
+        UpdateRedPoint();
+    }
+
+
+    private void OnFuncStateChangeEvent(int obj)
+    {
+        if (obj != (int)FuncOpenEnum.FestivalActivity)
+            return;
+        UpdateRedPoint();
+    }
+
+
+    private void OnBeforePlayerDataInitializeEventOnRelogin()
+    {
+        coinTotal = 0;
+        awardRecord = 0;
+    }
+
+    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
+    public const int activityID = (int)NewDayActivityID.FestivalActivityRechargeTotalAct;
+    public static OperationType operaType = OperationType.FestivalActivity_RechargeTotal;
+    // 鎬诲鍔�
+    public Redpoint redPoint = new Redpoint(
+        FestivalActivityManager.Instance.GetRedPointId(FestivalActivityRepointType.Recharge),
+        FestivalActivityManager.Instance.GetRedPointId(FestivalActivityRepointType.TotalRecharge));
+    public bool IsOpen => OperationTimeHepler.Instance.SatisfyOpenCondition(operaType);
+    public bool IsAdvance => OperationTimeHepler.Instance.SatisfyAdvanceCondition(operaType);
+    public bool priorityOpen => redPoint.state == RedPointState.Simple;
+    public event Action<int> onStateUpdate;
+
+    private void OperationTimeUpdateEvent(OperationType type)
+    {
+        if (UIManager.Instance.IsOpened<FestivalActivityRechargeBaseWin>())
+            UIManager.Instance.CloseWindow<FestivalActivityRechargeBaseWin>();
+        UpdateRedPoint();
+    }
+
+    private void OperationStartEvent(OperationType type, int state)
+    {
+        if (type == operaType && state == 0)
+        {
+            UpdateRedPoint();
+            onStateUpdate?.Invoke(activityID);
+        }
+    }
+
+    private void OperationEndEvent(OperationType type, int state)
+    {
+        if (type == operaType)
+        {
+            if (UIManager.Instance.IsOpened<FestivalActivityRechargeBaseWin>())
+                UIManager.Instance.CloseWindow<FestivalActivityRechargeBaseWin>();
+            UpdateRedPoint();
+            onStateUpdate?.Invoke(activityID);
+        }
+    }
+
+    private void OperationAdvanceEvent(OperationType type)
+    {
+        if (type == operaType)
+        {
+            UpdateRedPoint();
+            onStateUpdate?.Invoke(activityID);
+        }
+    }
+
+    public void UpdateRedPoint()
+    {
+        redPoint.state = RedPointState.None;
+        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.FestivalActivity))
+            return;
+        if (!IsOpen)
+            return;
+
+        var awardList = GetShowList();
+        if (awardList == null)
+            return;
+        for (int i = 0; i < awardList.Count; i++)
+        {
+            if (GetState(awardList[i]) == 1)
+            {
+                redPoint.state = RedPointState.Simple;
+                return;
+            }
+        }
+
+        var storeData = GetStoreData();
+        if (storeData != null && !IsReceived(storeData.shopId))
+        {
+            redPoint.state = RedPointState.Simple;
+        }
+    }
+    public bool GetActInfo(out OperationTotalRechargeInfo act, out ActTotalRechargeConfig config)
+    {
+        config = null;
+        if (!OperationTimeHepler.Instance.TryGetOperation(operaType, out act) || act == null)
+            return false;
+        config = ActTotalRechargeConfig.Get(act.CfgID);
+        return config != null;
+    }
+
+    public List<int> GetShowList(bool isSort = false)
+    {
+        if (!GetActInfo(out var act, out var config))
+            return null;
+
+        int ctgTempID = config.CTGTempID;
+        int ctgShopType = config.CTGShopType;
+        var res = new List<int>();
+
+        var awardIndexSortList = ActTotalRechargeTempConfig.GetAwardIndexSortList(ctgTempID);
+        for (int i = 0; i < awardIndexSortList.Count; i++)
+        {
+            var tempConfig = ActTotalRechargeTempConfig.GetConfig(ctgTempID, awardIndexSortList[i]);
+            if (tempConfig == null)
+                continue;
+            res.Add(tempConfig.AwardID);
+        }
+
+        if (isSort)
+        {
+            res = res.OrderBy(awardId =>
+            {
+                var tempConfig = ActTotalRechargeTempConfig.Get(awardId);
+                return IsAwardHave(tempConfig.AwardIndex);
+            })
+            .ThenBy(awardId => awardId)
+            .ToList();
+
+        }
+        return res;
+    }
+
+    public bool IsCanBuyShop(int shopID)
+    {
+        StoreConfig config = StoreConfig.Get(shopID);
+        if (config == null)
+            return false;
+        StoreModel.Instance.TryGetIsSellOut(config, out int remainNum);
+        return remainNum > 0;
+    }
+
+    public StoreModel.StoreData GetStoreData()
+    {
+        if (!GetActInfo(out var act, out var config))
+            return null;
+        int ctgShopType = config.CTGShopType;
+        if (StoreModel.Instance.storeTypeDict == null)
+            return null;
+        if (!StoreModel.Instance.storeTypeDict.TryGetValue(ctgShopType, out var list))
+            return null;
+        if (list.IsNullOrEmpty())
+            return null;
+        return list[0];
+    }
+
+    public float coinTotal;    //娲诲姩绱鍏呭�奸coin鍊�
+    public uint awardRecord;    //绱厖濂栧姳棰嗗璁板綍锛屾寜濂栧姳绱㈠紩浜岃繘鍒朵綅瀛樺偍鏄惁宸查鍙�
+    public event Action OnTotalRechargePlayerInfoEvent;
+    public void UpdateTotalRechargePlayerInfo(HAA1C_tagSCActTotalRechargePlayerInfo vNetData)
+    {
+        if (ActNum != vNetData.ActNum)
+            return;
+        coinTotal = (float)vNetData.CoinTotal / (float)100;
+        awardRecord = vNetData.AwardRecord;
+        UpdateRedPoint();
+        OnTotalRechargePlayerInfoEvent?.Invoke();
+    }
+
+    bool IsAwardHave(int awardIndex)
+    {
+        if (awardIndex < 0 || awardIndex >= 32)
+            return false;
+        return (awardRecord & (1u << awardIndex)) != 0;
+    }
+
+    // 鑾峰彇濂栧姳鐘舵�� 0 涓嶅彲棰嗗彇 1 鏈鍙� 2 宸查鍙�
+    public int GetState(int awardID)
+    {
+        var config = ActTotalRechargeTempConfig.Get(awardID);
+        if (config == null)
+            return 0;
+        if (coinTotal < config.NeedAmount)
+            return 0;
+        bool isAwardHave = IsAwardHave(config.AwardIndex);
+        return isAwardHave ? 2 : 1;
+    }
+
+    public bool IsReceived(int shopId)
+    {
+        var config = StoreConfig.Get(shopId);
+        if (config == null)
+            return false;
+        int boughtCount = StoreModel.Instance.GetShopLimitBuyCount(shopId);
+        return boughtCount >= config.LimitCnt;
+    }
+
+    public string GetActTimeStr()
+    {
+        if (!GetActInfo(out var act, out var config))
+        {
+            return Language.Get("OSActivity6");
+        }
+        return Language.Get("TotalRecharge08", TimeUtility.SecondsToShortDHMS(act.GetResetSurplusTime()));
+    }
+
+    public void SendGetReward(int awardIndex)
+    {
+        string actStr = ActNum.ToString();
+        var pack = new CA504_tagCMPlayerGetReward();
+        pack.RewardType = 18;
+        pack.DataEx = (uint)awardIndex;
+        pack.DataExStr = actStr;
+        pack.DataExStrLen = (byte)actStr.Length;
+        GameNetSystem.Instance.SendInfo(pack);
+    }
+}
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeTotalManager.cs.meta b/Main/System/FestivalActivity/FestivalActivityRechargeTotalManager.cs.meta
new file mode 100644
index 0000000..b849b79
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeTotalManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bcf0ceb7f1a7c8245afc8842e15ce2a3
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeTotalWin.cs b/Main/System/FestivalActivity/FestivalActivityRechargeTotalWin.cs
new file mode 100644
index 0000000..3c2734b
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeTotalWin.cs
@@ -0,0 +1,118 @@
+锘縰sing System;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class FestivalActivityRechargeTotalWin : UIBase
+{
+    [SerializeField] ItemCell totalRechargeItemCell;
+    [SerializeField] TextEx totalRechargeScoreText;
+    [SerializeField] RotationTween totalRechargeRotationTween;
+    [SerializeField] ImageEx totalRechargeFreeRedImage;
+    [SerializeField] ImageEx totalRechargeHaveImage;
+    [SerializeField] ScrollerController scroller;
+
+    FestivalActivityRechargeTotalManager manager { get { return FestivalActivityRechargeTotalManager.Instance; } }
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        manager.OnTotalRechargePlayerInfoEvent += OnTotalRechargePlayerInfoEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += OnRefreshBuyShopLimitEvent;
+        CreateScroller();
+        InitRechargeData();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        manager.OnTotalRechargePlayerInfoEvent -= OnTotalRechargePlayerInfoEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= OnRefreshBuyShopLimitEvent;
+    }
+
+    private void OnRefreshBuyShopLimitEvent()
+    {
+        scroller.m_Scorller.RefreshActiveCellViews();
+        RefreshRechargeData();
+    }
+
+    private void OnTotalRechargePlayerInfoEvent()
+    {
+        scroller.m_Scorller.RefreshActiveCellViews();
+        RefreshRechargeData();
+    }
+
+    void InitRechargeData()
+    {
+        var data = manager.GetStoreData();
+        bool isReceived = manager.IsReceived(data.shopId);
+        totalRechargeItemCell.Init(new ItemCellModel(data.storeConfig.ItemID, false, data.storeConfig.ItemCnt));
+        totalRechargeItemCell.button.SetListener(() =>
+        {
+            if (!isReceived)
+            {
+                StoreModel.Instance.SendBuyShopItem(data.storeConfig, 1);
+            }
+            else
+            {
+                ItemTipUtility.Show(data.storeConfig.ItemID);
+            }
+        });
+
+        totalRechargeHaveImage.SetActive(isReceived);
+        totalRechargeFreeRedImage.SetActive(!isReceived);
+        totalRechargeScoreText.text = Language.Get("TotalRecharge06", manager.coinTotal);
+        if (!isReceived)
+        {
+            totalRechargeRotationTween.Play();
+        }
+        else
+        {
+            totalRechargeRotationTween.Stop();
+            totalRechargeRotationTween.SetStartState();
+        }
+    }
+
+    void RefreshRechargeData()
+    {
+        var data = manager.GetStoreData();
+        bool isReceived = manager.IsReceived(data.shopId);
+        totalRechargeItemCell.Init(new ItemCellModel(data.storeConfig.ItemID, false, data.storeConfig.ItemCnt));
+        totalRechargeHaveImage.SetActive(isReceived);
+        totalRechargeFreeRedImage.SetActive(!isReceived);
+        totalRechargeScoreText.text = Language.Get("TotalRecharge06", manager.coinTotal);
+        if (!isReceived)
+        {
+            totalRechargeRotationTween.Play();
+        }
+        else
+        {
+            totalRechargeRotationTween.Stop();
+            totalRechargeRotationTween.SetStartState();
+        }
+    }
+
+
+
+    List<int> showList;
+    void CreateScroller()
+    {
+
+        showList = manager.GetShowList(true);
+        scroller.Refresh();
+        for (int i = 0; i < showList.Count; i++)
+        {
+            scroller.AddCell(ScrollerDataType.Header, i);
+        }
+        scroller.Restart();
+
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as FestivalActivityRechargeTotalCell;
+        _cell.Display(cell.index, showList);
+    }
+}
+
+
+
+
diff --git a/Main/System/FestivalActivity/FestivalActivityRechargeTotalWin.cs.meta b/Main/System/FestivalActivity/FestivalActivityRechargeTotalWin.cs.meta
new file mode 100644
index 0000000..dec0bac
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityRechargeTotalWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1a033d0838bfdfb468b0885f494be34b
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityShopCell.cs b/Main/System/FestivalActivity/FestivalActivityShopCell.cs
new file mode 100644
index 0000000..bb68acc
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityShopCell.cs
@@ -0,0 +1,135 @@
+锘縰sing UnityEngine;
+using UnityEngine.UI;
+
+public class FestivalActivityShopCell : MonoBehaviour
+{
+    [SerializeField] Transform saleRect;
+    [SerializeField] Text saleText;
+    [SerializeField] Text itemName;
+    [SerializeField] ItemCell itemCell;
+    [SerializeField] Text limitText;
+    [SerializeField] Text lockTip;
+
+    [SerializeField] Transform priceRect;
+    [SerializeField] Image priceIcon;
+    [SerializeField] Text priceText;
+
+    [SerializeField] Transform priceRect1;//灞呬腑浣嶇疆鐨勪环鏍�
+    [SerializeField] Image priceIcon1;
+    [SerializeField] Text priceText1;
+
+    [SerializeField] Transform salePriceRect;
+    [SerializeField] Text salePriceText;
+    [SerializeField] Button buyButton;
+    [SerializeField] Image freeRedPoint;
+    [SerializeField] Text freeText;
+    [SerializeField] Image exclusiveImage;//涓撳睘
+    [SerializeField] Image sellOutImage;//鍞絼
+    FestivalActivityManager manager => FestivalActivityManager.Instance;
+    public void Display(int index)
+    {
+        var act = manager.GetActInfo();
+        if (act == null)
+            return;
+        var config = ActSpecialSaleConfig.Get(act.CfgID);
+        if (config == null)
+            return;
+        if (!StoreModel.Instance.storeTypeDict.TryGetValue(config.ShopType, out var list))
+            return;
+
+        var storeData = list[index];
+        int shopID = storeData.shopId;
+        var itemID = storeData.storeConfig.ItemID;
+        var itemCount = storeData.storeConfig.ItemCnt;
+        exclusiveImage.SetActive(storeData.storeConfig.IsExclusive == 1);
+        itemCell.Init(new ItemCellModel(itemID, false, itemCount));
+        itemCell.button.AddListener(() =>
+        {
+            ItemTipUtility.Show(itemID);
+        });
+        var itemConfig = ItemConfig.Get(itemID);
+        itemName.text = itemConfig.ItemName;
+
+        //鎶樻墸
+        if (storeData.storeConfig.MoneyOriginal != 0)
+        {
+            saleRect.SetActive(true);
+            saleText.text = Language.Get("storename5", (storeData.storeConfig.MoneyNum * 10 / (float)storeData.storeConfig.MoneyOriginal).ToString("0.#"));
+        }
+        else
+        {
+            saleRect.SetActive(false);
+        }
+
+
+        var buyCnt = StoreModel.Instance.GetShopLimitBuyCount(shopID);
+        string limitStr = "";
+        if (storeData.storeConfig.MoneyNum == 0)
+        {
+            //鍏嶈垂
+            limitStr = "";
+        }
+        else if (storeData.storeConfig.ResetType == 0)
+        {
+            //闄愯喘
+            limitStr = storeData.storeConfig.LimitCnt > 0 ? Language.Get("storename8", storeData.storeConfig.LimitCnt - buyCnt, storeData.storeConfig.LimitCnt) : "";
+        }
+        else if (storeData.storeConfig.ResetType == 1)
+        {
+            //姣忔棩闄愯喘
+            limitStr = Language.Get("storename6", storeData.storeConfig.LimitCnt - buyCnt, storeData.storeConfig.LimitCnt);
+        }
+        else if (storeData.storeConfig.ResetType == 2)
+        {
+            //姣忓懆闄愯喘
+            limitStr = Language.Get("storename7", storeData.storeConfig.LimitCnt - buyCnt, storeData.storeConfig.LimitCnt);
+        }
+
+        limitText.text = buyCnt >= storeData.storeConfig.LimitCnt ? UIHelper.AppendColor(TextColType.Gray, limitStr) : limitStr;
+        buyButton.AddListener(() => { BuyGoods(shopID); });
+
+
+        //0鍙喘涔� 1宸插敭缃� 2鍏嶈垂 3鏈В閿�
+        var state = StoreModel.Instance.GetShopIDState(shopID);
+        sellOutImage.SetActive(state == 1);
+        freeRedPoint.SetActive(state == 2);
+        lockTip.text = state == 3 ? Language.Get("storename10", storeData.storeConfig.UnlockValue) : string.Empty;
+
+        priceRect.SetActive((state == 0 || state == 3) && storeData.storeConfig.MoneyOriginal != 0);
+        priceRect1.SetActive((state == 0 || state == 3) && storeData.storeConfig.MoneyOriginal == 0);
+        freeText.SetActive(state == 2 || (state == 1 && storeData.storeConfig.MoneyOriginal == 0));
+        salePriceRect.SetActive((state == 0 || state == 3) && storeData.storeConfig.MoneyOriginal != 0);
+
+        priceText.text = storeData.storeConfig.MoneyNum.ToString();
+        priceText1.text = storeData.storeConfig.MoneyNum.ToString();
+
+        if (storeData.storeConfig.MoneyType <= 0)
+        {
+            priceIcon.SetItemSprite(storeData.storeConfig.CostItemID);
+            priceIcon1.SetItemSprite(storeData.storeConfig.CostItemID);
+        }
+        else
+        {
+            priceIcon.SetIconWithMoneyType(storeData.storeConfig.MoneyType);
+            priceIcon1.SetIconWithMoneyType(storeData.storeConfig.MoneyType);
+        }
+
+        salePriceText.text = storeData.storeConfig.MoneyOriginal.ToString();
+    }
+
+    void BuyGoods(int shopID)
+    {
+        var state = StoreModel.Instance.GetShopIDState(shopID);
+        if (state == 1) return;
+
+        if (state == 2)
+        {
+            StoreModel.Instance.SendBuyShopItem(StoreConfig.Get(shopID), 1);
+        }
+        else
+        {
+            StoreModel.Instance.buyShopID = shopID;
+            UIManager.Instance.OpenWindow<BuyItemWin>();
+        }
+    }
+}
diff --git a/Main/System/FestivalActivity/FestivalActivityShopCell.cs.meta b/Main/System/FestivalActivity/FestivalActivityShopCell.cs.meta
new file mode 100644
index 0000000..ea05fa0
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityShopCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1ab9f2879e44d2a42ab352d11f5254fd
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityShopLineCell.cs b/Main/System/FestivalActivity/FestivalActivityShopLineCell.cs
new file mode 100644
index 0000000..cce0529
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityShopLineCell.cs
@@ -0,0 +1,31 @@
+锘縰sing UnityEngine;
+
+public class FestivalActivityShopLineCell : CellView
+{
+    [SerializeField] FestivalActivityShopCell[] storeCells;
+    FestivalActivityManager manager => FestivalActivityManager.Instance;
+    public void Display(int index)
+    {
+        var act = manager.GetActInfo();
+        if (act == null)
+            return;
+        var config = ActSpecialSaleConfig.Get(act.CfgID);
+        if (config == null)
+            return;
+        if (!StoreModel.Instance.storeTypeDict.TryGetValue(config.ShopType, out var list))
+            return;
+
+        for (int i = 0; i < storeCells.Length; i++)
+        {
+            if (index + i < list.Count)
+            {
+                storeCells[i].SetActive(true);
+                storeCells[i].Display(index + i);
+            }
+            else
+            {
+                storeCells[i].SetActive(false);
+            }
+        }
+    }
+}
diff --git a/Main/System/FestivalActivity/FestivalActivityShopLineCell.cs.meta b/Main/System/FestivalActivity/FestivalActivityShopLineCell.cs.meta
new file mode 100644
index 0000000..65e034b
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityShopLineCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6bd33c42e26241b47987559017eaa303
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityShopWin.cs b/Main/System/FestivalActivity/FestivalActivityShopWin.cs
new file mode 100644
index 0000000..a98241a
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityShopWin.cs
@@ -0,0 +1,84 @@
+using UnityEngine;
+
+public class FestivalActivityShopWin : UIBase
+{
+    [SerializeField] OwnItemCell ownItemCell;
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] TextEx timeText;
+    [SerializeField] ScrollerController scroller;
+    FestivalActivityManager manager => FestivalActivityManager.Instance;
+    protected override void InitComponent()
+    {
+        closeButton.SetListener(CloseWindow);
+    }
+
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        StoreModel.Instance.RefreshShopEvent += CreateScroller;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += CreateScroller;
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        if (!manager.IsShopVisitedToday)
+        {
+            manager.SaveShopVisitTimeData();
+            manager.UpdateRedpoint();
+        }
+
+        var act = manager.GetActInfo();
+        if (act == null)
+            return;
+        var config = ActSpecialSaleConfig.Get(act.CfgID);
+        if (config == null)
+            return;
+
+        ownItemCell.itemID = config.ShopItemID;
+
+        CreateScroller();
+        OnSecondEvent();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        StoreModel.Instance.RefreshShopEvent -= CreateScroller;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= CreateScroller;
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+        StoreModel.Instance.selectStoreFuncType = StoreFunc.Normal;
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as FestivalActivityShopLineCell;
+        _cell.Display(cell.index);
+    }
+
+    private void OnSecondEvent()
+    {
+        manager.GetActTimeStr(timeText);
+    }
+
+    void CreateScroller()
+    {
+        var act = manager.GetActInfo();
+        if (act == null)
+            return;
+        var config = ActSpecialSaleConfig.Get(act.CfgID);
+        if (config == null)
+            return;
+        if (!StoreModel.Instance.storeTypeDict.TryGetValue(config.ShopType, out var list))
+            return;
+
+        scroller.Refresh();
+        for (int i = 0; i < list.Count; i++)
+        {
+            if (i % 3 == 0)
+            {
+                scroller.AddCell(ScrollerDataType.Header, i);
+            }
+        }
+
+        scroller.Restart();
+        scroller.lockType = EnhanceLockType.KeepVertical;
+    }
+
+}
diff --git a/Main/System/FestivalActivity/FestivalActivityShopWin.cs.meta b/Main/System/FestivalActivity/FestivalActivityShopWin.cs.meta
new file mode 100644
index 0000000..9348df8
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityShopWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f29a66f9d8794c342bce21767d912ecd
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/FestivalActivityWin.cs b/Main/System/FestivalActivity/FestivalActivityWin.cs
new file mode 100644
index 0000000..235fb47
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityWin.cs
@@ -0,0 +1,79 @@
+using UnityEngine;
+public class FestivalActivityWin : UIBase
+{
+    [SerializeField] ImageEx bgImage;
+    [SerializeField] TextEx timeText;
+
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] ButtonEx checkInButton;
+    [SerializeField] ButtonEx missionButton;
+    [SerializeField] ButtonEx shopButton;
+    [SerializeField] ButtonEx giftButton;
+    [SerializeField] ButtonEx rechargeButton;
+    [SerializeField] ButtonEx previewButton;
+
+    [SerializeField] RedpointBehaviour checkInRedpoint;
+    [SerializeField] RedpointBehaviour missionRedpoint;
+    [SerializeField] RedpointBehaviour shopRedpoint;
+    [SerializeField] RedpointBehaviour giftRedpoint;
+    [SerializeField] RedpointBehaviour rechargeRedpoint;
+
+    FestivalActivityManager manager => FestivalActivityManager.Instance;
+    protected override void InitComponent()
+    {
+        closeButton.SetListener(() => UIManager.Instance.CloseWindow<FestivalActivityWin>());
+        checkInButton.SetListener(() => UIManager.Instance.OpenWindow<FestivalActivityCheckInWin>());
+        missionButton.SetListener(() => UIManager.Instance.OpenWindow<FestivalActivityMissionWin>());
+        shopButton.SetListener(() => UIManager.Instance.OpenWindow<FestivalActivityShopWin>());
+        giftButton.SetListener(() => UIManager.Instance.OpenWindow<FestivalActivityGiftWin>());
+        rechargeButton.SetListener(() => UIManager.Instance.OpenWindow<FestivalActivityRechargeBaseWin>());
+    }
+
+    protected override void OnPreOpen()
+    {
+        InitRedpoint();
+
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += Display;
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+        RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= Display;
+    }
+
+    private void OnRechargeCountEvent(int obj)
+    {
+        Display();
+    }
+
+    public void InitRedpoint()
+    {
+        checkInRedpoint.redpointId = manager.GetRedPointId(FestivalActivityRepointType.CheckIn);
+        missionRedpoint.redpointId = manager.GetRedPointId(FestivalActivityRepointType.Mission);
+        shopRedpoint.redpointId = manager.GetRedPointId(FestivalActivityRepointType.Shop);
+        giftRedpoint.redpointId = manager.GetRedPointId(FestivalActivityRepointType.Gift);
+        rechargeRedpoint.redpointId = manager.GetRedPointId(FestivalActivityRepointType.Recharge);
+    }
+
+    private void Display()
+    {
+
+        OnSecondEvent();
+    }
+
+    private void OnSecondEvent()
+    {
+        var act = manager.GetActInfo();
+        if (act == null)
+        {
+            timeText.text = Language.Get("OSActivity6");
+            return;
+        }
+        timeText.text = Language.Get("FestivalActivity02", act.ToDisplayTimeEx(), TimeUtility.SecondsToShortDHMS(act.GetResetSurplusTime()));
+    }
+}
diff --git a/Main/System/FestivalActivity/FestivalActivityWin.cs.meta b/Main/System/FestivalActivity/FestivalActivityWin.cs.meta
new file mode 100644
index 0000000..0fc9230
--- /dev/null
+++ b/Main/System/FestivalActivity/FestivalActivityWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bd54e7e15919c3a409eab1cb99dbfab5
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/OperationCheckInActivityInfo.cs b/Main/System/FestivalActivity/OperationCheckInActivityInfo.cs
new file mode 100644
index 0000000..8ffb16c
--- /dev/null
+++ b/Main/System/FestivalActivity/OperationCheckInActivityInfo.cs
@@ -0,0 +1,23 @@
+
+public class OperationCheckInActivityInfo : OperationBase
+{
+    public int ActType; // 娲诲姩绫诲瀷锛岀敤浜庡叧鑱旀椿鍔ㄧ浉鍏虫ā鍧楃敤锛屽绛惧埌銆佷换鍔$瓑
+    public int CfgID;   // 娲诲姩鏃堕棿琛ㄩ厤缃甀D
+
+    public override string ToDisplayTime()
+    {
+        var textBuilder = OperationTimeHepler.textBuilder;
+        textBuilder.Length = 0;
+        textBuilder.Append(startDate.ToDisplay(false));
+        textBuilder.Append(" 00:00:00");
+        if (startDate != endDate)
+        {
+            textBuilder.Append("-");
+            textBuilder.Append(endDate.ToDisplay(false));
+            textBuilder.Append(" 23:59:59");
+        }
+        return textBuilder.ToString();
+    }
+
+
+}
diff --git a/Main/System/FestivalActivity/OperationCheckInActivityInfo.cs.meta b/Main/System/FestivalActivity/OperationCheckInActivityInfo.cs.meta
new file mode 100644
index 0000000..03843ac
--- /dev/null
+++ b/Main/System/FestivalActivity/OperationCheckInActivityInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: df08f6c5862454d4c8a24d44af3a84f0
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/OperationFlashSaleActivityInfo.cs b/Main/System/FestivalActivity/OperationFlashSaleActivityInfo.cs
new file mode 100644
index 0000000..195114a
--- /dev/null
+++ b/Main/System/FestivalActivity/OperationFlashSaleActivityInfo.cs
@@ -0,0 +1,34 @@
+
+public class OperationFlashSaleActivityInfo : OperationBase
+{
+    public int ActType; // 娲诲姩绫诲瀷锛岀敤浜庡叧鑱旀椿鍔ㄧ浉鍏虫ā鍧楃敤锛屽绛惧埌銆佷换鍔$瓑
+    public int CfgID;   // 娲诲姩鏃堕棿琛ㄩ厤缃甀D
+
+    public override string ToDisplayTime()
+    {
+        var textBuilder = OperationTimeHepler.textBuilder;
+        textBuilder.Length = 0;
+        textBuilder.Append(startDate.ToDisplay(false));
+        textBuilder.Append(" 00:00:00");
+        if (startDate != endDate)
+        {
+            textBuilder.Append("-");
+            textBuilder.Append(endDate.ToDisplay(false));
+            textBuilder.Append(" 23:59:59");
+        }
+        return textBuilder.ToString();
+    }
+
+    public string ToDisplayTimeEx()
+    {
+        var textBuilder = OperationTimeHepler.textBuilder;
+        textBuilder.Length = 0;
+        textBuilder.Append(startDate.ToDisplay(false));
+        if (startDate != endDate)
+        {
+            textBuilder.Append("-");
+            textBuilder.Append(endDate.ToDisplay(false));
+        }
+        return textBuilder.ToString();
+    }
+}
diff --git a/Main/System/FestivalActivity/OperationFlashSaleActivityInfo.cs.meta b/Main/System/FestivalActivity/OperationFlashSaleActivityInfo.cs.meta
new file mode 100644
index 0000000..1af8ced
--- /dev/null
+++ b/Main/System/FestivalActivity/OperationFlashSaleActivityInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 546d13d472461714fa4e45fd54742409
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/FestivalActivity/OperationMissionActivityInfo.cs b/Main/System/FestivalActivity/OperationMissionActivityInfo.cs
new file mode 100644
index 0000000..6fc7976
--- /dev/null
+++ b/Main/System/FestivalActivity/OperationMissionActivityInfo.cs
@@ -0,0 +1,23 @@
+
+public class OperationMissionActivityInfo : OperationBase
+{
+    public int ActType; // 娲诲姩绫诲瀷锛岀敤浜庡叧鑱旀椿鍔ㄧ浉鍏虫ā鍧楃敤锛屽绛惧埌銆佷换鍔$瓑
+    public int CfgID;   // 娲诲姩鏃堕棿琛ㄩ厤缃甀D
+
+    public override string ToDisplayTime()
+    {
+        var textBuilder = OperationTimeHepler.textBuilder;
+        textBuilder.Length = 0;
+        textBuilder.Append(startDate.ToDisplay(false));
+        textBuilder.Append(" 00:00:00");
+        if (startDate != endDate)
+        {
+            textBuilder.Append("-");
+            textBuilder.Append(endDate.ToDisplay(false));
+            textBuilder.Append(" 23:59:59");
+        }
+        return textBuilder.ToString();
+    }
+
+
+}
diff --git a/Main/System/FestivalActivity/OperationMissionActivityInfo.cs.meta b/Main/System/FestivalActivity/OperationMissionActivityInfo.cs.meta
new file mode 100644
index 0000000..560efe3
--- /dev/null
+++ b/Main/System/FestivalActivity/OperationMissionActivityInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: afebd8558abc1734fbb2a360b7da975c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Main/HomeWin.cs b/Main/System/Main/HomeWin.cs
index 076820e..c3143d9 100644
--- a/Main/System/Main/HomeWin.cs
+++ b/Main/System/Main/HomeWin.cs
@@ -74,6 +74,7 @@
     [SerializeField] TimeRushCell timeRushCell;
     [SerializeField] HeroDebutCell heroDebutCell;
     [SerializeField] HeroReturnCell heroReturnCell;
+    [SerializeField] Button festivalActivityBtn;
 
     //鍧愰獞
     [SerializeField] Image horseBGImg;
@@ -232,7 +233,10 @@
         {
             UIManager.Instance.OpenWindow<DailySpecialsBaseWin>();
         });
-
+        festivalActivityBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<FestivalActivityWin>();
+        });
     }
 
 
@@ -298,6 +302,7 @@
         DisplayTimeRush();
         DisplayHeroDebut();
         DisplayHeroReturn();
+        DisplayFestivalActivity();
         DelayPlayMusic().Forget();
 
     }
@@ -346,6 +351,10 @@
         {
             DisplayGalaBtn();
         }
+        else if (type == OperationType.FestivalActivity)
+        {
+            DisplayFestivalActivity();
+        }
     }
 
     private void OpenServerActivityStateChange()
@@ -354,6 +363,7 @@
         DisplayHeroDebut();
         DisplayHeroReturn();
         DisplayGalaBtn();
+        DisplayFestivalActivity();
     }
 
     private void OnShowGiftIdListAddEvent()
@@ -856,6 +866,10 @@
         {
             DisplayHeroReturn();
         }
+        else if (funcId == (int)FuncOpenEnum.FestivalActivity)
+        {
+            DisplayFestivalActivity();
+        }
     }
 
     private void OnUpdateFirstChargeInfo()
@@ -959,6 +973,12 @@
             return;
         heroReturnCell.Display();
     }
+
+    void DisplayFestivalActivity()
+    {
+        bool isOpen = FestivalActivityManager.Instance.IsFestivalActivityOpen();
+        festivalActivityBtn.SetActive(isOpen);
+    }
 }
 
 
diff --git a/Main/System/OpenServerActivity/OperationTimeHepler.cs b/Main/System/OpenServerActivity/OperationTimeHepler.cs
index 0738659..aa2a94b 100644
--- a/Main/System/OpenServerActivity/OperationTimeHepler.cs
+++ b/Main/System/OpenServerActivity/OperationTimeHepler.cs
@@ -497,72 +497,190 @@
 
     public void UpdateActTotalRechargeInfo(HAA1D_tagSCActTotalRechargeInfo package)
     {
-        OperationBase operationBase = null;
-        operationDict.TryGetValue(OperationType.TotalRecharge, out operationBase);
+        var opreationType = OperationType.TotalRecharge;
+        switch (package.ActNum)
+        {
+            case 10:
+                opreationType = OperationType.TotalRecharge;
+                break;
+            case 30:
+                opreationType = OperationType.FestivalActivity_RechargeTotal;
+                break;
+        }
+
         if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate))
         {
-            ForceStopOperation(OperationType.TotalRecharge);
+            ForceStopOperation(opreationType);
+            return;
         }
-        else
-        {
-            if (operationBase == null)
-            {
-                operationBase = new OperationTotalRechargeInfo();
-                operationDict.Add(OperationType.TotalRecharge, operationBase);
-            }
-            OperationTotalRechargeInfo operation = operationBase as OperationTotalRechargeInfo;
-            operation.Reset();
-            operation.startDate = ParseOperationDate(package.StartDate);
-            operation.endDate = ParseOperationDate(package.EndtDate);
-            operation.ActNum = package.ActNum;
-            operation.CfgID = package.CfgID;
-            
-            var config = ActTotalRechargeConfig.Get(package.CfgID);
-            if (config == null)
-            {
-                SysNotifyMgr.Instance.ShowTip("LoadConfigErr");
-                return;
-            }
 
-            if (operationTimeUpdateEvent != null)
-            {
-                operationTimeUpdateEvent(OperationType.TotalRecharge);
-            }
+        if (!operationDict.TryGetValue(opreationType, out OperationBase operationBase))
+        {
+            operationBase = new OperationTotalRechargeInfo();
+            operationDict.Add(opreationType, operationBase);
         }
+        OperationTotalRechargeInfo operation = operationBase as OperationTotalRechargeInfo;
+        operation.Reset();
+        operation.startDate = ParseOperationDate(package.StartDate);
+        operation.endDate = ParseOperationDate(package.EndtDate);
+        operation.ActNum = package.ActNum;
+        operation.CfgID = package.CfgID;
+
+        var config = ActTotalRechargeConfig.Get(package.CfgID);
+        if (config == null)
+        {
+            SysNotifyMgr.Instance.ShowTip("LoadConfigErr");
+            return;
+        }
+        operation.dayReset = config.IsDayReset == 1;
+        operationTimeUpdateEvent?.Invoke(opreationType);
     }
 
     public void UpdateActTotDayRechargeInfo(HAA1B_tagSCActTotDayRechargeInfo package)
     {
-        OperationBase operationBase = null;
-        operationDict.TryGetValue(OperationType.TotDayRecharge, out operationBase);
+        var opreationType = OperationType.TotDayRecharge;
+        switch (package.ActNum)
+        {
+            case 10:
+                opreationType = OperationType.TotDayRecharge;
+                break;
+            case 30:
+                opreationType = OperationType.FestivalActivity_RechargeTotDay;
+                break;
+        }
         if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate))
         {
-            ForceStopOperation(OperationType.TotDayRecharge);
+            ForceStopOperation(opreationType);
+            return;
         }
-        else
+        if (!operationDict.TryGetValue(opreationType, out OperationBase operationBase))
         {
-            if (operationBase == null)
-            {
-                operationBase = new OperationTotDayRechargeInfo();
-                operationDict.Add(OperationType.TotDayRecharge, operationBase);
-            }
-            OperationTotDayRechargeInfo operation = operationBase as OperationTotDayRechargeInfo;
-            operation.Reset();
-            operation.startDate = ParseOperationDate(package.StartDate);
-            operation.endDate = ParseOperationDate(package.EndtDate);
-            operation.ActNum = package.ActNum;
-            operation.CfgID = package.CfgID;
-
-            var config = ActTotalRechargeConfig.Get(package.CfgID);
-            if (config == null)
-            {
-                SysNotifyMgr.Instance.ShowTip("LoadConfigErr");
-                return;
-            }
-            
-            operation.dayReset = config.IsDayReset == 1;
-            operationTimeUpdateEvent?.Invoke(OperationType.TotDayRecharge);
+            operationBase = new OperationTotDayRechargeInfo();
+            operationDict.Add(opreationType, operationBase);
         }
+        OperationTotDayRechargeInfo operation = operationBase as OperationTotDayRechargeInfo;
+        operation.Reset();
+        operation.startDate = ParseOperationDate(package.StartDate);
+        operation.endDate = ParseOperationDate(package.EndtDate);
+        operation.ActNum = package.ActNum;
+        operation.CfgID = package.CfgID;
+
+        if (ActTotDayRechargeConfig.Get(package.CfgID) == null)
+        {
+            SysNotifyMgr.Instance.ShowTip("LoadConfigErr");
+            return;
+        }
+        operationTimeUpdateEvent?.Invoke(opreationType);
+    }
+
+    public void UpdateFlashSaleActivityInfo(HAA10_tagSCActSpecialSaleInfo package)
+    {
+        var opreationType = OperationType.FestivalActivity;
+        switch (package.ActNum)
+        {
+            case 30:
+                opreationType = OperationType.FestivalActivity;
+                break;
+        }
+
+        if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate))
+        {
+            ForceStopOperation(opreationType);
+            return;
+        }
+
+        if (!operationDict.TryGetValue(opreationType, out OperationBase operationBase))
+        {
+            operationBase = new OperationFlashSaleActivityInfo();
+            operationDict.Add(opreationType, operationBase);
+        }
+        OperationFlashSaleActivityInfo operation = operationBase as OperationFlashSaleActivityInfo;
+        operation.Reset();
+        operation.startDate = ParseOperationDate(package.StartDate);
+        operation.endDate = ParseOperationDate(package.EndtDate);
+        operation.ActNum = package.ActNum;
+        operation.CfgID = package.CfgID;
+
+        if (ActSpecialSaleConfig.Get(package.CfgID) == null)
+        {
+            SysNotifyMgr.Instance.ShowTip("LoadConfigErr");
+            return;
+        }
+        operationTimeUpdateEvent?.Invoke(opreationType);
+    }
+
+    public void UpdateCheckInActivityInfo(HAA23_tagSCActSignInfo package)
+    {
+        var opreationType = OperationType.FestivalActivity_CheckIn;
+        switch (package.ActNum)
+        {
+            case 30:
+                opreationType = OperationType.FestivalActivity_CheckIn;
+                break;
+        }
+
+        if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate))
+        {
+            ForceStopOperation(opreationType);
+            return;
+        }
+
+        if (!operationDict.TryGetValue(opreationType, out OperationBase operationBase))
+        {
+            operationBase = new OperationCheckInActivityInfo();
+            operationDict.Add(opreationType, operationBase);
+        }
+        OperationCheckInActivityInfo operation = operationBase as OperationCheckInActivityInfo;
+        operation.Reset();
+        operation.startDate = ParseOperationDate(package.StartDate);
+        operation.endDate = ParseOperationDate(package.EndtDate);
+        operation.ActType = package.ActNum;
+        operation.CfgID = package.CfgID;
+
+        if (ActSignConfig.Get(package.CfgID) == null)
+        {
+            SysNotifyMgr.Instance.ShowTip("LoadConfigErr");
+            return;
+        }
+        operationTimeUpdateEvent?.Invoke(opreationType);
+    }
+
+    public void UpdateMissionActivityInfo(HAA71_tagSCActTaskInfo package)
+    {
+        var opreationType = OperationType.FestivalActivity_Mission;
+        switch (package.ActNum)
+        {
+            case 30:
+                opreationType = OperationType.FestivalActivity_Mission;
+                break;
+        }
+
+        if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate))
+        {
+            ForceStopOperation(opreationType);
+            return;
+        }
+
+        if (!operationDict.TryGetValue(opreationType, out OperationBase operationBase))
+        {
+            operationBase = new OperationMissionActivityInfo();
+            operationDict.Add(opreationType, operationBase);
+        }
+        OperationMissionActivityInfo operation = operationBase as OperationMissionActivityInfo;
+        operation.Reset();
+        operation.startDate = ParseOperationDate(package.StartDate);
+        operation.endDate = ParseOperationDate(package.EndtDate);
+        operation.ActType = package.ActNum;
+        operation.CfgID = package.CfgID;
+
+        var config = ActTaskConfig.Get(package.CfgID);
+        if (config == null)
+        {
+            SysNotifyMgr.Instance.ShowTip("LoadConfigErr");
+            return;
+        }
+        operation.dayReset = config.IsDayReset == 1;
+        operationTimeUpdateEvent?.Invoke(opreationType);
     }
 
     // public void UpdateActYunShiInfo(HAA87_tagMCActYunshiInfo package)
@@ -1157,5 +1275,10 @@
     HeroReturn = 3, //鏃ユ湡鍨嬫椿鍔� - 姝﹀皢杩斿満
     TotalRecharge = 4,//绱厖娲诲姩
     TotDayRecharge = 5, //绱厖澶╂椿鍔�
+    FestivalActivity = 6,   //鑺傛棩娲诲姩
+    FestivalActivity_RechargeTotDay = 7,   //鑺傛棩娲诲姩-绱ぉ鍏呭��
+    FestivalActivity_RechargeTotal = 8,   //鑺傛棩娲诲姩-绱厖鍊�
+    FestivalActivity_CheckIn = 9,   //鑺傛棩娲诲姩-绛惧埌
+    FestivalActivity_Mission = 10,   //鑺傛棩娲诲姩-浠诲姟
     max,
 }
\ No newline at end of file
diff --git a/Main/System/Redpoint/MainRedDot.cs b/Main/System/Redpoint/MainRedDot.cs
index 2365d68..e4325f9 100644
--- a/Main/System/Redpoint/MainRedDot.cs
+++ b/Main/System/Redpoint/MainRedDot.cs
@@ -155,7 +155,8 @@
     public const int RedPoint_OSHeroTrain = 481;
     public const int RedPoint_OSBeautyMM = 482;
     public const int RedPoint_OSMingge = 483;
-    public const int HeroReturnRepoint = 484; //姝﹀皢杩斿満
+    public const int HeroReturnRepoint = 484;   //姝﹀皢杩斿満
+    public const int FestivalActivityRepoint = 485;    //鑺傛棩娲诲姩
     public void Register()
     {
 
diff --git a/Main/Utility/EnumHelper.cs b/Main/Utility/EnumHelper.cs
index 65646a6..a0618e8 100644
--- a/Main/Utility/EnumHelper.cs
+++ b/Main/Utility/EnumHelper.cs
@@ -859,6 +859,7 @@
     Qunying = 62, //缇よ嫳姒�
     HeroDebut = 63,//姝﹀皢鐧诲満
     HeroReturn = 64,  //姝﹀皢杩斿満
+    FestivalActivity = 65,//鑺傛棩娲诲姩
 }
 
 
@@ -1815,8 +1816,13 @@
     TimeRushAct = 200,  //杞洖娈�(姝﹀皢鍐插埡)
     HeroDebutAct = 201,  //鑻遍泟鐧诲満娲诲姩
     HeroReturnAct = 202,  //鑻遍泟杩斿満娲诲姩
-    TotalRechargeAct = 4,   //绱厖娲诲姩
-    TotDayRechargeAct = 5,  //绱厖澶╂椿鍔�
+    TotalRechargeAct = 203,   //绱厖娲诲姩
+    TotDayRechargeAct = 204,  //绱厖澶╂椿鍔�
+    FestivalActivityAct = 205,  //鑺傛棩娲诲姩
+    FestivalActivityRechargeTotalAct = 206,
+    FestivalActivityRechargeTotDayAct = 207,
+    FestivalActivityCheckInAct = 208,
+    FestivalActivityMissionAct = 209,   //鑺傛棩娲诲姩-浠诲姟
 }
 
 //浠欑帀璐拱鐨勪簩娆$‘璁ゆ绫诲瀷

--
Gitblit v1.8.0