From 991c31124d6818550bb2a14c23853476d72e7a14 Mon Sep 17 00:00:00 2001
From: lcy <1459594991@qq.com>
Date: 星期一, 29 十二月 2025 10:20:17 +0800
Subject: [PATCH] 251 每日特惠-客户端

---
 Main/System/DailySpecials/DailySpecialsItem.cs              |  108 +++++
 Main/System/DailySpecials/DailySpecialsDayGiftCell.cs.meta  |   11 
 Main/System/DailySpecials/DailySpecialsShopWin.cs.meta      |   11 
 Main/System/DailySpecials/DailySpecialsItem.cs.meta         |   11 
 Main/System/DailySpecials.meta                              |    8 
 Main/System/Redpoint/MainRedDot.cs                          |    1 
 Main/System/DailySpecials/DailySpecialsWeekGiftWin.cs.meta  |   11 
 Main/System/DailySpecials/DailySpecialsWeekGiftWin.cs       |   56 ++
 Main/System/Main/HomeWin.cs                                 |   18 
 Main/Main.cs                                                |    1 
 Main/System/DailySpecials/DailySpecialsDayGiftWin.cs        |   58 ++
 Main/System/DailySpecials/DailySpecialsBaseWin.cs.meta      |   11 
 Main/System/Store/StoreModel.cs                             |    5 
 Main/System/DailySpecials/DailySpecialsDayGiftWin.cs.meta   |   11 
 Main/Utility/EnumHelper.cs                                  |    2 
 Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs.meta |   11 
 Main/System/DailySpecials/DailySpecialsDayGiftCell.cs       |   80 ++++
 Main/System/DailySpecials/DailySpecialsManager.cs.meta      |   11 
 Main/System/DailySpecials/DailySpecialsWin.cs               |   90 ++++
 Main/System/DailySpecials/DailySpecialsManager.cs           |  300 +++++++++++++++
 Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs      |   80 ++++
 Main/Utility/UIHelper.cs                                    |   12 
 Main/System/DailySpecials/DailySpecialsBaseWin.cs           |  193 +++++++++
 Main/System/DailySpecials/DailySpecialsShopWin.cs           |   49 ++
 Main/System/DailySpecials/DailySpecialsWin.cs.meta          |   11 
 25 files changed, 1,156 insertions(+), 4 deletions(-)

diff --git a/Main/Main.cs b/Main/Main.cs
index bbc65ce..c416293 100644
--- a/Main/Main.cs
+++ b/Main/Main.cs
@@ -96,6 +96,7 @@
         managers.Add(OSActivityManager.Instance);
         managers.Add(HeroFatesManager.Instance);
         managers.Add(BeautyMMManager.Instance);
+        managers.Add(DailySpecialsManager.Instance);
         foreach (var manager in managers)
         {
             manager.Init();
diff --git a/Main/System/DailySpecials.meta b/Main/System/DailySpecials.meta
new file mode 100644
index 0000000..d6f0076
--- /dev/null
+++ b/Main/System/DailySpecials.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: cbbbe8e7b4947df46809a886006847ad
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/DailySpecials/DailySpecialsBaseWin.cs b/Main/System/DailySpecials/DailySpecialsBaseWin.cs
new file mode 100644
index 0000000..66a9253
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsBaseWin.cs
@@ -0,0 +1,193 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class DailySpecialsBaseWin : FunctionsBaseWin
+{
+    [SerializeField] ImageEx imgBG;
+    [SerializeField] ImageEx imgFan0;
+    [SerializeField] ImageEx imgFanOther;
+    [SerializeField] ImageEx[] imgIHs;
+    [SerializeField] ImageEx[] imgTitles;
+    [SerializeField] Transform[] transMoneys;
+
+    [SerializeField] ItemCell freeItem;
+    [SerializeField] ImageEx imgFreeHave;
+    [SerializeField] Image imgFreeRed;
+    [SerializeField] RotationTween rotationTween;
+
+    [SerializeField] ImageEx imgTimeBG1;
+    [SerializeField] TextEx txtTime1;
+    [SerializeField] ImageEx imgTimeBG2;
+    [SerializeField] TextEx txtTime2;
+
+    DailySpecialsManager manager { get { return DailySpecialsManager.Instance; } }
+    StoreModel storeModel { get { return StoreModel.Instance; } }
+
+    protected override void OnPreOpen()
+    {
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        storeModel.RefreshBuyShopLimitEvent += OnRefreshBuyShopLimitEvent;
+        InitRedpoint();
+        tabButtons[functionOrder].SelectBtn();
+        OpenSubUIByTabIndex();
+    }
+
+    protected override void OnPreClose()
+    {
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+        storeModel.RefreshBuyShopLimitEvent -= OnRefreshBuyShopLimitEvent;
+    }
+
+    private void OnRefreshBuyShopLimitEvent()
+    {
+        DisplayFreeItem(functionOrder);
+    }
+
+    private void OnSecondEvent()
+    {
+        DisplayTime(functionOrder);
+    }
+
+    public void InitRedpoint()
+    {
+        for (int i = 0; i < tabButtons.Length; i++)
+        {
+            if (!Enum.IsDefined(typeof(DailySpecialsTabEnum), functionOrder))
+            {
+                return;
+            }
+            tabButtons[i].redpoint.redpointId = manager.GetTabRedponitId(i);
+        }
+    }
+
+    public void DisplayTime(int functionOrder)
+    {
+        imgTimeBG1.SetActive(functionOrder == 0 || functionOrder == 1);
+        imgTimeBG2.SetActive(functionOrder == 2 || functionOrder == 3);
+        txtTime1.text = Language.Get("PhantasmPavilion10", functionOrder == 3 ? manager.GetCountdownToWeekEnd() : manager.GetCountdownToNextDay());
+        txtTime2.text = Language.Get("PhantasmPavilion10", functionOrder == 3 ? manager.GetCountdownToWeekEnd() : manager.GetCountdownToNextDay());
+    }
+
+    public void DisplayFan(int functionOrder)
+    {
+        imgFan0.SetActive(functionOrder == 0);
+        imgFanOther.SetActive(functionOrder != 0);
+        imgFanOther.SetSprite(StringUtility.Concat("DailySpecialsFan", functionOrder.ToString()));
+    }
+
+    public void DisplayIH(int functionOrder)
+    {
+        SetActiveByIndex(imgIHs, functionOrder);
+    }
+
+    public void DisplayTitle(int functionOrder)
+    {
+        SetActiveByIndex(imgTitles, functionOrder);
+    }
+
+    public void DisplayMoney(int functionOrder)
+    {
+        for (int i = 0; i < transMoneys.Length; i++)
+        {
+            transMoneys[i].SetActive(i == functionOrder);
+        }
+    }
+
+    public void DisplayBG(int functionOrder)
+    {
+        imgBG.SetSprite(functionOrder == 0 ? "DailySpecialsBG1" : "DailySpecialsBG2");
+    }
+
+    public void DisplayFreeItem(int functionOrder)
+    {
+        int itemId = 0;
+        int itemCount = 0;
+
+        int shopId = manager.GetShopIdByFunctionOrder(functionOrder);
+
+        if (!StoreConfig.HasKey(shopId))
+        {
+            freeItem.SetActive(false);
+            return;
+        }
+        freeItem.SetActive(true);
+        StoreConfig storeConfig = StoreConfig.Get(shopId);
+
+        itemId = storeConfig.ItemID;
+        itemCount = storeConfig.ItemCnt;
+
+        bool isReceived = manager.IsReceived(shopId);
+        freeItem.Init(new ItemCellModel(itemId, false, itemCount));
+        freeItem.button.SetListener(() =>
+        {
+            if (!isReceived)
+            {
+                storeModel.SendBuyShopItem(storeConfig, 1);
+            }
+            else
+            {
+                ItemTipUtility.Show(itemId);
+            }
+
+        });
+        imgFreeHave.SetActive(isReceived);
+        imgFreeRed.SetActive(!isReceived);
+
+        if (!isReceived)
+        {
+            rotationTween.Play();
+        }
+        else
+        {
+            rotationTween.Stop();
+            rotationTween.SetStartState();
+        }
+    }
+
+    // 閫氱敤鏂规硶锛氭縺娲绘寚瀹氱储寮曠殑鍥剧墖
+    private void SetActiveByIndex(ImageEx[] images, int targetIndex)
+    {
+        for (int i = 0; i < images.Length; i++)
+        {
+            images[i].SetActive(i == targetIndex);
+        }
+    }
+
+    protected override void OpenSubUIByTabIndex()
+    {
+        DisplayBG(functionOrder);
+        DisplayFan(functionOrder);
+        DisplayIH(functionOrder);
+        DisplayTitle(functionOrder);
+        DisplayFreeItem(functionOrder);
+        DisplayTime(functionOrder);
+        DisplayMoney(functionOrder);
+
+        switch (functionOrder)
+        {
+            case 0:
+                // 姣忔棩鐗规儬
+                currentSubUI = UIManager.Instance.OpenWindow<DailySpecialsWin>();
+                break;
+            case 1:
+                // 鐗规儬鍟嗗煄
+                StoreModel.Instance.selectStoreFuncType = StoreFunc.SpecialStore;
+                currentSubUI = UIManager.Instance.OpenWindow<DailySpecialsShopWin>();
+                break;
+            case 2:
+                // 姣忔棩绀煎寘
+                currentSubUI = UIManager.Instance.OpenWindow<DailySpecialsDayGiftWin>();
+                break;
+            case 3:
+                // 姣忓懆绀煎寘
+                currentSubUI = UIManager.Instance.OpenWindow<DailySpecialsWeekGiftWin>();
+                break;
+            default:
+                Debug.LogWarning("鏈煡鐨勬爣绛剧储寮�: " + functionOrder);
+                break;
+        }
+    }
+
+
+}
diff --git a/Main/System/DailySpecials/DailySpecialsBaseWin.cs.meta b/Main/System/DailySpecials/DailySpecialsBaseWin.cs.meta
new file mode 100644
index 0000000..69ded3a
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsBaseWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5334c94ed6e4c0041948de4f1c6c6f96
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/DailySpecials/DailySpecialsDayGiftCell.cs b/Main/System/DailySpecials/DailySpecialsDayGiftCell.cs
new file mode 100644
index 0000000..c2382f8
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsDayGiftCell.cs
@@ -0,0 +1,80 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class DailySpecialsDayGiftCell : MonoBehaviour
+{
+    [SerializeField] ItemCell[] itemCells;
+    [SerializeField] ImageEx imgGiftIcon;
+    [SerializeField] ImageEx imgRate;
+    [SerializeField] ImageEx imgMask;
+    [SerializeField] TextEx txtRate;
+    [SerializeField] TextEx txtGiftTitle;
+    [SerializeField] TextEx txtLimitInfo;
+    [SerializeField] ButtonEx btnBuy;
+    [SerializeField] ImageEx imgBuy;
+    [SerializeField] TextEx txtBuy;
+    DailySpecialsManager manager { get { return DailySpecialsManager.Instance; } }
+    public void Display(int index, List<int> ctgIDList)
+    {
+        if (ctgIDList.IsNullOrEmpty() || ctgIDList.Count <= index || index < 0)
+        {
+            return;
+        }
+        int ctgId = ctgIDList[index];
+
+        if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderInfoConfig))
+        {
+            return;
+        }
+
+        if (!CTGConfig.HasKey(ctgId))
+        {
+            return;
+        }
+
+        CTGConfig ctgConfig = CTGConfig.Get(ctgId);
+        int[][] gainItemList = ctgConfig.GainItemList;
+
+        if (gainItemList.IsNullOrEmpty())
+        {
+            return;
+        }
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            if (i < gainItemList.Length)
+            {
+                int itemId = gainItemList[i][0];
+                int count = gainItemList[i][1];
+                itemCells[i].Init(new ItemCellModel(itemId, false, count));
+                itemCells[i].button.SetListener(() => { ItemTipUtility.Show(itemId); });
+                itemCells[i].SetActive(true);
+            }
+            else
+            {
+                itemCells[i].SetActive(false);
+            }
+        }
+
+        bool hasRechargeCount = RechargeManager.Instance.TryGetRechargeCount(ctgId, out RechargeCount _rechargeCount);
+        bool isBuy = manager.IsDayGiftBuy(ctgId);
+        imgRate.SetActive(!isBuy);
+        imgMask.SetActive(isBuy);
+
+        imgBuy.SetSprite(!isBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2");
+        txtBuy.text = !isBuy ? Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale) : Language.Get("storename11");
+
+        imgGiftIcon.SetSprite(ctgConfig.Icon);
+        txtGiftTitle.text = ctgConfig.Title;
+        txtRate.text = Language.Get("DailySpecials07", ctgConfig.Percentage);
+        txtLimitInfo.text = Language.Get("storename6", ctgConfig.DailyBuyCount - _rechargeCount.todayCount, ctgConfig.DailyBuyCount);
+        btnBuy.SetListener(() =>
+        {
+            if (isBuy)
+            {
+                return;
+            }
+            RechargeManager.Instance.CTG(ctgId);
+        });
+    }
+
+}
\ No newline at end of file
diff --git a/Main/System/DailySpecials/DailySpecialsDayGiftCell.cs.meta b/Main/System/DailySpecials/DailySpecialsDayGiftCell.cs.meta
new file mode 100644
index 0000000..e48ef58
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsDayGiftCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1f954c52cc69b4e41a23025861342e5d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/DailySpecials/DailySpecialsDayGiftWin.cs b/Main/System/DailySpecials/DailySpecialsDayGiftWin.cs
new file mode 100644
index 0000000..6b728de
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsDayGiftWin.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class DailySpecialsDayGiftWin : UIBase
+{
+    readonly int payType = 20;
+    [SerializeField] ScrollerController scroller;
+    DailySpecialsManager manager { get { return DailySpecialsManager.Instance; } }
+    RechargeManager rechargeManager { get { return RechargeManager.Instance; } }
+
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        rechargeManager.rechargeCountEvent += OnRechargeCountEvent;
+        CreateScroller();
+    }
+
+    private void OnRechargeCountEvent(int obj)
+    {
+        CreateScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        rechargeManager.rechargeCountEvent -= OnRechargeCountEvent;
+        StoreModel.Instance.selectStoreFuncType = StoreFunc.Normal;
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<DailySpecialsDayGiftCell>();
+        _cell.Display(cell.index, ctgIDList);
+    }
+
+    List<int> ctgIDList = null;
+    void CreateScroller()
+    {
+        if (ctgIDList.IsNullOrEmpty())
+        {
+            ctgIDList = RechargeManager.Instance.GetCTGIDListByType(payType);
+        }
+        if (!ctgIDList.IsNullOrEmpty())
+        {
+            ctgIDList = ctgIDList.OrderBy(ctgId => { return manager.IsDayGiftBuy(ctgId); }).ThenBy(ctgId => ctgId).ToList();
+            scroller.Refresh();
+            for (int i = 0; i < ctgIDList.Count; i++)
+            {
+                scroller.AddCell(ScrollerDataType.Header, i);
+            }
+            scroller.Restart();
+        }
+    }
+}
+
diff --git a/Main/System/DailySpecials/DailySpecialsDayGiftWin.cs.meta b/Main/System/DailySpecials/DailySpecialsDayGiftWin.cs.meta
new file mode 100644
index 0000000..7d285e9
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsDayGiftWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 10ad4bd016db44b4581bd3ebb2b84438
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/DailySpecials/DailySpecialsItem.cs b/Main/System/DailySpecials/DailySpecialsItem.cs
new file mode 100644
index 0000000..dd7148b
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsItem.cs
@@ -0,0 +1,108 @@
+using UnityEngine;
+
+public class DailySpecialsItem : MonoBehaviour
+{
+    [SerializeField] TextEx txtRate;
+    [SerializeField] ItemCell[] itemCells;
+    [SerializeField] ImageEx imgBuy;
+    [SerializeField] ButtonEx btnBuy;
+    [SerializeField] TextEx txtBuy;
+    DailySpecialsManager manager { get { return DailySpecialsManager.Instance; } }
+    public void Display(int index, bool isAllBuy)
+    {
+        if (!manager.TryGetDailyCtgIdByIndex(index, out int ctgId))
+        {
+            return;
+        }
+
+        if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderInfoConfig))
+        {
+            return;
+        }
+
+        if (!CTGConfig.HasKey(ctgId))
+        {
+            return;
+        }
+
+        CTGConfig ctgConfig = CTGConfig.Get(ctgId);
+        int[][] gainItemList = ctgConfig.GainItemList;
+
+        if (gainItemList.IsNullOrEmpty())
+        {
+            return;
+        }
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            if (i < gainItemList.Length)
+            {
+                int itemId = gainItemList[i][0];
+                int count = gainItemList[i][1];
+                itemCells[i].Init(new ItemCellModel(itemId, false, count));
+                itemCells[i].button.SetListener(() => { ItemTipUtility.Show(itemId); });
+                itemCells[i].SetActive(true);
+            }
+            else
+            {
+                itemCells[i].SetActive(false);
+            }
+        }
+
+        if (isAllBuy)
+        {
+            btnBuy.SetActive(false);
+            imgBuy.SetActive(true);
+        }
+        else
+        {
+            bool hasRechargeCount = RechargeManager.Instance.TryGetRechargeCount(ctgId, out RechargeCount _rechargeCount);
+            bool isBuy = hasRechargeCount && _rechargeCount.todayCount > 0;
+            btnBuy.SetActive(!isBuy);
+            imgBuy.SetActive(isBuy);
+
+            txtBuy.text = Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale);
+            txtRate.text = Language.Get("DailySpecials07", ctgConfig.Percentage);
+            btnBuy.SetListener(() =>
+            {
+                string iconName = UIHelper.GetIconNameWithMoneyType(54);
+                if (!CTGConfig.HasKey(manager.bundleRechargeId))
+                {
+                    return;
+                }
+                CTGConfig ctgConfig = CTGConfig.Get(manager.bundleRechargeId);
+                int[][] gainItemList = ctgConfig.GainItemList;
+                if (gainItemList.IsNullOrEmpty())
+                {
+                    return;
+                }
+                int count = gainItemList[0][1];
+
+                // 鍏堟鏌ユ槸鍚﹀凡缁忓嬀閫�"鏈鐧诲綍涓嶅啀鎻愰啋"
+                if (manager.isDailySpecialsToggleOn)
+                {
+                    RechargeManager.Instance.CTG(ctgId);
+                    return;
+
+                }
+                ConfirmCancel.ToggleConfirmCancel(
+                    Language.Get("L1003"),                                    
+                    Language.Get("DailySpecials08", iconName, count),         
+                    Language.Get("TianziBillborad08"),                          
+                    Language.Get("PopConfirmWin_OK"),                         
+                    null,                                                     
+                    (bool isOK, bool isToggle) =>
+                    {
+                        if (isOK)
+                        {
+                            manager.isDailySpecialsToggleOn = isToggle;
+                            RechargeManager.Instance.CTG(ctgId);
+                        }
+                    },
+                    false                                                     
+                );
+            });
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/Main/System/DailySpecials/DailySpecialsItem.cs.meta b/Main/System/DailySpecials/DailySpecialsItem.cs.meta
new file mode 100644
index 0000000..227301b
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsItem.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 779116b373fd11246a789aef55cb0157
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/DailySpecials/DailySpecialsManager.cs b/Main/System/DailySpecials/DailySpecialsManager.cs
new file mode 100644
index 0000000..f9560e3
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsManager.cs
@@ -0,0 +1,300 @@
+using System;
+using System.Collections.Generic;
+using LitJson;
+
+public class DailySpecialsManager : GameSystemManager<DailySpecialsManager>
+{
+    public int[] dailyRechargeIds;      // 姣忔棩鐗规儬绀煎寘鍏呭�糏D鍒楄〃锛堝崟鐙喘涔扮敤锛�
+    public int bundleRechargeId;        // 鎵撳寘璐拱鍏呭�糏D
+    public int originalPrice;
+    public bool isDailySpecialsToggleOn;  // 鏈鐧诲綍涓嶅啀鎻愰啋鐨勭姸鎬�
+    RechargeManager rechargeManager { get { return RechargeManager.Instance; } }
+    public override void Init()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
+        rechargeManager.rechargeCountEvent += OnRechargeCountEvent;
+        StoreModel.Instance.RefreshShopEvent += OnRefreshShopEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += OnRefreshBuyShopLimitEvent;
+        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChange;
+        InitTable();
+        InitRedpoints();
+    }
+
+    public override void Release()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin;
+        rechargeManager.rechargeCountEvent += OnRechargeCountEvent;
+        StoreModel.Instance.RefreshShopEvent -= OnRefreshShopEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= OnRefreshBuyShopLimitEvent;
+        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChange;
+    }
+
+    private void OnFuncStateChange(int obj)
+    {
+        if (FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.DailySpecials))
+        {
+            UpdateRedPoint();
+        }
+    }
+
+    private void OnBeforePlayerDataInitializeEventOnRelogin()
+    {
+        isDailySpecialsToggleOn = false;
+    }
+
+    private void OnRechargeCountEvent(int obj)
+    {
+        UpdateRedPoint();
+    }
+
+    private void OnRefreshBuyShopLimitEvent()
+    {
+        UpdateRedPoint();
+    }
+
+
+    private void OnRefreshShopEvent()
+    {
+        UpdateRedPoint();
+    }
+
+    void InitTable()
+    {
+        var config = FuncConfigConfig.Get("DailyTehui");
+        dailyRechargeIds = JsonMapper.ToObject<int[]>(config.Numerical1);
+        bundleRechargeId = int.Parse(config.Numerical2);
+        originalPrice = int.Parse(config.Numerical3);
+    }
+    public bool IsWeekGiftBuy(int ctgId)
+    {
+        if (!CTGConfig.HasKey(ctgId))
+        {
+            return false;
+        }
+        CTGConfig ctgConfig = CTGConfig.Get(ctgId);
+        bool hasRechargeCount = RechargeManager.Instance.TryGetRechargeCount(ctgId, out RechargeCount _rechargeCount);
+        bool isBuy = hasRechargeCount && _rechargeCount.weekPayCount >= ctgConfig.WeekBuyCount;
+        return isBuy;
+    }
+
+    public bool IsDayGiftBuy(int ctgId)
+    {
+        if (!CTGConfig.HasKey(ctgId))
+        {
+            return false;
+        }
+        CTGConfig ctgConfig = CTGConfig.Get(ctgId);
+        bool hasRechargeCount = RechargeManager.Instance.TryGetRechargeCount(ctgId, out RechargeCount _rechargeCount);
+        bool isBuy = hasRechargeCount && _rechargeCount.todayCount >= ctgConfig.DailyBuyCount;
+        return isBuy;
+    }
+
+    public readonly Dictionary<int, StoreFunc> FunctionOrderToStoreFunc = new Dictionary<int, StoreFunc>()
+    {
+        {0, StoreFunc.DailySpecialsFree},
+        {2, StoreFunc.DailyGiftFree},
+        {3, StoreFunc.WeeklyGiftFree},
+    };
+
+    public int GetShopIdByFunctionOrder(int functionOrder)
+    {
+        if (FunctionOrderToStoreFunc.TryGetValue(functionOrder, out StoreFunc storeFunc))
+        {
+            return GetShopIdByStoreFunc(storeFunc);
+        }
+        return 0;
+    }
+    private int GetShopIdByStoreFunc(StoreFunc storeFunc)
+    {
+        return GetFreeShopIDDict().TryGetValue(storeFunc, out int shopId) ? shopId : 0;
+    }
+
+    Dictionary<StoreFunc, int> freeShopIDDict = null;
+    private Dictionary<StoreFunc, int> GetFreeShopIDDict()
+    {
+        if (freeShopIDDict.IsNullOrEmpty())
+        {
+            freeShopIDDict = new Dictionary<StoreFunc, int>();
+            List<StoreConfig> storeConfigs = StoreConfig.GetValues();
+            foreach (var storeConfig in storeConfigs)
+            {
+                foreach (var StoreFunc in FunctionOrderToStoreFunc.Values)
+                {
+                    if (storeConfig.ShopType == (int)StoreFunc)
+                    {
+                        freeShopIDDict[StoreFunc] = storeConfig.ID;
+                    }
+                }
+            }
+        }
+        return freeShopIDDict;
+    }
+
+    public bool IsReceived(int shopId)
+    {
+        if (!StoreConfig.HasKey(shopId))
+        {
+            return false;
+        }
+
+        StoreConfig storeConfig = StoreConfig.Get(shopId);
+        int boughtCount = StoreModel.Instance.GetShopLimitBuyCount(shopId);
+        return boughtCount >= storeConfig.LimitCnt;
+    }
+
+    public string GetCountdownToNextDay()
+    {
+        int remainSeconds = TimeUtility.GetTodayRemainSeconds();
+        return TimeUtility.SecondsToShortDHMS(remainSeconds);
+    }
+    public string GetCountdownToWeekEnd()
+    {
+        DateTime now = TimeUtility.ServerNow;
+        int daysUntilMonday = (int)DayOfWeek.Monday - (int)now.DayOfWeek;
+        if (daysUntilMonday <= 0)
+        {
+            daysUntilMonday += 7; // 涓嬪懆涓�
+        }
+        DateTime nextMonday = now.AddDays(daysUntilMonday);
+        DateTime weekEndTime = new DateTime(nextMonday.Year, nextMonday.Month, nextMonday.Day);
+        int remainSeconds = (int)(weekEndTime - now).TotalSeconds;
+        return TimeUtility.SecondsToShortDHMS(remainSeconds);
+    }
+
+
+
+    public bool TryGetDailyCtgIdByIndex(int index, out int ctgId)
+    {
+        ctgId = 0;
+        if (dailyRechargeIds.IsNullOrEmpty())
+        {
+            return false;
+        }
+
+        if (index < 0 || index >= dailyRechargeIds.Length)
+        {
+            return false;
+        }
+
+        ctgId = dailyRechargeIds[index];
+        return true;
+    }
+
+
+    /// 妫�鏌ユ槸鍚︽湁浠绘剰鍗曠嫭鍟嗗搧宸茶喘涔�
+    public bool HasAnySingleItemBought()
+    {
+        if (dailyRechargeIds.IsNullOrEmpty())
+        {
+            return false;
+        }
+
+        for (int i = 0; i < dailyRechargeIds.Length; i++)
+        {
+            int singleCtgId = dailyRechargeIds[i];
+            if (rechargeManager.TryGetRechargeCount(singleCtgId, out RechargeCount singleRechargeCount))
+            {
+                if (singleRechargeCount.todayCount > 0)
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    #region 绾㈢偣
+
+    public Redpoint parentRedpoint = new Redpoint(MainRedDot.DailyTehui);
+
+    public Dictionary<int, Redpoint> tabRedpoints = new Dictionary<int, Redpoint>();
+
+    public void InitRedpoints()
+    {
+        tabRedpoints.Clear();
+        var enumValues = Enum.GetValues(typeof(DailySpecialsTabEnum));
+        foreach (DailySpecialsTabEnum tab in enumValues)
+        {
+            int tabRedponitId = GetTabRedponitId((int)tab);
+            tabRedpoints[tabRedponitId] = new Redpoint(MainRedDot.DailyTehui, tabRedponitId);
+        }
+    }
+
+    public int GetTabRedponitId(int functionOrder)
+    {
+        if (!Enum.IsDefined(typeof(DailySpecialsTabEnum), functionOrder))
+        {
+            return 0;
+        }
+        return MainRedDot.DailyTehui * 10 + functionOrder + 1;
+    }
+
+    public void UpdateRedPoint()
+    {
+        parentRedpoint.state = RedPointState.None;
+        foreach (DailySpecialsTabEnum tab in Enum.GetValues(typeof(DailySpecialsTabEnum)))
+        {
+            int redpointId = GetTabRedponitId((int)tab);
+            if (tabRedpoints.ContainsKey(redpointId))
+            {
+                tabRedpoints[redpointId].state = RedPointState.None;
+            }
+        }
+
+        // 鍔熻兘娌″紑
+        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.DailySpecials))
+            return;
+        foreach (DailySpecialsTabEnum tab in Enum.GetValues(typeof(DailySpecialsTabEnum)))
+        {
+            int redpointId = GetTabRedponitId((int)tab);
+            if (!tabRedpoints.ContainsKey(redpointId))
+            {
+                continue;
+            }
+
+            if (tab == DailySpecialsTabEnum.DailySpecials || tab == DailySpecialsTabEnum.DailyGift || tab == DailySpecialsTabEnum.WeeklyGift)
+            {
+                int shopId = GetShopIdByFunctionOrder((int)tab);
+                bool isReceived = IsReceived(shopId);
+                if (!isReceived)
+                {
+                    tabRedpoints[redpointId].state = RedPointState.Simple;
+                }
+
+            }
+            else if (tab == DailySpecialsTabEnum.SpecialStore)
+            {
+                Dictionary<int, List<int>> freeShopDict = StoreModel.Instance.freeShopDict;
+                bool isFlag = false;
+                if (!freeShopDict.IsNullOrEmpty() && freeShopDict.ContainsKey((int)StoreFunc.SpecialStore))
+                {
+                    var shopList = freeShopDict[(int)StoreFunc.SpecialStore];
+                    for (int i = 0; i < shopList.Count; i++)
+                    {
+                        var shopId = shopList[i];
+                        bool isReceived = IsReceived(shopId);
+                        if (!isReceived)
+                        {
+                            isFlag = true;
+                            break;
+                        }
+                    }
+                    if (isFlag)
+                    {
+                        tabRedpoints[redpointId].state = RedPointState.Simple;
+                    }
+                }
+            }
+        }
+    }
+    #endregion
+}
+
+public enum DailySpecialsTabEnum
+{
+    DailySpecials = 0,  // 姣忔棩鐗规儬
+    SpecialStore = 1,   // 鐗规儬鍟嗗煄
+    DailyGift = 2,      // 姣忔棩绀煎寘
+    WeeklyGift = 3,     // 姣忓懆绀煎寘
+}
\ No newline at end of file
diff --git a/Main/System/DailySpecials/DailySpecialsManager.cs.meta b/Main/System/DailySpecials/DailySpecialsManager.cs.meta
new file mode 100644
index 0000000..8d0413c
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 054be96b4996f534bb390b6275520623
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/DailySpecials/DailySpecialsShopWin.cs b/Main/System/DailySpecials/DailySpecialsShopWin.cs
new file mode 100644
index 0000000..dc51586
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsShopWin.cs
@@ -0,0 +1,49 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class DailySpecialsShopWin : UIBase
+{
+    [SerializeField] ScrollerController scroller;
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        StoreModel.Instance.RefreshShopEvent += CreateScroller;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += CreateScroller;
+        CreateScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        StoreModel.Instance.RefreshShopEvent -= CreateScroller;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= CreateScroller;
+        StoreModel.Instance.selectStoreFuncType = StoreFunc.Normal;
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as StoreLineCell;
+        _cell.Display(cell.index);
+    }
+    void CreateScroller()
+    {
+        if (!StoreModel.Instance.storeTypeDict.ContainsKey((int)StoreModel.Instance.selectStoreFuncType))
+        {
+            return;
+        }
+
+        scroller.Refresh();
+        var list = StoreModel.Instance.storeTypeDict[(int)StoreModel.Instance.selectStoreFuncType];
+        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/DailySpecials/DailySpecialsShopWin.cs.meta b/Main/System/DailySpecials/DailySpecialsShopWin.cs.meta
new file mode 100644
index 0000000..515eff4
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsShopWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f357c7a3d2108a146ae91e3227e0a969
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs b/Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs
new file mode 100644
index 0000000..750e0e9
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs
@@ -0,0 +1,80 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class DailySpecialsWeekGiftCell : MonoBehaviour
+{
+    [SerializeField] ItemCell[] itemCells;
+    [SerializeField] ImageEx imgGiftIcon;
+    [SerializeField] ImageEx imgRate;
+    [SerializeField] ImageEx imgMask;
+    [SerializeField] TextEx txtRate;
+    [SerializeField] TextEx txtGiftTitle;
+    [SerializeField] TextEx txtLimitInfo;
+    [SerializeField] ButtonEx btnBuy;
+    [SerializeField] ImageEx imgBuy;
+    [SerializeField] TextEx txtBuy;
+    DailySpecialsManager manager { get { return DailySpecialsManager.Instance; } }
+    public void Display(int index, List<int> ctgIDList)
+    {
+        if (ctgIDList.IsNullOrEmpty() || ctgIDList.Count <= index || index < 0)
+        {
+            return;
+        }
+        int ctgId = ctgIDList[index];
+
+        if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderInfoConfig))
+        {
+            return;
+        }
+
+        if (!CTGConfig.HasKey(ctgId))
+        {
+            return;
+        }
+
+        CTGConfig ctgConfig = CTGConfig.Get(ctgId);
+        int[][] gainItemList = ctgConfig.GainItemList;
+
+        if (gainItemList.IsNullOrEmpty())
+        {
+            return;
+        }
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            if (i < gainItemList.Length)
+            {
+                int itemId = gainItemList[i][0];
+                int count = gainItemList[i][1];
+                itemCells[i].Init(new ItemCellModel(itemId, false, count));
+                itemCells[i].button.SetListener(() => { ItemTipUtility.Show(itemId); });
+                itemCells[i].SetActive(true);
+            }
+            else
+            {
+                itemCells[i].SetActive(false);
+            }
+        }
+
+        bool hasRechargeCount = RechargeManager.Instance.TryGetRechargeCount(ctgId, out RechargeCount _rechargeCount);
+        bool isBuy = manager.IsWeekGiftBuy(ctgId);
+        imgRate.SetActive(!isBuy);
+        imgMask.SetActive(isBuy);
+
+        imgBuy.SetSprite(!isBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2");
+        txtBuy.text = !isBuy ? Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale) : Language.Get("storename11");
+
+        imgGiftIcon.SetSprite(ctgConfig.Icon);
+        txtGiftTitle.text = ctgConfig.Title;
+        txtRate.text = Language.Get("DailySpecials07", ctgConfig.Percentage);
+        txtLimitInfo.text = Language.Get("storename7", ctgConfig.WeekBuyCount - _rechargeCount.weekPayCount, ctgConfig.WeekBuyCount);
+        btnBuy.SetListener(() =>
+        {
+            if (isBuy)
+            {
+                return;
+            }
+            RechargeManager.Instance.CTG(ctgId);
+        });
+    }
+
+}
\ No newline at end of file
diff --git a/Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs.meta b/Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs.meta
new file mode 100644
index 0000000..f2a92c5
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3a145ea085a927e4793891ab25c05d3a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/DailySpecials/DailySpecialsWeekGiftWin.cs b/Main/System/DailySpecials/DailySpecialsWeekGiftWin.cs
new file mode 100644
index 0000000..0a2c169
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsWeekGiftWin.cs
@@ -0,0 +1,56 @@
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+public class DailySpecialsWeekGiftWin : UIBase
+{
+    readonly int payType = 21;
+    [SerializeField] ScrollerController scroller;
+    DailySpecialsManager manager { get { return DailySpecialsManager.Instance; } }
+    RechargeManager rechargeManager { get { return RechargeManager.Instance; } }
+
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        rechargeManager.rechargeCountEvent += OnRechargeCountEvent;
+        CreateScroller();
+    }
+
+    private void OnRechargeCountEvent(int obj)
+    {
+        CreateScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        rechargeManager.rechargeCountEvent -= OnRechargeCountEvent;
+        StoreModel.Instance.selectStoreFuncType = StoreFunc.Normal;
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<DailySpecialsWeekGiftCell>();
+        _cell.Display(cell.index, ctgIDList);
+    }
+
+    List<int> ctgIDList = null;
+    void CreateScroller()
+    {
+        if (ctgIDList.IsNullOrEmpty())
+        {
+            ctgIDList = RechargeManager.Instance.GetCTGIDListByType(payType);
+        }
+        if (!ctgIDList.IsNullOrEmpty())
+        {
+            ctgIDList = ctgIDList.OrderBy(ctgId => { return manager.IsWeekGiftBuy(ctgId); }).ThenBy(ctgId => ctgId).ToList();
+            scroller.Refresh();
+            for (int i = 0; i < ctgIDList.Count; i++)
+            {
+                scroller.AddCell(ScrollerDataType.Header, i);
+            }
+            scroller.Restart();
+        }
+    }
+}
+
diff --git a/Main/System/DailySpecials/DailySpecialsWeekGiftWin.cs.meta b/Main/System/DailySpecials/DailySpecialsWeekGiftWin.cs.meta
new file mode 100644
index 0000000..8e7b2a0
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsWeekGiftWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8e1af0521d5ad21469154f8d34cce2d2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/DailySpecials/DailySpecialsWin.cs b/Main/System/DailySpecials/DailySpecialsWin.cs
new file mode 100644
index 0000000..66786fb
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsWin.cs
@@ -0,0 +1,90 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class DailySpecialsWin : UIBase
+{
+    [SerializeField] DailySpecialsItem[] items;
+    [SerializeField] GradientText txtRate;
+    [SerializeField] TextEx txtCurrentPrice;
+    [SerializeField] TextEx txtOriginalPrice;
+    [SerializeField] ButtonEx btnBuyAll;
+    [SerializeField] ImageEx imgBuyAll;
+    [SerializeField] TextEx txtBuyAll;
+    [SerializeField] ItemCell itemcellAllBuy;
+    [SerializeField] ImageEx imgAllBuyHave;
+
+    DailySpecialsManager manager { get { return DailySpecialsManager.Instance; } }
+    RechargeManager rechargeManager { get { return RechargeManager.Instance; } }
+    protected override void InitComponent()
+    {
+        btnBuyAll.SetListener(() =>
+        {
+            RechargeManager.Instance.CTG(manager.bundleRechargeId);
+        });
+    }
+
+    protected override void OnPreOpen()
+    {
+        rechargeManager.rechargeCountEvent += OnRechargeCountEvent;
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        rechargeManager.rechargeCountEvent -= OnRechargeCountEvent;
+    }
+
+    private void OnRechargeCountEvent(int obj)
+    {
+        Display();
+    }
+
+    void Display()
+    {
+        int ctgid = manager.bundleRechargeId;
+        if (!CTGConfig.HasKey(ctgid))
+        {
+            return;
+        }
+
+        if (!RechargeManager.Instance.TryGetOrderInfo(ctgid, out var orderInfoConfig))
+        {
+            return;
+        }
+
+        CTGConfig ctgConfig = CTGConfig.Get(ctgid);
+        int[][] gainItemList = ctgConfig.GainItemList;
+
+        if (gainItemList.IsNullOrEmpty())
+        {
+            return;
+        }
+
+        txtRate.text = Language.Get("DailySpecials07", ctgConfig.Percentage);
+
+        int itemId = gainItemList[0][0];
+        int itemCount = gainItemList[0][1];
+        itemcellAllBuy.Init(new ItemCellModel(itemId, false, itemCount));
+        itemcellAllBuy.button.SetListener(() => { ItemTipUtility.Show(itemId); });
+
+        bool hasRechargeCount = RechargeManager.Instance.TryGetRechargeCount(ctgid, out RechargeCount _rechargeCount);
+        bool isBuyAll = hasRechargeCount && _rechargeCount.todayCount > 0;
+
+        // 妫�鏌ユ槸鍚︽湁浠绘剰鍗曠嫭鍟嗗搧宸茶喘涔�
+        bool hasAnySingleItemBought = manager.HasAnySingleItemBought();
+        // 濡傛灉鏈変换鎰忓崟鐙晢鍝佸凡璐拱锛屽垯鎵撳寘涔熻涓哄凡璐拱鐘舵��
+        bool finalIsBuyAll = isBuyAll || hasAnySingleItemBought;
+
+        imgAllBuyHave.SetActive(isBuyAll);
+        txtBuyAll.text = !finalIsBuyAll ? Language.Get("DailySpecials03", Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale)) : Language.Get("storename11");
+        btnBuyAll.interactable = !finalIsBuyAll;
+        imgBuyAll.gray = finalIsBuyAll;
+        for (int i = 0; i < items.Length; i++)
+        {
+            items[i].Display(i, isBuyAll);
+        }
+    }
+
+}
+
diff --git a/Main/System/DailySpecials/DailySpecialsWin.cs.meta b/Main/System/DailySpecials/DailySpecialsWin.cs.meta
new file mode 100644
index 0000000..db207c4
--- /dev/null
+++ b/Main/System/DailySpecials/DailySpecialsWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fdfabe6b2123bfe4dbd292bcc96695f9
+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 78e80dc..c962e66 100644
--- a/Main/System/Main/HomeWin.cs
+++ b/Main/System/Main/HomeWin.cs
@@ -62,6 +62,7 @@
     [SerializeField] RightFuncInHome rightFuncInHome;
 
     [SerializeField] Button FirstChargeBtn;
+    [SerializeField] Button DailySpecialsBtns;
     [SerializeField] Button osMainLevelBtn;
     [SerializeField] Button osHeroCallBtn;
     [SerializeField] Button osGalaBtn;
@@ -205,6 +206,12 @@
         {
             UIManager.Instance.OpenWindow<OSGalaBaseWin>();
         });
+
+        DailySpecialsBtns.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<DailySpecialsBaseWin>();
+        });
+
     }
 
 
@@ -232,6 +239,7 @@
         //inputFastChat.characterLimit = ChatManager.Instance.characterLimit;
         //UpdateSendButton();
         ShowChatInfo();
+        DisplayDailySpecialsBtn();
     }
 
     protected override void OnPreOpen()
@@ -731,6 +739,12 @@
         DisplayFirstChargeBtn();
     }
 
+    private void DisplayDailySpecialsBtn()
+    {
+        bool isOpen = FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.DailySpecials);
+        DailySpecialsBtns.SetActive(isOpen);
+    }
+
     private void OnFuncStateChange(int funcId)
     {
         if (funcId == GeneralDefine.mainRightFuncOpenFuncID)
@@ -746,6 +760,10 @@
         {
             DisplayOSActivity();
         }
+        else if (funcId == (int)FuncOpenEnum.DailySpecials)
+        {
+            DisplayDailySpecialsBtn();
+        }
     }
 
     private void OnUpdateFirstChargeInfo()
diff --git a/Main/System/Redpoint/MainRedDot.cs b/Main/System/Redpoint/MainRedDot.cs
index 219e838..06b1084 100644
--- a/Main/System/Redpoint/MainRedDot.cs
+++ b/Main/System/Redpoint/MainRedDot.cs
@@ -138,6 +138,7 @@
     public const int LineupRecommendRepoint = 473; //闃靛鎺ㄨ崘
     public const int FunctionPreviewRepoint = 474; //鍔熻兘棰勫憡
     public const int HeroFatesRepoint = 475;//瀹跨紭
+    public const int DailyTehui = 476;//姣忔棩鐗规儬
     public void Register()
     {
 
diff --git a/Main/System/Store/StoreModel.cs b/Main/System/Store/StoreModel.cs
index 56e6eb9..5a584dd 100644
--- a/Main/System/Store/StoreModel.cs
+++ b/Main/System/Store/StoreModel.cs
@@ -572,7 +572,10 @@
     OSHeroCall = 4, //4锛氬紑鏈嶆嫑鍕熺ぜ鍖�
     OSGalaChange = 5, //5锛氬紑鏈嶅簡鍏稿厬鎹�
     OSGalaGift = 6, //6锛氬紑鏈嶅簡鍏哥ぜ鍖�
-
+    SpecialStore = 7, //7锛氱壒鎯犲晢鍩�
+    DailySpecialsFree = 8, //8: 姣忔棩鐗规儬-姣忔棩鐗规儬鍏嶈垂
+    DailyGiftFree = 9, //9: 姣忔棩鐗规儬-姣忔棩绀煎寘鍏嶈垂
+    WeeklyGiftFree = 10, //10: 姣忔棩鐗规儬-姣忓懆绀煎寘鍏嶈垂
 }
 
 
diff --git a/Main/Utility/EnumHelper.cs b/Main/Utility/EnumHelper.cs
index eab9fb4..a7fc5ff 100644
--- a/Main/Utility/EnumHelper.cs
+++ b/Main/Utility/EnumHelper.cs
@@ -711,6 +711,7 @@
     default44,  // 272 姝﹀皢鎷涘嫙绉垎
     GoldRush = 285, // 娣橀噾浠�
     ChallengeVoucher = 286,//鎸戞垬鍑瘉
+    DailySpecials = 287, //鐗规儬鍗扮欢
     OSGalaScore = 288, //寮�鏈嶅簡鍏哥Н鍒�
 };
 
@@ -846,6 +847,7 @@
     FunctionPreview = 48, //鍔熻兘棰勮
     HeroFatesUpgrade = 49, //瀹跨紭鍗囩骇
     LineupRecommend = 50, //闃靛鎺ㄨ崘
+    DailySpecials = 51, //姣忔棩鐗规儬
 }
 
 
diff --git a/Main/Utility/UIHelper.cs b/Main/Utility/UIHelper.cs
index a4310db..747a050 100644
--- a/Main/Utility/UIHelper.cs
+++ b/Main/Utility/UIHelper.cs
@@ -1004,6 +1004,7 @@
         {43, PlayerDataType.default34},
         {42, PlayerDataType.default33},
         {53, PlayerDataType.ChallengeVoucher},
+        {54, PlayerDataType.DailySpecials},
         {55, PlayerDataType.OSGalaScore},
         {99, PlayerDataType.ExAttr11},
     };
@@ -1152,6 +1153,11 @@
                 {
                     //鎸戞垬鍑瘉
                     return PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.ChallengeVoucher);
+                }
+            case 54:
+                {
+                    //鐗规儬鍗扮欢
+                    return PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.DailySpecials);
                 }
             case 55:
                 {
@@ -1436,7 +1442,7 @@
     {
         return GUIUtility.systemCopyBuffer;
     }
-    
+
     /// <summary>
     /// 寮哄埗鍒锋柊Layout锛岃В鍐冲祵濂桳ayout鍜孋ontentSizeFitter鐨勯噸鍙犻棶棰�
     /// </summary>
@@ -1457,6 +1463,6 @@
         }
 
     }
-    
-    
+
+
 }

--
Gitblit v1.8.0